diff --git a/net/bind/Makefile b/net/bind/Makefile index c400bd8125..fa709878d1 100644 --- a/net/bind/Makefile +++ b/net/bind/Makefile @@ -10,7 +10,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=bind PKG_VERSION:=9.20.18 -PKG_RELEASE:=1 +PKG_RELEASE:=2 USERID:=bind=57:bind=57 PKG_MAINTAINER:=Noah Meyerhans diff --git a/net/bind/patches/fix-usr-allow-rndc-addzone#1.patch b/net/bind/patches/fix-usr-allow-rndc-addzone#1.patch new file mode 100644 index 0000000000..9d7f313e50 --- /dev/null +++ b/net/bind/patches/fix-usr-allow-rndc-addzone#1.patch @@ -0,0 +1,97 @@ +From 6e1450ef0f9d66679587092cef2e83e6deb1575f Mon Sep 17 00:00:00 2001 +From: Mark Andrews +Date: Tue, 2 Dec 2025 11:02:34 +1100 +Subject: [PATCH 1/4] Allow rndc addzone to replace automatic empty zones + +Check if the found zone is an automatic zone and if so remove it +from the view prior to adding the new zone. If the addzone fails +restore the automatic zone to the view. +--- + bin/named/server.c | 34 +++++++++++++++++++++++++++++++++- + lib/dns/view.c | 4 +++- + 2 files changed, 36 insertions(+), 2 deletions(-) + +--- a/bin/named/server.c ++++ b/bin/named/server.c +@@ -13946,6 +13946,7 @@ do_addzone(named_server_t *server, ns_cf + bool redirect, isc_buffer_t **text) { + isc_result_t result, tresult; + dns_zone_t *zone = NULL; ++ dns_zone_t *oldzone = NULL; + #ifndef HAVE_LMDB + FILE *fp = NULL; + bool cleanup_config = false; +@@ -13964,7 +13965,13 @@ do_addzone(named_server_t *server, ns_cf + } else { + result = dns_view_findzone(view, name, DNS_ZTFIND_EXACT, &zone); + if (result == ISC_R_SUCCESS) { +- result = ISC_R_EXISTS; ++ if (dns_zone_getautomatic(zone)) { ++ oldzone = zone; ++ zone = NULL; ++ result = ISC_R_NOTFOUND; ++ } else { ++ result = ISC_R_EXISTS; ++ } + } + } + if (result != ISC_R_NOTFOUND) { +@@ -13973,6 +13980,10 @@ do_addzone(named_server_t *server, ns_cf + + isc_loopmgr_pause(named_g_loopmgr); + ++ if (oldzone != NULL) { ++ dns_view_delzone(view, oldzone); ++ } ++ + #ifndef HAVE_LMDB + /* + * Make sure we can open the configuration save file +@@ -14077,6 +14088,11 @@ do_addzone(named_server_t *server, ns_cf + /* Remove the zone from the zone table */ + dns_view_delzone(view, zone); + goto cleanup; ++ } else if (oldzone != NULL) { ++ /* ++ * We no longer need to keep the old zone around. ++ */ ++ dns_zone_detach(&oldzone); + } + + /* Flag the zone as having been added at runtime */ +@@ -14093,6 +14109,22 @@ do_addzone(named_server_t *server, ns_cf + + cleanup: + ++ if (oldzone != NULL) { ++ /* ++ * Restore the old zone. ++ */ ++ dns_view_thaw(view); ++ tresult = dns_view_addzone(view, oldzone); ++ dns_view_freeze(view); ++ dns_zone_detach(&oldzone); ++ ++ if (tresult != ISC_R_SUCCESS && tresult != ISC_R_SHUTTINGDOWN) { ++ TCHECK(putstr(text, "\nUnable to restore automatic " ++ "empty zone: ")); ++ TCHECK(putstr(text, isc_result_totext(result))); ++ } ++ } ++ + #ifndef HAVE_LMDB + if (fp != NULL) { + (void)isc_stdio_close(fp); +--- a/lib/dns/view.c ++++ b/lib/dns/view.c +@@ -778,7 +778,9 @@ dns_view_delzone(dns_view_t *view, dns_z + + REQUIRE(DNS_VIEW_VALID(view)); + +- dns_zone_prepare_shutdown(zone); ++ if (!dns_zone_getautomatic(zone)) { ++ dns_zone_prepare_shutdown(zone); ++ } + + rcu_read_lock(); + zonetable = rcu_dereference(view->zonetable); diff --git a/net/bind/patches/fix-usr-allow-rndc-addzone#2.patch b/net/bind/patches/fix-usr-allow-rndc-addzone#2.patch new file mode 100644 index 0000000000..5a0805b9f2 --- /dev/null +++ b/net/bind/patches/fix-usr-allow-rndc-addzone#2.patch @@ -0,0 +1,123 @@ +From cb9cb3c8d9f1c8e5e6a0fb55fea8dba43ea5d529 Mon Sep 17 00:00:00 2001 +From: Mark Andrews +Date: Tue, 2 Dec 2025 11:05:51 +1100 +Subject: [PATCH 2/4] Check if adding new zone can replace an automatic empty + zone + +--- + bin/tests/system/addzone/ns6/added.db | 25 ++++++++++++++ + bin/tests/system/addzone/ns6/named.conf.j2 | 40 ++++++++++++++++++++++ + bin/tests/system/addzone/tests.sh | 29 ++++++++++++++++ + 3 files changed, 94 insertions(+) + create mode 100644 bin/tests/system/addzone/ns6/added.db + create mode 100644 bin/tests/system/addzone/ns6/named.conf.j2 + +--- /dev/null ++++ b/bin/tests/system/addzone/ns6/added.db +@@ -0,0 +1,25 @@ ++; Copyright (C) Internet Systems Consortium, Inc. ("ISC") ++; ++; SPDX-License-Identifier: MPL-2.0 ++; ++; This Source Code Form is subject to the terms of the Mozilla Public ++; License, v. 2.0. If a copy of the MPL was not distributed with this ++; file, you can obtain one at https://mozilla.org/MPL/2.0/. ++; ++; See the COPYRIGHT file distributed with this work for additional ++; information regarding copyright ownership. ++ ++$TTL 300 ; 5 minutes ++@ IN SOA mname1. . ( ++ 1 ; serial ++ 20 ; refresh (20 seconds) ++ 20 ; retry (20 seconds) ++ 1814400 ; expire (3 weeks) ++ 3600 ; minimum (1 hour) ++ ) ++ NS ns2 ++ns2 A 10.53.0.2 ++ MX 10 mail ++ ++a A 10.0.0.1 ++mail A 10.0.0.2 +--- /dev/null ++++ b/bin/tests/system/addzone/ns6/named.conf.j2 +@@ -0,0 +1,40 @@ ++/* ++ * Copyright (C) Internet Systems Consortium, Inc. ("ISC") ++ * ++ * SPDX-License-Identifier: MPL-2.0 ++ * ++ * This Source Code Form is subject to the terms of the Mozilla Public ++ * License, v. 2.0. If a copy of the MPL was not distributed with this ++ * file, you can obtain one at https://mozilla.org/MPL/2.0/. ++ * ++ * See the COPYRIGHT file distributed with this work for additional ++ * information regarding copyright ownership. ++ */ ++ ++options { ++ port @PORT@; ++ pid-file "named.pid"; ++ listen-on { 10.53.0.6; }; ++ listen-on-v6 { none; }; ++ allow-query { any; }; ++ recursion yes; ++ allow-new-zones yes; ++ dnssec-validation no; ++}; ++ ++include "../../_common/rndc.key"; ++ ++controls { ++ inet 10.53.0.6 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; ++}; ++ ++template primary { ++ type primary; ++ file "$view-$name.db"; ++ initial-file "added.db"; ++}; ++ ++zone "." { ++ type hint; ++ file "../../_common/root.hint"; ++}; +--- a/bin/tests/system/addzone/tests.sh ++++ b/bin/tests/system/addzone/tests.sh +@@ -68,6 +68,35 @@ n=$((n + 1)) + if [ $ret != 0 ]; then echo_i "failed"; fi + status=$((status + ret)) + ++echo_i "adding new zone which replaces an automatic empty zone ($n)" ++ret=0 ++$DIG $DIGOPTS @10.53.0.6 168.192.in-addr.arpa SOA >dig.out.pre.$n || ret=1 ++grep 'status: NOERROR' dig.out.pre.$n >/dev/null || ret=1 ++grep '168\.192\.in-addr\.arpa\..86400.IN.SOA.168\.192\.IN-ADDR\.ARPA\. \. 0 28800 7200 604800 86400' dig.out.pre.$n >/dev/null || ret=1 ++$RNDCCMD 10.53.0.6 addzone '168.192.in-addr.arpa { type primary; file "added.db"; };' 2>&1 | sed 's/^/I:ns6 /' ++_check_adding_new_zone() ( ++ $DIG $DIGOPTS @10.53.0.6 a.168.192.in-addr.arpa a >dig.out.ns6.$n \ ++ && grep 'status: NOERROR' dig.out.ns6.$n >/dev/null \ ++ && grep '^a.168.192.in-addr.arpa' dig.out.ns6.$n >/dev/null ++) ++retry_quiet 10 _check_adding_new_zone || ret=1 ++n=$((n + 1)) ++if [ $ret != 0 ]; then echo_i "failed"; fi ++status=$((status + ret)) ++ ++echo_i "adding new zone which replaces an automatic empty zone with bad file ($n)" ++ret=0 ++$DIG $DIGOPTS @10.53.0.6 10.in-addr.arpa SOA >dig.out.pre.$n || ret=1 ++grep 'status: NOERROR' dig.out.pre.$n >/dev/null || ret=1 ++grep '10\.in-addr\.arpa\..86400.IN.SOA.10\.IN-ADDR\.ARPA\. \. 0 28800 7200 604800 86400' dig.out.pre.$n >/dev/null || ret=1 ++$RNDCCMD 10.53.0.6 addzone '10.in-addr.arpa { type primary; file "bad.db"; };' 2>&1 | sed 's/^/I:ns6 /' ++$DIG $DIGOPTS @10.53.0.6 10.in-addr.arpa SOA >dig.out.post.$n || ret=1 ++grep 'status: NOERROR' dig.out.post.$n >/dev/null || ret=1 ++grep '10\.in-addr\.arpa\..86400.IN.SOA.10\.IN-ADDR\.ARPA\. \. 0 28800 7200 604800 86400' dig.out.post.$n >/dev/null || ret=1 ++n=$((n + 1)) ++if [ $ret != 0 ]; then echo_i "failed"; fi ++status=$((status + ret)) ++ + nextpart ns2/named.run >/dev/null + echo_i "checking addzone errors are logged correctly" + ret=0 diff --git a/net/bind/patches/fix-usr-allow-rndc-addzone#3.patch b/net/bind/patches/fix-usr-allow-rndc-addzone#3.patch new file mode 100644 index 0000000000..2a7d63658b --- /dev/null +++ b/net/bind/patches/fix-usr-allow-rndc-addzone#3.patch @@ -0,0 +1,42 @@ +From 6cea04633d2461456d30cbdd69695ca0da540b4f Mon Sep 17 00:00:00 2001 +From: Mark Andrews +Date: Tue, 9 Dec 2025 15:51:34 +1100 +Subject: [PATCH 3/4] Document rndc addzone with automatic empty zones + +--- + bin/rndc/rndc.rst | 27 ++++++++++++++------------- + 1 file changed, 14 insertions(+), 13 deletions(-) + +--- a/bin/rndc/rndc.rst ++++ b/bin/rndc/rndc.rst +@@ -129,18 +129,19 @@ Currently supported commands are: + .. option:: addzone zone [class [view]] configuration + + This command adds a zone while the server is running. This command +- requires the ``allow-new-zones`` option to be set to ``yes``. The +- configuration string specified on the command line is the zone +- configuration text that would ordinarily be placed in :iscman:`named.conf`. ++ requires the ``allow-new-zones`` option to be set to ``yes``. ++ The configuration string specified on the command line is the ++ zone configuration text that would ordinarily be placed in ++ :iscman:`named.conf`. Automatic empty zones will be replaced. + +- The configuration is saved in a file called ``viewname.nzf`` (or, if +- :iscman:`named` is compiled with liblmdb, an LMDB database file called +- ``viewname.nzd``). ``viewname`` is the name of the view, unless the view +- name contains characters that are incompatible with use as a file +- name, in which case a cryptographic hash of the view name is used +- instead. When :iscman:`named` is restarted, the file is loaded into +- the view configuration so that zones that were added can persist +- after a restart. ++ The configuration is saved in a file called ``viewname.nzf`` ++ (or, if :iscman:`named` is compiled with liblmdb, an LMDB database ++ file called ``viewname.nzd``). ``viewname`` is the name of the ++ view, unless the view name contains characters that are incompatible ++ with use as a file name, in which case a cryptographic hash of ++ the view name is used instead. When :iscman:`named` is restarted, ++ the file is loaded into the view configuration so that zones ++ that were added can persist after a restart. + + This sample ``addzone`` command adds the zone ``example.com`` to + the default view: diff --git a/net/bind/patches/fix-usr-allow-rndc-addzone#4.patch b/net/bind/patches/fix-usr-allow-rndc-addzone#4.patch new file mode 100644 index 0000000000..1e49c12d56 --- /dev/null +++ b/net/bind/patches/fix-usr-allow-rndc-addzone#4.patch @@ -0,0 +1,36 @@ +From be735c1b5e12117039ac64f802e30b075987dd22 Mon Sep 17 00:00:00 2001 +From: Matthijs Mekking +Date: Thu, 11 Dec 2025 15:14:55 +0100 +Subject: [PATCH 4/4] fixup! Check if adding new zone can replace an automatic + empty zone + +--- + bin/tests/system/addzone/tests.sh | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +--- a/bin/tests/system/addzone/tests.sh ++++ b/bin/tests/system/addzone/tests.sh +@@ -84,6 +84,23 @@ n=$((n + 1)) + if [ $ret != 0 ]; then echo_i "failed"; fi + status=$((status + ret)) + ++echo_i "deleting zone which replaced an automatic empty zone ($n)" ++ret=0 ++$DIG $DIGOPTS @10.53.0.6 a.168.192.in-addr.arpa a >dig.out.pre.$n || ret=1 ++grep 'status: NOERROR' dig.out.pre.$n >/dev/null || ret=1 ++grep '^a.168.192.in-addr.arpa' dig.out.pre.$n >/dev/null || ret=1 ++$RNDCCMD 10.53.0.6 delzone '168.192.in-addr.arpa' 2>&1 | sed 's/^/I:ns6 /' ++_check_removing_new_zone() ( ++ DIGOPTS2="+tcp +nosea +nostat +nocmd +norec +noauth +noadd +nostats +dnssec -p ${PORT}" ++ $DIG $DIGOPTS2 @10.53.0.6 168.192.in-addr.arpa SOA >dig.out.ns6.$n \ ++ && grep 'status: NOERROR' dig.out.ns6.$n >/dev/null \ ++ && grep '168\.192\.in-addr\.arpa\..86400.IN.SOA.168\.192\.IN-ADDR\.ARPA\. \. 0 28800 7200 604800 86400' dig.out.ns6.$n >/dev/null ++) ++retry_quiet 10 _check_removing_new_zone || ret=1 ++n=$((n + 1)) ++if [ $ret != 0 ]; then echo_i "failed"; fi ++status=$((status + ret)) ++ + echo_i "adding new zone which replaces an automatic empty zone with bad file ($n)" + ret=0 + $DIG $DIGOPTS @10.53.0.6 10.in-addr.arpa SOA >dig.out.pre.$n || ret=1