void dns_dlzdestroy(dns_dlzdb_t **dbp) { isc_mem_t *mctx; dns_dlzdestroy_t destroy; /* Write debugging message to log */ isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2), "Unloading DLZ driver."); /* * Perform checks to make sure data is as we expect it to be. */ REQUIRE(dbp != NULL && DNS_DLZ_VALID(*dbp)); #ifdef BIND9 if ((*dbp)->ssutable != NULL) { dns_ssutable_detach(&(*dbp)->ssutable); } #endif /* call the drivers destroy method */ if ((*dbp) != NULL) { mctx = (*dbp)->mctx; destroy = (*dbp)->implementation->methods->destroy; (*destroy)((*dbp)->implementation->driverarg,(*dbp)->dbdata); /* return memory */ isc_mem_put(mctx, (*dbp), sizeof(dns_dlzdb_t)); isc_mem_detach(&mctx); } *dbp = NULL; }
isc_result_t dns_dlzallowzonexfr(dns_view_t *view, dns_name_t *name, isc_sockaddr_t *clientaddr, dns_db_t **dbp) { isc_result_t result; dns_dlzallowzonexfr_t allowzonexfr; dns_dlzdb_t *dlzdatabase; /* * Performs checks to make sure data is as we expect it to be. */ REQUIRE(DNS_DLZ_VALID(view->dlzdatabase)); REQUIRE(name != NULL); REQUIRE(dbp != NULL && *dbp == NULL); /* ask driver if the zone is supported */ dlzdatabase = view->dlzdatabase; allowzonexfr = dlzdatabase->implementation->methods->allowzonexfr; result = (*allowzonexfr)(dlzdatabase->implementation->driverarg, dlzdatabase->dbdata, dlzdatabase->mctx, view->rdclass, name, clientaddr, dbp); if (result == ISC_R_NOTIMPLEMENTED) return (ISC_R_NOTFOUND); return (result); }
void dns_dlzdestroy(dns_dlzdb_t **dbp) { dns_dlzdestroy_t destroy; dns_dlzdb_t *db; /* Write debugging message to log */ isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2), "Unloading DLZ driver."); /* * Perform checks to make sure data is as we expect it to be. */ REQUIRE(dbp != NULL && DNS_DLZ_VALID(*dbp)); db = *dbp; *dbp = NULL; if (db->ssutable != NULL) dns_ssutable_detach(&db->ssutable); /* call the drivers destroy method */ if (db->dlzname != NULL) isc_mem_free(db->mctx, db->dlzname); destroy = db->implementation->methods->destroy; (*destroy)(db->implementation->driverarg, db->dbdata); /* return memory and detach */ isc_mem_putanddetach(&db->mctx, db, sizeof(dns_dlzdb_t)); }
isc_result_t dns_dlzfindzone(dns_view_t *view, dns_name_t *name, unsigned int minlabels, dns_db_t **dbp) { dns_fixedname_t fname; dns_name_t *zonename; unsigned int namelabels; unsigned int i; isc_result_t result; dns_dlzfindzone_t findzone; dns_dlzdb_t *dlzdatabase; /* * Performs checks to make sure data is as we expect it to be. */ REQUIRE(DNS_DLZ_VALID(view->dlzdatabase)); REQUIRE(name != NULL); REQUIRE(dbp != NULL && *dbp == NULL); /* setup a "fixed" dns name */ dns_fixedname_init(&fname); zonename = dns_fixedname_name(&fname); /* count the number of labels in the name */ namelabels = dns_name_countlabels(name); /* * loop through starting with the longest domain name and * trying shorter names portions of the name until we find a * match, have an error, or are below the 'minlabels' * threshold. minlabels is 0, if the standard database didn't * have a zone name match. Otherwise minlabels is the number * of labels in that name. We need to beat that for a * "better" match for the DLZ database to be authoritative * instead of the standard database. */ for (i = namelabels; i > minlabels && i > 1; i--) { if (i == namelabels) { result = dns_name_copy(name, zonename, NULL); if (result != ISC_R_SUCCESS) return (result); } else dns_name_split(name, i, NULL, zonename); /* ask SDLZ driver if the zone is supported */ dlzdatabase = view->dlzdatabase; findzone = dlzdatabase->implementation->methods->findzone; result = (*findzone)(dlzdatabase->implementation->driverarg, dlzdatabase->dbdata, dlzdatabase->mctx, view->rdclass, zonename, dbp); if (result != ISC_R_NOTFOUND) return (result); } return (ISC_R_NOTFOUND); }
isc_result_t dns_dlzallowzonexfr(dns_view_t *view, dns_name_t *name, isc_sockaddr_t *clientaddr, dns_db_t **dbp) { isc_result_t result = ISC_R_NOTFOUND; dns_dlzallowzonexfr_t allowzonexfr; dns_dlzdb_t *dlzdb; /* * Performs checks to make sure data is as we expect it to be. */ REQUIRE(name != NULL); REQUIRE(dbp != NULL && *dbp == NULL); /* * Find a driver in which the zone exists and transfer is supported */ for (dlzdb = ISC_LIST_HEAD(view->dlz_searched); dlzdb != NULL; dlzdb = ISC_LIST_NEXT(dlzdb, link)) { REQUIRE(DNS_DLZ_VALID(dlzdb)); allowzonexfr = dlzdb->implementation->methods->allowzonexfr; result = (*allowzonexfr)(dlzdb->implementation->driverarg, dlzdb->dbdata, dlzdb->mctx, view->rdclass, name, clientaddr, dbp); /* * if ISC_R_NOPERM, we found the right database but * the zone may not transfer. */ if (result == ISC_R_SUCCESS || result == ISC_R_NOPERM) return (result); } if (result == ISC_R_NOTIMPLEMENTED) result = ISC_R_NOTFOUND; return (result); }
/*% * Configure a DLZ driver. This is optional, and if supplied gives * the backend an opportunity to configure parameters related to DLZ. */ isc_result_t dns_dlzconfigure(dns_view_t *view, dns_dlzdb_t *dlzdb, dlzconfigure_callback_t callback) { dns_dlzimplementation_t *impl; isc_result_t result; REQUIRE(DNS_DLZ_VALID(dlzdb)); REQUIRE(dlzdb->implementation != NULL); impl = dlzdb->implementation; if (impl->methods->configure == NULL) return (ISC_R_SUCCESS); dlzdb->configure_callback = callback; result = impl->methods->configure(impl->driverarg, dlzdb->dbdata, view, dlzdb); return (result); }
/*% * Configure a DLZ driver. This is optional, and if supplied gives * the backend an opportunity to configure parameters related to DLZ. */ isc_result_t dns_dlzconfigure(dns_view_t *view, isc_result_t (*callback)(dns_view_t *, dns_zone_t *)) { dns_dlzimplementation_t *impl; dns_dlzdb_t *dlzdatabase; isc_result_t result; REQUIRE(view != NULL); REQUIRE(DNS_DLZ_VALID(view->dlzdatabase)); REQUIRE(view->dlzdatabase->implementation != NULL); dlzdatabase = view->dlzdatabase; impl = dlzdatabase->implementation; if (impl->methods->configure == NULL) return (ISC_R_SUCCESS); dlzdatabase->configure_callback = callback; result = impl->methods->configure(impl->driverarg, dlzdatabase->dbdata, view); return (result); }
/* * Create a writeable DLZ zone. This can be called by DLZ drivers * during configure() to create a zone that can be updated. The zone * type is set to dns_zone_dlz, which is equivalent to a master zone * * This function uses a callback setup in dns_dlzconfigure() to call * into the server zone code to setup the remaining pieces of server * specific functionality on the zone */ isc_result_t dns_dlz_writeablezone(dns_view_t *view, const char *zone_name) { dns_zone_t *zone = NULL; dns_zone_t *dupzone = NULL; isc_result_t result; isc_buffer_t buffer; dns_fixedname_t fixorigin; dns_name_t *origin; dns_dlzdb_t *dlzdatabase; REQUIRE(DNS_DLZ_VALID(view->dlzdatabase)); dlzdatabase = view->dlzdatabase; REQUIRE(dlzdatabase->configure_callback != NULL); isc_buffer_init(&buffer, zone_name, strlen(zone_name)); isc_buffer_add(&buffer, strlen(zone_name)); dns_fixedname_init(&fixorigin); result = dns_name_fromtext(dns_fixedname_name(&fixorigin), &buffer, dns_rootname, 0, NULL); if (result != ISC_R_SUCCESS) goto cleanup; origin = dns_fixedname_name(&fixorigin); /* See if the zone already exists */ result = dns_view_findzone(view, origin, &dupzone); if (result == ISC_R_SUCCESS) { dns_zone_detach(&dupzone); result = ISC_R_EXISTS; goto cleanup; } INSIST(dupzone == NULL); /* Create it */ result = dns_zone_create(&zone, view->mctx); if (result != ISC_R_SUCCESS) goto cleanup; result = dns_zone_setorigin(zone, origin); if (result != ISC_R_SUCCESS) goto cleanup; dns_zone_setview(zone, view); dns_zone_setadded(zone, ISC_TRUE); if (dlzdatabase->ssutable == NULL) { result = dns_ssutable_createdlz(dlzdatabase->mctx, &dlzdatabase->ssutable, view->dlzdatabase); if (result != ISC_R_SUCCESS) goto cleanup; } dns_zone_setssutable(zone, dlzdatabase->ssutable); result = dlzdatabase->configure_callback(view, zone); if (result != ISC_R_SUCCESS) goto cleanup; /* * Add the zone to its view in the new view list. */ result = dns_view_addzone(view, zone); cleanup: if (zone != NULL) dns_zone_detach(&zone); return (result); }
/* * Create a writeable DLZ zone. This can be called by DLZ drivers * during configure() to create a zone that can be updated. The zone * type is set to dns_zone_dlz, which is equivalent to a master zone * * This function uses a callback setup in dns_dlzconfigure() to call * into the server zone code to setup the remaining pieces of server * specific functionality on the zone */ isc_result_t dns_dlz_writeablezone(dns_view_t *view, dns_dlzdb_t *dlzdb, const char *zone_name) { dns_zone_t *zone = NULL; dns_zone_t *dupzone = NULL; isc_result_t result; isc_buffer_t buffer; dns_fixedname_t fixorigin; dns_name_t *origin; REQUIRE(DNS_DLZ_VALID(dlzdb)); REQUIRE(dlzdb->configure_callback != NULL); isc_buffer_constinit(&buffer, zone_name, strlen(zone_name)); isc_buffer_add(&buffer, strlen(zone_name)); dns_fixedname_init(&fixorigin); result = dns_name_fromtext(dns_fixedname_name(&fixorigin), &buffer, dns_rootname, 0, NULL); if (result != ISC_R_SUCCESS) goto cleanup; origin = dns_fixedname_name(&fixorigin); if (!dlzdb->search) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_WARNING, "DLZ %s has 'search no;', but attempted to " "register writeable zone %s.", dlzdb->dlzname, zone_name); result = ISC_R_SUCCESS; goto cleanup; } /* See if the zone already exists */ result = dns_view_findzone(view, origin, &dupzone); if (result == ISC_R_SUCCESS) { dns_zone_detach(&dupzone); result = ISC_R_EXISTS; goto cleanup; } INSIST(dupzone == NULL); /* Create it */ result = dns_zone_create(&zone, view->mctx); if (result != ISC_R_SUCCESS) goto cleanup; result = dns_zone_setorigin(zone, origin); if (result != ISC_R_SUCCESS) goto cleanup; dns_zone_setview(zone, view); dns_zone_setadded(zone, ISC_TRUE); if (dlzdb->ssutable == NULL) { result = dns_ssutable_createdlz(dlzdb->mctx, &dlzdb->ssutable, dlzdb); if (result != ISC_R_SUCCESS) goto cleanup; } dns_zone_setssutable(zone, dlzdb->ssutable); result = dlzdb->configure_callback(view, dlzdb, zone); if (result != ISC_R_SUCCESS) goto cleanup; result = dns_view_addzone(view, zone); cleanup: if (zone != NULL) dns_zone_detach(&zone); return (result); }