bind: backport patch replace automatic empty zones
authorPhilip Prindeville <redacted>
Wed, 10 Dec 2025 21:50:48 +0000 (14:50 -0700)
committerNoah Meyerhans <redacted>
Sun, 1 Feb 2026 14:01:50 +0000 (09:01 -0500)
The RFC-1918 zones are automatically synthesized locally by bind
to avoid forwarding queries about them to root nameservers.  As
a result, we can't easily replace them with rndc addzone on the
fly.  We need this for DHCP integration.

Signed-off-by: Philip Prindeville <redacted>
net/bind/Makefile
net/bind/patches/fix-usr-allow-rndc-addzone#1.patch [new file with mode: 0644]
net/bind/patches/fix-usr-allow-rndc-addzone#2.patch [new file with mode: 0644]
net/bind/patches/fix-usr-allow-rndc-addzone#3.patch [new file with mode: 0644]
net/bind/patches/fix-usr-allow-rndc-addzone#4.patch [new file with mode: 0644]

index c400bd81250ce0032ce7b4864e3f22dbd6cefb91..fa709878d1750f76b04c7da5534e268b923f8f18 100644 (file)
@@ -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 <frodo@morgul.net>
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 (file)
index 0000000..9d7f313
--- /dev/null
@@ -0,0 +1,97 @@
+From 6e1450ef0f9d66679587092cef2e83e6deb1575f Mon Sep 17 00:00:00 2001
+From: Mark Andrews <marka@isc.org>
+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 (file)
index 0000000..5a0805b
--- /dev/null
@@ -0,0 +1,123 @@
+From cb9cb3c8d9f1c8e5e6a0fb55fea8dba43ea5d529 Mon Sep 17 00:00:00 2001
+From: Mark Andrews <marka@isc.org>
+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 (file)
index 0000000..2a7d636
--- /dev/null
@@ -0,0 +1,42 @@
+From 6cea04633d2461456d30cbdd69695ca0da540b4f Mon Sep 17 00:00:00 2001
+From: Mark Andrews <marka@isc.org>
+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 (file)
index 0000000..1e49c12
--- /dev/null
@@ -0,0 +1,36 @@
+From be735c1b5e12117039ac64f802e30b075987dd22 Mon Sep 17 00:00:00 2001
+From: Matthijs Mekking <matthijs@isc.org>
+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
git clone https://git.99rst.org/PROJECT