]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
effective config: specific view cases
authorColin Vidal <colin@isc.org>
Thu, 16 Oct 2025 14:33:51 +0000 (16:33 +0200)
committerEvan Hunt <each@isc.org>
Wed, 29 Oct 2025 20:55:04 +0000 (13:55 -0700)
User specified views don't override default views. In particular, the
_bind/CH view is still active. However, the order is important: if the
user defines a foo/CH view, it must be able to override _bind/CH by
matching clients first (this is how the view is documented).

The server configuration code is now simpler; it only has to build the
views based on the effective view list, and only creates the _default
view if there are no explicit views created by the user.

bin/named/server.c
lib/isccfg/namedconf.c

index 653c915ee21c7006e925279615cffbb5d77045f3..8742428e8af81f85ef83b41090871e5d381996f8 100644 (file)
@@ -3827,6 +3827,7 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
                maps[i++] = voptions;
                cfgmaps[j++] = voptions;
        }
+
        if (options != NULL) {
                maps[i++] = options;
        }
@@ -7631,47 +7632,65 @@ static isc_result_t
 create_views(cfg_obj_t *config, cfg_aclconfctx_t *aclctx,
             dns_viewlist_t *viewlist) {
        isc_result_t result = ISC_R_SUCCESS;
+       const cfg_obj_t *bindview = NULL;
        const cfg_obj_t *views = NULL;
+       bool explicitviews = false;
+       dns_view_t *view = NULL;
 
        APPLY_CONFIGURATION_SUBROUTINE_LOG;
 
        (void)cfg_map_get(config, "view", &views);
        CFG_LIST_FOREACH(views, element) {
                cfg_obj_t *vconfig = cfg_listelt_value(element);
-               dns_view_t *view = NULL;
+               const char *vname = NULL;
+               dns_rdataclass_t vclass;
 
-               result = create_view(vconfig, viewlist, &view);
-               if (result != ISC_R_SUCCESS) {
-                       return result;
+               /*
+                * Skip the addition of the _bind/CHAOS zone until
+                * after all the others.
+                */
+               CHECK(get_viewinfo(vconfig, &vname, &vclass));
+
+               if (strcmp(vname, "_bind") == 0 &&
+                   vclass == dns_rdataclass_chaos)
+               {
+                       INSIST(cfg_list_next(element) == NULL);
+                       bindview = vconfig;
+                       continue;
                }
+
+               CHECK(create_view(vconfig, viewlist, &view));
                INSIST(view != NULL);
 
                result = setup_newzones(view, config, vconfig, aclctx);
-               dns_view_detach(&view);
+               explicitviews = true;
 
-               if (result != ISC_R_SUCCESS) {
-                       return result;
-               }
+               dns_view_detach(&view);
        }
 
        /*
         * If there were no explicit views then we do the default
         * view here.
         */
-       if (views == NULL) {
-               dns_view_t *view = NULL;
-
-               result = create_view(NULL, viewlist, &view);
-               if (result != ISC_R_SUCCESS) {
-                       return result;
-               }
+       if (explicitviews == false) {
+               CHECK(create_view(NULL, viewlist, &view));
                INSIST(view != NULL);
 
-               result = setup_newzones(view, config, NULL, aclctx);
-
+               CHECK(setup_newzones(view, config, NULL, aclctx));
                dns_view_detach(&view);
        }
 
+       /*
+        * Finally, add _bind/CHAOS.
+        */
+       INSIST(bindview != NULL);
+       CHECK(create_view(bindview, viewlist, &view));
+       INSIST(view != NULL);
+
+cleanup:
+       if (view != NULL) {
+               dns_view_detach(&view);
+       }
        return result;
 }
 
@@ -7685,6 +7704,7 @@ configure_views(cfg_obj_t *config, const cfg_obj_t *bindkeys,
        isc_result_t result = ISC_R_SUCCESS;
        const cfg_obj_t *views = NULL;
        dns_viewlist_t tmpviewlist;
+       bool explicitviews = false;
 
        APPLY_CONFIGURATION_SUBROUTINE_LOG;
 
@@ -7711,6 +7731,13 @@ configure_views(cfg_obj_t *config, const cfg_obj_t *bindkeys,
                        dns_view_detach(&view);
                        return result;
                }
+
+               if (!(strcmp(view->name, "_bind") == 0 &&
+                     view->rdclass == dns_rdataclass_chaos))
+               {
+                       explicitviews = true;
+               }
+
                dns_view_freeze(view);
                dns_view_detach(&view);
        }
@@ -7719,7 +7746,7 @@ configure_views(cfg_obj_t *config, const cfg_obj_t *bindkeys,
         * Make sure we have a default view if and only if there
         * were no explicit views.
         */
-       if (views == NULL) {
+       if (explicitviews == false) {
                dns_view_t *view = NULL;
                result = find_view(NULL, viewlist, &view);
                if (result != ISC_R_SUCCESS) {
@@ -7737,33 +7764,6 @@ configure_views(cfg_obj_t *config, const cfg_obj_t *bindkeys,
                dns_view_detach(&view);
        }
 
-       /*
-        * Create (or recreate) the built-in views.
-        */
-       views = NULL;
-       RUNTIME_CHECK(cfg_map_get(named_g_defaultconfig, "view", &views) ==
-                     ISC_R_SUCCESS);
-       CFG_LIST_FOREACH(views, element) {
-               cfg_obj_t *vconfig = cfg_listelt_value(element);
-               dns_view_t *view = NULL;
-
-               result = create_view(vconfig, viewlist, &view);
-               if (result != ISC_R_SUCCESS) {
-                       return result;
-               }
-
-               result = configure_view(view, viewlist, config, vconfig,
-                                       cachelist, &server->cachelist, kasplist,
-                                       bindkeys, isc_g_mctx, aclctx,
-                                       tlsctx_client_cache, false, first_time);
-               if (result != ISC_R_SUCCESS) {
-                       dns_view_detach(&view);
-                       return result;
-               }
-               dns_view_freeze(view);
-               dns_view_detach(&view);
-       }
-
        /*
         * Commit any dns_zone_setview() calls on all zones in the new
         * view.
index 85ea405a01a7a3eeee5ed474696f8da51b7d90ef..2e39482173e7f33f6121db70125cd99edb1b312a 100644 (file)
@@ -1196,6 +1196,11 @@ map_merge(cfg_obj_t *effectivemap, const cfg_obj_t *defaultmap) {
        }
 }
 
+static void
+merge_append(cfg_obj_t *effectiveobj, const cfg_obj_t *defaultobj) {
+       cfg_list_addclone(effectiveobj, defaultobj, false);
+}
+
 static void
 options_merge_defaultacl(cfg_obj_t *effectiveoptions,
                         const cfg_obj_t *defaultoptions, const char *aclname,
@@ -1363,7 +1368,7 @@ static cfg_clausedef_t namedconf_clauses[] = {
 #endif
        { "template", &cfg_type_template, CFG_CLAUSEFLAG_MULTI },
        { "tls", &cfg_type_tlsconf, CFG_CLAUSEFLAG_MULTI },
-       { "view", &cfg_type_view, CFG_CLAUSEFLAG_MULTI },
+       { "view", &cfg_type_view, CFG_CLAUSEFLAG_MULTI, merge_append },
        { NULL, NULL, 0 }
 };