]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Handle duplicate catalog zone entries gracefully
authorMark Andrews <marka@isc.org>
Wed, 22 Sep 2021 05:21:45 +0000 (15:21 +1000)
committerMark Andrews <marka@isc.org>
Tue, 26 Oct 2021 14:32:57 +0000 (01:32 +1100)
Duplicate catalog zone entries caused an assertion failure
in named during configuration.  This is now a soft error
that is detected earlier by named and also by named-checkconf.

bin/tests/system/checkconf/bad-catz-zone-dup.conf [new file with mode: 0644]
lib/bind9/check.c

diff --git a/bin/tests/system/checkconf/bad-catz-zone-dup.conf b/bin/tests/system/checkconf/bad-catz-zone-dup.conf
new file mode 100644 (file)
index 0000000..6488211
--- /dev/null
@@ -0,0 +1,8 @@
+options {
+       catalog-zones { zone example.com; zone example.com; };
+};
+
+zone example.com {
+       type primary;
+       file "example.com";
+};
index d34f7774bd56a79535fe5b7ebd1a6e9dad26e5f1..85e3884df3ff3281027a3d12ab8bcd3fc156cb7b 100644 (file)
@@ -1465,15 +1465,17 @@ check_options(const cfg_obj_t *options, const cfg_obj_t *config,
                                            &symtab);
                if (tresult != ISC_R_SUCCESS) {
                        result = tresult;
-               }
-               for (element = cfg_list_first(obj); element != NULL;
-                    element = cfg_list_next(element))
-               {
-                       obj = cfg_listelt_value(element);
-                       tresult = mustbesecure(obj, symtab, logctx, mctx);
-                       if (result == ISC_R_SUCCESS && tresult != ISC_R_SUCCESS)
+               } else {
+                       for (element = cfg_list_first(obj); element != NULL;
+                            element = cfg_list_next(element))
                        {
-                               result = tresult;
+                               obj = cfg_listelt_value(element);
+                               tresult = mustbesecure(obj, symtab, logctx,
+                                                      mctx);
+                               if (result == ISC_R_SUCCESS &&
+                                   tresult != ISC_R_SUCCESS) {
+                                       result = tresult;
+                               }
                        }
                }
                if (symtab != NULL) {
@@ -4829,29 +4831,58 @@ check_rpz_catz(const char *rpz_catz, const cfg_obj_t *rpz_obj,
 }
 
 static isc_result_t
-check_catz(const cfg_obj_t *catz_obj, const char *viewname, isc_log_t *logctx) {
+check_catz(const cfg_obj_t *catz_obj, const char *viewname, isc_mem_t *mctx,
+          isc_log_t *logctx) {
        const cfg_listelt_t *element;
        const cfg_obj_t *obj, *nameobj, *primariesobj;
        const char *zonename;
        const char *forview = " for view ";
-       isc_result_t result;
+       isc_result_t result, tresult;
+       isc_symtab_t *symtab = NULL;
+       dns_fixedname_t fixed;
+       dns_name_t *name = dns_fixedname_initname(&fixed);
 
        if (viewname == NULL) {
                viewname = "";
                forview = "";
        }
 
-       result = ISC_R_SUCCESS;
+       result = isc_symtab_create(mctx, 100, freekey, mctx, false, &symtab);
+       if (result != ISC_R_SUCCESS) {
+               return (result);
+       }
 
        obj = cfg_tuple_get(catz_obj, "zone list");
 
        for (element = cfg_list_first(obj); element != NULL;
             element = cfg_list_next(element))
        {
+               char namebuf[DNS_NAME_FORMATSIZE];
+
                obj = cfg_listelt_value(element);
                nameobj = cfg_tuple_get(obj, "zone name");
                zonename = cfg_obj_asstring(nameobj);
 
+               tresult = dns_name_fromstring(name, zonename, 0, NULL);
+               if (tresult != ISC_R_SUCCESS) {
+                       cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
+                                   "bad domain name '%s'", zonename);
+                       if (result == ISC_R_SUCCESS) {
+                               result = tresult;
+                               continue;
+                       }
+               }
+
+               dns_name_format(name, namebuf, sizeof(namebuf));
+               tresult =
+                       nameexist(nameobj, namebuf, 1, symtab,
+                                 "catalog zone '%s': already added here %s:%u",
+                                 logctx, mctx);
+               if (tresult != ISC_R_SUCCESS) {
+                       result = tresult;
+                       continue;
+               }
+
                primariesobj = cfg_tuple_get(obj, "default-primaries");
                if (primariesobj != NULL && cfg_obj_istuple(primariesobj)) {
                        primariesobj = cfg_tuple_get(obj, "default-masters");
@@ -4869,6 +4900,10 @@ check_catz(const cfg_obj_t *catz_obj, const char *viewname, isc_log_t *logctx) {
                }
        }
 
+       if (symtab != NULL) {
+               isc_symtab_destroy(&symtab);
+       }
+
        return (result);
 }
 
@@ -5058,7 +5093,7 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions,
                obj = NULL;
                if ((cfg_map_get(opts, "catalog-zones", &obj) ==
                     ISC_R_SUCCESS) &&
-                   (check_catz(obj, viewname, logctx) != ISC_R_SUCCESS))
+                   (check_catz(obj, viewname, mctx, logctx) != ISC_R_SUCCESS))
                {
                        result = ISC_R_FAILURE;
                }