]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
1986. [func] Report when a zone is removed. [RT #15849]
authorMark Andrews <marka@isc.org>
Tue, 21 Feb 2006 23:12:27 +0000 (23:12 +0000)
committerMark Andrews <marka@isc.org>
Tue, 21 Feb 2006 23:12:27 +0000 (23:12 +0000)
CHANGES
bin/named/server.c
lib/dns/include/dns/zone.h
lib/dns/zone.c

diff --git a/CHANGES b/CHANGES
index 914bf3ce0a463da789af2830729d267da65bb21a..aa88f7fcda6062da38f0db8fc8972df870f4af54 100644 (file)
--- 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]
 
index 6541c3cf51bf1e4d78143c247721c319a0a04c8a..43ab0dcdf9fd314369247f80d9ccfb5cbd736b04 100644 (file)
@@ -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);
-
        }
 
        /*
index e39832734e44e40abbb2069174e3b6f71ccd3e0c..163795879949aa36a3d4c0626634e26026f8d304 100644 (file)
@@ -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);
 /*%<
index a954a1af49f4ca9105e66d6f5e11d28922486865..1b19ac9888443420ab512dd6e42b722aa8fd53c2 100644 (file)
@@ -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);