diff --git a/CHANGES b/CHANGES index 914bf3ce0a..aa88f7fcda 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,5 @@ +1986. [func] Report when a zone is removed. [RT #15849] + 1985. [protocol] DLV has now been assigned a official type code of 32769. [RT #15807] diff --git a/bin/named/server.c b/bin/named/server.c index 6541c3cf51..43ab0dcdf9 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: server.c,v 1.456 2006/02/17 00:24:20 marka Exp $ */ +/* $Id: server.c,v 1.457 2006/02/21 23:12:27 marka Exp $ */ /*! \file */ @@ -215,10 +215,6 @@ static const struct { { NULL, ISC_FALSE } }; -static const char *empty_dbtype[] = { "_builtin", "empty", NULL, NULL }; -static unsigned int empty_dbtypec = - (sizeof(empty_dbtype) / sizeof(empty_dbtype[0])); - static void fatal(const char *msg, isc_result_t result); @@ -847,6 +843,38 @@ on_disable_list(cfg_obj_t *disablelist, dns_name_t *zonename) { return (ISC_FALSE); } +static void +check_dbtype(dns_zone_t **zonep, unsigned int dbtypec, const char **dbargv, + isc_mem_t *mctx) +{ + char **argv = NULL; + unsigned int i; + isc_result_t result; + + result = dns_zone_getdbtype(*zonep, &argv, mctx); + if (result != ISC_R_SUCCESS) { + dns_zone_detach(zonep); + return; + } + + /* + * Check that all the arguments match. + */ + for (i = 0; i < dbtypec; i++) + if (argv[i] == NULL || strcmp(argv[i], dbargv[i]) != 0) { + dns_zone_detach(zonep); + break; + } + + /* + * Check that there are not extra arguments. + */ + if (i == dbtypec && argv[i] != NULL) + dns_zone_detach(zonep); + isc_mem_free(mctx, argv); +} + + /* * Configure 'view' according to 'vconfig', taking defaults from 'config' * where values are missing in 'vconfig'. @@ -1598,6 +1626,9 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig, char server[DNS_NAME_FORMATSIZE + 1]; char contact[DNS_NAME_FORMATSIZE + 1]; isc_boolean_t logit; + const char *empty_dbtype[4] = + { "_builtin", "empty", NULL, NULL }; + int empty_dbtypec = 4; dns_fixedname_init(&fixed); name = dns_fixedname_name(&fixed); @@ -1638,6 +1669,7 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig, empty = empty_zones[++empty_zone].zone) { dns_forwarders_t *forwarders = NULL; + dns_view_t *pview = NULL; isc_buffer_init(&buffer, empty, strlen(empty)); isc_buffer_add(&buffer, strlen(empty)); @@ -1686,6 +1718,29 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig, continue; } + /* + * See if we can re-use a existing zone. + */ + result = dns_viewlist_find(&ns_g_server->viewlist, + view->name, view->rdclass, + &pview); + if (result != ISC_R_NOTFOUND && + result != ISC_R_SUCCESS) + goto cleanup; + + if (pview != NULL) { + (void)dns_view_findzone(pview, name, &zone); + dns_view_detach(&pview); + if (zone != NULL) + check_dbtype(&zone, empty_dbtypec, + empty_dbtype, mctx); + if (zone != NULL) { + dns_zone_setview(zone, view); + dns_zone_detach(&zone); + continue; + } + } + CHECK(dns_zone_create(&zone, mctx)); CHECK(dns_zone_setorigin(zone, name)); dns_zone_setview(zone, view); @@ -2142,10 +2197,8 @@ configure_zone(cfg_obj_t *config, cfg_obj_t *zconfig, cfg_obj_t *vconfig, result = dns_view_findzone(pview, origin, &zone); if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS) goto cleanup; - if (zone != NULL) { - if (! ns_zone_reusable(zone, zconfig)) - dns_zone_detach(&zone); - } + if (zone != NULL && !ns_zone_reusable(zone, zconfig)) + dns_zone_detach(&zone); if (zone != NULL) { /* @@ -2552,6 +2605,31 @@ portlist_fromconf(dns_portlist_t *portlist, unsigned int family, return (result); } +static isc_result_t +removed(dns_zone_t *zone, void *uap) { + const char *type; + + if (dns_zone_getview(zone) != uap) + return (ISC_R_SUCCESS); + + switch (dns_zone_gettype(zone)) { + case dns_zone_master: + type = "master"; + break; + case dns_zone_slave: + type = "slave"; + break; + case dns_zone_stub: + type = "stub"; + break; + default: + type = "other"; + break; + } + dns_zone_log(zone, ISC_LOG_INFO, "(%s) removed", type); + return (ISC_R_SUCCESS); +} + static isc_result_t load_configuration(const char *filename, ns_server_t *server, isc_boolean_t first_time) @@ -3186,8 +3264,11 @@ load_configuration(const char *filename, ns_server_t *server, view = view_next) { view_next = ISC_LIST_NEXT(view, link); ISC_LIST_UNLINK(viewlist, view, link); + if (result == ISC_R_SUCCESS && + strcmp(view->name, "_bind") != 0) + (void)dns_zt_apply(view->zonetable, ISC_FALSE, + removed, view); dns_view_detach(&view); - } /* diff --git a/lib/dns/include/dns/zone.h b/lib/dns/include/dns/zone.h index e39832734e..1637958799 100644 --- a/lib/dns/include/dns/zone.h +++ b/lib/dns/include/dns/zone.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: zone.h,v 1.141 2006/01/06 00:01:44 marka Exp $ */ +/* $Id: zone.h,v 1.142 2006/02/21 23:12:27 marka Exp $ */ #ifndef DNS_ZONE_H #define DNS_ZONE_H 1 @@ -356,6 +356,22 @@ dns_zone_setdbtype(dns_zone_t *zone, *\li #ISC_R_SUCCESS */ +isc_result_t +dns_zone_getdbtype(dns_zone_t *zone, char ***argv, isc_mem_t *mctx); +/*%< + * Returns the current dbtype. isc_mem_free() should be used + * to free 'argv' after use. + * + * Require: + *\li 'zone' to be a valid zone. + *\li 'argv' to be non NULL and *argv to be NULL. + *\li 'mctx' to be valid. + * + * Returns: + *\li #ISC_R_NOMEMORY + *\li #ISC_R_SUCCESS + */ + void dns_zone_markdirty(dns_zone_t *zone); /*%< diff --git a/lib/dns/zone.c b/lib/dns/zone.c index a954a1af49..1b19ac9888 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: zone.c,v 1.451 2006/02/17 00:24:21 marka Exp $ */ +/* $Id: zone.c,v 1.452 2006/02/21 23:12:27 marka Exp $ */ /*! \file */ @@ -799,6 +799,39 @@ zone_freedbargs(dns_zone_t *zone) { zone->db_argv = NULL; } +isc_result_t +dns_zone_getdbtype(dns_zone_t *zone, char ***argv, isc_mem_t *mctx) { + size_t size = 0; + unsigned int i; + isc_result_t result = ISC_R_SUCCESS; + void *mem; + char **tmp, *tmp2; + + REQUIRE(DNS_ZONE_VALID(zone)); + REQUIRE(argv != NULL && *argv == NULL); + + LOCK_ZONE(zone); + size = (zone->db_argc + 1) * sizeof(char *); + for (i = 0; i < zone->db_argc; i++) + size += strlen(zone->db_argv[i]) + 1; + mem = isc_mem_allocate(mctx, size); + if (mem != NULL) { + tmp = mem; + tmp2 = mem; + tmp2 += (zone->db_argc + 1) * sizeof(char *); + for (i = 0; i < zone->db_argc; i++) { + *tmp++ = tmp2; + strcpy(tmp2, zone->db_argv[i]); + tmp2 += strlen(tmp2) + 1; + } + *tmp = NULL; + } else + result = ISC_R_NOMEMORY; + UNLOCK_ZONE(zone); + *argv = mem; + return (result); +} + isc_result_t dns_zone_setdbtype(dns_zone_t *zone, unsigned int dbargc, const char * const *dbargv) { @@ -5946,7 +5979,8 @@ dns_zone_getmaxxfrout(dns_zone_t *zone) { return (zone->maxxfrout); } -dns_zonetype_t dns_zone_gettype(dns_zone_t *zone) { +dns_zonetype_t +dns_zone_gettype(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (zone->type);