]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
effective config: specific check-names case
authorColin Vidal <colin@isc.org>
Thu, 16 Oct 2025 15:14:14 +0000 (17:14 +0200)
committerEvan Hunt <each@isc.org>
Wed, 29 Oct 2025 20:55:04 +0000 (13:55 -0700)
There are multiple check-names options provided in the default
configuration, and they must "complete" those provided by the user.
This is now handled when building the effective tree.

lib/isccfg/namedconf.c

index b302daf5e35981c3a52dd5711eb9e14c4f54808b..37fb30eb92db14104a26a4dac7d613e018a48ee6 100644 (file)
@@ -2250,6 +2250,45 @@ prefetch_merge(cfg_obj_t *effectiveobj, const cfg_obj_t *defaultobj) {
        }
 }
 
+static void
+checknames_merge(cfg_obj_t *effectiveobj, const cfg_obj_t *defaultobj) {
+       /*
+        * Applies only to the top-level option `check-names` statement.
+        * The view and zone-level versions aren't merged into the defaults
+        * the way global options are.
+        */
+       REQUIRE(cfg_obj_islist(effectiveobj));
+       REQUIRE(cfg_obj_islist(defaultobj));
+
+       CFG_LIST_FOREACH(defaultobj, delt) {
+               const cfg_obj_t *checkname = cfg_listelt_value(delt);
+               const cfg_obj_t *type = cfg_tuple_get(checkname, "type");
+               bool found = false;
+
+               CFG_LIST_FOREACH(effectiveobj, eelt) {
+                       const cfg_obj_t *echeckname = cfg_listelt_value(eelt);
+                       const cfg_obj_t *etype = cfg_tuple_get(echeckname,
+                                                              "type");
+
+                       if (strcasecmp(type->value.string.base,
+                                      etype->value.string.base) == 0)
+                       {
+                               found = true;
+                               break;
+                       }
+               }
+
+               if (found == false) {
+                       cfg_listelt_t *eelt = isc_mem_get(effectiveobj->mctx,
+                                                         sizeof(*eelt));
+
+                       *eelt = (cfg_listelt_t){ .link = ISC_LINK_INITIALIZER };
+                       cfg_obj_clone(checkname, &eelt->obj);
+                       ISC_LIST_APPEND(effectiveobj->value.list, eelt, link);
+               }
+       }
+}
+
 /*%
  * Clauses that can be found within the 'view' statement,
  * with defaults in the 'options' statement.
@@ -2273,7 +2312,8 @@ static cfg_clausedef_t view_clauses[] = {
        { "auth-nxdomain", &cfg_type_boolean, 0 },
        { "cache-file", NULL, CFG_CLAUSEFLAG_ANCIENT },
        { "catalog-zones", &cfg_type_catz, 0 },
-       { "check-names", &cfg_type_checknames, CFG_CLAUSEFLAG_MULTI },
+       { "check-names", &cfg_type_checknames, CFG_CLAUSEFLAG_MULTI,
+         checknames_merge },
        { "cleaning-interval", NULL, CFG_CLAUSEFLAG_ANCIENT },
        { "clients-per-query", &cfg_type_uint32, 0 },
        { "deny-answer-addresses", &cfg_type_denyaddresses, 0 },