From: Colin Vidal Date: Tue, 25 Nov 2025 09:16:13 +0000 (+0100) Subject: minimal fix for missing `key`/`tls` in named `remote-servers` X-Git-Tag: v9.21.16~18^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e732a8d25a8cbb78eed50b33d2569e8e9ea6e038;p=thirdparty%2Fbind9.git minimal fix for missing `key`/`tls` in named `remote-servers` The following case remote-servers foo { 10.53.0.5; }; remote-servers bar { foo key fookey; }; did not work: the `fookey` was silently ignored. No matter how `bar` was used, the server `10.53.0.5` wouldn't be contacted using the TSIG key `fookey`. The problem is the same the for `tls` property. The reason of the problem was that when `named_config_getipandkeylist()` reached a named server-list (here, `foo`), it modified the current context in order to immediately process what is inside `foo`, but forgot to look at the fields `key` and `tls`, to associate those with `foo` addresses. Fix the problem by wrapping the `key` and `tls` from the "caller" list inside the existing `lists` struct which is used to figure out if a list is already processed or not. That way, the `key` and `tls` values can be read when adding the addresses of the nested list. --- diff --git a/bin/named/config.c b/bin/named/config.c index 05c832798a1..6e0c835bc30 100644 --- a/bin/named/config.c +++ b/bin/named/config.c @@ -353,9 +353,8 @@ named_config_getipandkeylist(const cfg_obj_t *config, const cfg_obj_t *list, dns_name_t **tlss = NULL; struct { const char *name; - in_port_t port; - isc_sockaddr_t *src4s; - isc_sockaddr_t *src6s; + dns_name_t *key; + dns_name_t *tls; } *lists = NULL; struct { const cfg_listelt_t *element; @@ -462,7 +461,20 @@ resume: result = tresult; goto cleanup; } - lists[l++].name = listname; + lists[l].name = listname; + + result = named_config_getname(mctx, key, &lists[l].key); + if (result != ISC_R_SUCCESS) { + goto cleanup; + } + + result = named_config_getname(mctx, tls, &lists[l].tls); + if (result != ISC_R_SUCCESS) { + goto cleanup; + } + + l++; + /* Grow stack? */ grow_array(mctx, stack, pushed, stackcount); /* @@ -491,6 +503,12 @@ resume: goto cleanup; } + if (keys[i] == NULL && lists != NULL && lists[l-1].key != NULL) { + keys[i] = isc_mem_get(mctx, sizeof(*keys[i])); + dns_name_init(keys[i]); + dns_name_dup(lists[l-1].key, mctx, keys[i]); + } + result = named_config_getname(mctx, tls, &tlss[i]); if (result != ISC_R_SUCCESS) { i++; /* Increment here so that cleanup on error works. @@ -498,6 +516,12 @@ resume: goto cleanup; } + if (tlss[i] == NULL && lists != NULL && lists[l-1].tls != NULL) { + tlss[i] = isc_mem_get(mctx, sizeof(*tlss[i])); + dns_name_init(tlss[i]); + dns_name_dup(lists[l-1].tls, mctx, tlss[i]); + } + /* If the port is unset, take it from one of the upper levels */ if (isc_sockaddr_getport(&addrs[i]) == 0) { in_port_t addr_port = port; @@ -536,6 +560,7 @@ resume: port = stack[pushed].port; src4 = stack[pushed].src4; src6 = stack[pushed].src6; + l--; goto resume; } @@ -545,6 +570,23 @@ resume: shrink_array(mctx, sources, i, srccount); if (lists != NULL) { + for (size_t j = 0; j < listcount; j++) { + if (lists[j].key != NULL) { + if (dns_name_dynamic(lists[j].key)) { + dns_name_free(lists[j].key, mctx); + } + isc_mem_put(mctx, lists[j].key, + sizeof(*lists[j].key)); + } + + if (lists[j].tls != NULL) { + if (dns_name_dynamic(lists[j].tls)) { + dns_name_free(lists[j].tls, mctx); + } + isc_mem_put(mctx, lists[j].tls, + sizeof(*lists[j].tls)); + } + } isc_mem_cput(mctx, lists, listcount, sizeof(lists[0])); } if (stack != NULL) { @@ -596,6 +638,23 @@ cleanup: isc_mem_cput(mctx, sources, srccount, sizeof(sources[0])); } if (lists != NULL) { + for (size_t j = 0; j < listcount; j++) { + if (lists[j].key != NULL) { + if (dns_name_dynamic(lists[j].key)) { + dns_name_free(lists[j].key, mctx); + } + isc_mem_put(mctx, lists[j].key, + sizeof(*lists[j].key)); + } + + if (lists[j].tls != NULL) { + if (dns_name_dynamic(lists[j].tls)) { + dns_name_free(lists[j].tls, mctx); + } + isc_mem_put(mctx, lists[j].tls, + sizeof(*lists[j].tls)); + } + } isc_mem_cput(mctx, lists, listcount, sizeof(lists[0])); } if (stack != NULL) {