From 1f54a9107dfe14ed2194a8371d4a994fe8238e5b Mon Sep 17 00:00:00 2001 From: Colin Vidal Date: Thu, 16 Oct 2025 16:50:30 +0200 Subject: [PATCH] effective config: specific dnssec-policy case Default dnssec-policies are not overridden by user-provided ones. Add this specific case to make sure those are kept, and also ensure that the default dnssec-policy is always in the first position (which is an implicit requirement in the existing implementation). Also simplify the server configuration code, as it only needs to build the list of dnssec-policy based on the effective config list. --- bin/named/server.c | 36 ++++++++---------------------------- lib/isccfg/namedconf.c | 16 +++++++++++++++- 2 files changed, 23 insertions(+), 29 deletions(-) diff --git a/bin/named/server.c b/bin/named/server.c index 8742428e8a..595043d466 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -7833,37 +7833,9 @@ configure_kasplist(const cfg_obj_t *config, dns_kasplist_t *kasplist, APPLY_CONFIGURATION_SUBROUTINE_LOG; - /* - * Create the built-in kasp policies ("default", "insecure"). - */ - (void)cfg_map_get(named_g_defaultconfig, "dnssec-policy", &kasps); - CFG_LIST_FOREACH(kasps, element) { - cfg_obj_t *kconfig = cfg_listelt_value(element); - dns_kasp_t *kasp = NULL; - - result = cfg_kasp_fromconfig(kconfig, default_kasp, kaspopts, - isc_g_mctx, keystorelist, kasplist, - &kasp); - if (result != ISC_R_SUCCESS) { - return result; - } - INSIST(kasp != NULL); - dns_kasp_freeze(kasp); - - /* Insist that the first built-in policy is the default one. */ - if (default_kasp == NULL) { - INSIST(strcmp(dns_kasp_getname(kasp), "default") == 0); - dns_kasp_attach(kasp, &default_kasp); - } - - dns_kasp_detach(&kasp); - } - INSIST(default_kasp != NULL); - /* * Create the DNSSEC key and signing policies (KASP). */ - kasps = NULL; (void)cfg_map_get(config, "dnssec-policy", &kasps); CFG_LIST_FOREACH(kasps, element) { cfg_obj_t *kconfig = cfg_listelt_value(element); @@ -7875,8 +7847,16 @@ configure_kasplist(const cfg_obj_t *config, dns_kasplist_t *kasplist, if (result != ISC_R_SUCCESS) { return result; } + INSIST(kasp != NULL); dns_kasp_freeze(kasp); + + /* Insist that the first built-in policy is the default one. */ + if (default_kasp == NULL) { + INSIST(strcmp(dns_kasp_getname(kasp), "default") == 0); + dns_kasp_attach(kasp, &default_kasp); + } + dns_kasp_detach(&kasp); } dns_kasp_detach(&default_kasp); diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index 2e39482173..ee632a98e8 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -1196,6 +1196,19 @@ map_merge(cfg_obj_t *effectivemap, const cfg_obj_t *defaultmap) { } } +/* + * These are used when merging clauses with CFG_CLAUSEFLAG_MULTI, where + * the entries from the user configuration and the default configuration + * are added together, rather than the user configuration overriding the + * default. merge_prepend() puts the default configuration at the + * beginning of the cloned object (for example, for dnssec-policy), and + * merge_append() puts it at the end (for example, for views). + */ +static void +merge_prepend(cfg_obj_t *effectiveobj, const cfg_obj_t *defaultobj) { + cfg_list_addclone(effectiveobj, defaultobj, true); +} + static void merge_append(cfg_obj_t *effectiveobj, const cfg_obj_t *defaultobj) { cfg_list_addclone(effectiveobj, defaultobj, false); @@ -1340,7 +1353,8 @@ options_merge(cfg_obj_t *effectiveoptions, const cfg_obj_t *defaultoptions) { static cfg_clausedef_t namedconf_clauses[] = { { "acl", &cfg_type_acl, CFG_CLAUSEFLAG_MULTI }, { "controls", &cfg_type_controls, CFG_CLAUSEFLAG_MULTI }, - { "dnssec-policy", &cfg_type_dnssecpolicy, CFG_CLAUSEFLAG_MULTI }, + { "dnssec-policy", &cfg_type_dnssecpolicy, CFG_CLAUSEFLAG_MULTI, + merge_prepend }, #if HAVE_LIBNGHTTP2 { "http", &cfg_type_http_description, CFG_CLAUSEFLAG_MULTI | CFG_CLAUSEFLAG_OPTIONAL },