]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Implement catalog zones options new syntax based on custom properties
authorAram Sargsyan <aram@isc.org>
Wed, 16 Mar 2022 20:11:17 +0000 (20:11 +0000)
committerAram Sargsyan <aram@isc.org>
Thu, 14 Apr 2022 10:53:52 +0000 (10:53 +0000)
According to DNS catalog zones draft version 5 document, catalog
zone custom properties must be placed under the "ext" label.

Make necessary changes to support the new custom properties syntax in
catalog zones with version "2" of the schema.

Change the default catalog zones schema version from "1" to "2" in
ARM to prepare for the new features and changes which come starting
from this commit in order to support the latest DNS catalog zones draft
document.

Make some restructuring in ARM and rename the term catalog zone "option"
to "custom property" to better reflect the terms used in the draft.

Change the version of 'catalog1.zone.' catalog zone in the "catz" system
test to "2", and leave the version of 'catalog2.zone.' catalog zone at
version "1" to test both versions.

Add tests to check that the new syntax works only with the new schema
version, and that the old syntax works only with the legacy schema
version catalog zones.

bin/tests/system/catz/.gitignore
bin/tests/system/catz/clean.sh
bin/tests/system/catz/ns1/catalog.example.db.in
bin/tests/system/catz/ns3/catalog.example.db.in [new file with mode: 0644]
bin/tests/system/catz/setup.sh
bin/tests/system/catz/tests.sh
doc/arm/catz.rst
lib/dns/catz.c

index 85e2e073842d81328d56cede7d11f51f19652801..b5ba95a12a44def220de7881f6dd8e19ad858b7d 100644 (file)
@@ -12,6 +12,8 @@
 /ns1/*dom*.example.db
 /ns3/dom13.example.db
 /ns3/dom14.example.db
+/ns3/dom17.example.db
+/ns3/dom18.example.db
 
 /ns2/zonedir
 
index c3600d305bdf35f51c01dc819528f7571412762f..375587cc00845f458f62dd04906c7a8f813983c0 100644 (file)
@@ -20,7 +20,7 @@ rm -f ns*/named.run.prev
 rm -f ns1/*dom*example.db
 rm -f ns2/__catz__*db
 rm -f ns2/named.conf.tmp
-rm -f ns3/dom13.example.db ns3/dom14.example.db
+rm -f ns3/dom13.example.db ns3/dom14.example.db ns3/dom17.example.db ns3/dom18.example.db
 rm -f nsupdate.out.*
 rm -f ns[123]/catalog[1234].example.db
 rm -rf ns2/zonedir
index a0bab0dfe284a2d8b8722f452b94a8cd0a6f6df0..6b529479223eceaa02ec7aa8546d2461cda5252a 100644 (file)
@@ -11,4 +11,4 @@
 
 @ 3600 SOA . . 1 86400 3600 86400 3600
 @ 3600 IN NS invalid.
-version IN TXT "1"
+version IN TXT "2"
diff --git a/bin/tests/system/catz/ns3/catalog.example.db.in b/bin/tests/system/catz/ns3/catalog.example.db.in
new file mode 100644 (file)
index 0000000..a0bab0d
--- /dev/null
@@ -0,0 +1,14 @@
+; 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.
+
+@ 3600 SOA . . 1 86400 3600 86400 3600
+@ 3600 IN NS invalid.
+version IN TXT "1"
index 5e99898880bd6772df17e58a33d22d9251be444e..9f924992287166bf29592cdb27cb02d7549edc45 100644 (file)
@@ -20,7 +20,7 @@ copy_setports ns2/named1.conf.in ns2/named.conf
 copy_setports ns3/named.conf.in ns3/named.conf
 
 cp -f ns1/catalog.example.db.in ns1/catalog1.example.db
-cp -f ns1/catalog.example.db.in ns3/catalog2.example.db
+cp -f ns3/catalog.example.db.in ns3/catalog2.example.db
 cp -f ns1/catalog.example.db.in ns1/catalog3.example.db
 cp -f ns1/catalog.example.db.in ns1/catalog4.example.db
 
index 469acdcdb9a8f94a4a5eddae781da2a09574b3ff..ae17b72e42e597b4fc92158666a50782a779ed6e 100644 (file)
@@ -434,7 +434,7 @@ ret=0
 $NSUPDATE -d <<END >> nsupdate.out.test$n 2>&1 || ret=1
     server 10.53.0.1 ${PORT}
     update add somerandomlabel.zones.catalog1.example. 3600 IN PTR dom5.example.
-    update add primaries.somerandomlabel.zones.catalog1.example. 3600 IN A 10.53.0.3
+    update add primaries.ext.somerandomlabel.zones.catalog1.example. 3600 IN A 10.53.0.3
     send
 END
 if [ $ret -ne 0 ]; then echo_i "failed"; fi
@@ -489,8 +489,8 @@ echo_i "adding dom6.example. and a valid global primaries option (IP without TSI
 ret=0
 $NSUPDATE -d <<END >> nsupdate.out.test$n 2>&1 || ret=1
     server 10.53.0.1 ${PORT}
-    update add primaries.catalog1.example. 3600 IN A 10.53.0.3
-    update add primaries.catalog1.example. 3600 IN AAAA fd92:7065:b8e:ffff::3
+    update add primaries.ext.catalog1.example. 3600 IN A 10.53.0.3
+    update add primaries.ext.catalog1.example. 3600 IN AAAA fd92:7065:b8e:ffff::3
     update add 4346f565b4d63ddb99e5d2497ff22d04e878e8f8.zones.catalog1.example. 3600 IN PTR dom6.example.
     send
 END
@@ -517,8 +517,8 @@ echo_i "removing dom6.example. ($n)"
 ret=0
 $NSUPDATE -d <<END >> nsupdate.out.test$n 2>&1 || ret=1
     server 10.53.0.1 ${PORT}
-    update delete primaries.catalog1.example. 3600 IN A 10.53.0.3
-    update delete primaries.catalog1.example. 3600 IN AAAA  fd92:7065:b8e:ffff::3
+    update delete primaries.ext.catalog1.example. 3600 IN A 10.53.0.3
+    update delete primaries.ext.catalog1.example. 3600 IN AAAA  fd92:7065:b8e:ffff::3
     update delete 4346f565b4d63ddb99e5d2497ff22d04e878e8f8.zones.catalog1.example. 3600 IN PTR dom6.example.
     send
 END
@@ -546,7 +546,7 @@ echo_i "adding dom6.example. and an invalid global primaries option (TSIG withou
 ret=0
 $NSUPDATE -d <<END >> nsupdate.out.test$n 2>&1 || ret=1
     server 10.53.0.1 ${PORT}
-    update add label1.primaries.catalog1.example. 3600 IN TXT "tsig_key"
+    update add label1.primaries.ext.catalog1.example. 3600 IN TXT "tsig_key"
     update add 4346f565b4d63ddb99e5d2497ff22d04e878e8f8.zones.catalog1.example. 3600 IN PTR dom6.example.
     send
 END
@@ -566,7 +566,7 @@ echo_i "removing dom6.example. ($n)"
 ret=0
 $NSUPDATE -d <<END >> nsupdate.out.test$n 2>&1 || ret=1
     server 10.53.0.1 ${PORT}
-    update delete label1.primaries.catalog1.example. 3600 IN TXT "tsig_key"
+    update delete label1.primaries.ext.catalog1.example. 3600 IN TXT "tsig_key"
     update delete 4346f565b4d63ddb99e5d2497ff22d04e878e8f8.zones.catalog1.example. 3600 IN PTR dom6.example.
     send
 END
@@ -619,7 +619,7 @@ ret=0
 $NSUPDATE -d <<END >> nsupdate.out.test$n 2>&1 || ret=1
     server 10.53.0.1 ${PORT}
     update add 78833ec3c0059fd4540fee81c7eaddce088e7cd7.zones.catalog1.example. 3600 IN PTR dom7.example.
-    update add allow-query.78833ec3c0059fd4540fee81c7eaddce088e7cd7.zones.catalog1.example. 3600 IN APL 1:10.53.0.1/32 !1:10.53.0.0/30 1:0.0.0.0/0
+    update add allow-query.ext.78833ec3c0059fd4540fee81c7eaddce088e7cd7.zones.catalog1.example. 3600 IN APL 1:10.53.0.1/32 !1:10.53.0.0/30 1:0.0.0.0/0
     send
 END
 if [ $ret -ne 0 ]; then echo_i "failed"; fi
@@ -661,8 +661,8 @@ ret=0
 $NSUPDATE -d <<END >> nsupdate.out.test$n 2>&1 || ret=1
     server 10.53.0.1 ${PORT}
     update add cba95222e308baba42417be6021026fdf20827b6.zones.catalog1.example. 3600 IN PTR dom8.example
-    update add allow-query.catalog1.example. 3600 IN APL 1:10.53.0.1/32
-    update add allow-transfer.catalog1.example. 3600 IN APL 1:10.53.0.2/32
+    update add allow-query.ext.catalog1.example. 3600 IN APL 1:10.53.0.1/32
+    update add allow-transfer.ext.catalog1.example. 3600 IN APL 1:10.53.0.2/32
     send
 END
 if [ $ret -ne 0 ]; then echo_i "failed"; fi
@@ -712,8 +712,8 @@ echo_i "deleting global allow-query and allow-domain ACLs ($n)"
 ret=0
 $NSUPDATE -d <<END >> nsupdate.out.test$n 2>&1 || ret=1
     server 10.53.0.1 ${PORT}
-    update delete allow-query.catalog1.example. 3600 IN APL 1:10.53.0.1/32
-    update delete allow-transfer.catalog1.example. 3600 IN APL 1:10.53.0.2/32
+    update delete allow-query.ext.catalog1.example. 3600 IN APL 1:10.53.0.1/32
+    update delete allow-transfer.ext.catalog1.example. 3600 IN APL 1:10.53.0.2/32
     send
 END
 if [ $ret -ne 0 ]; then echo_i "failed"; fi
@@ -780,8 +780,8 @@ ret=0
 $NSUPDATE -d <<END >> nsupdate.out.test$n 2>&1 || ret=1
     server 10.53.0.1 ${PORT}
     update add f0f989bc71c5c8ca3a1eb9c9ab5246521907e3af.zones.catalog1.example. 3600 IN PTR dom9.example.
-    update add label1.primaries.f0f989bc71c5c8ca3a1eb9c9ab5246521907e3af.zones.catalog1.example. 3600 IN A 10.53.0.1
-    update add label1.primaries.f0f989bc71c5c8ca3a1eb9c9ab5246521907e3af.zones.catalog1.example. 3600 IN TXT "tsig_key"
+    update add label1.primaries.ext.f0f989bc71c5c8ca3a1eb9c9ab5246521907e3af.zones.catalog1.example. 3600 IN A 10.53.0.1
+    update add label1.primaries.ext.f0f989bc71c5c8ca3a1eb9c9ab5246521907e3af.zones.catalog1.example. 3600 IN TXT "tsig_key"
     send
 END
 if [ $ret -ne 0 ]; then echo_i "failed"; fi
@@ -808,8 +808,8 @@ ret=0
 $NSUPDATE -d <<END >> nsupdate.out.test$n 2>&1 || ret=1
     server 10.53.0.1 ${PORT}
     update delete f0f989bc71c5c8ca3a1eb9c9ab5246521907e3af.zones.catalog1.example. 3600 IN PTR dom9.example.
-    update delete label1.primaries.f0f989bc71c5c8ca3a1eb9c9ab5246521907e3af.zones.catalog1.example. 3600 IN A 10.53.0.1
-    update delete label1.primaries.f0f989bc71c5c8ca3a1eb9c9ab5246521907e3af.zones.catalog1.example. 3600 IN TXT "tsig_key"
+    update delete label1.primaries.ext.f0f989bc71c5c8ca3a1eb9c9ab5246521907e3af.zones.catalog1.example. 3600 IN A 10.53.0.1
+    update delete label1.primaries.ext.f0f989bc71c5c8ca3a1eb9c9ab5246521907e3af.zones.catalog1.example. 3600 IN TXT "tsig_key"
     send
 END
 if [ $ret -ne 0 ]; then echo_i "failed"; fi
@@ -837,7 +837,7 @@ ret=0
 $NSUPDATE -d <<END >> nsupdate.out.test$n 2>&1 || ret=1
     server 10.53.0.1 ${PORT}
     update add f0f989bc71c5c8ca3a1eb9c9ab5246521907e3af.zones.catalog1.example. 3600 IN PTR dom9.example.
-    update add label1.primaries.f0f989bc71c5c8ca3a1eb9c9ab5246521907e3af.zones.catalog1.example. 3600 IN TXT "tsig_key"
+    update add label1.primaries.ext.f0f989bc71c5c8ca3a1eb9c9ab5246521907e3af.zones.catalog1.example. 3600 IN TXT "tsig_key"
     send
 END
 if [ $ret -ne 0 ]; then echo_i "failed"; fi
@@ -857,7 +857,7 @@ ret=0
 $NSUPDATE -d <<END >> nsupdate.out.test$n 2>&1 || ret=1
     server 10.53.0.1 ${PORT}
     update delete f0f989bc71c5c8ca3a1eb9c9ab5246521907e3af.zones.catalog1.example. 3600 IN PTR dom9.example.
-    update delete label1.primaries.f0f989bc71c5c8ca3a1eb9c9ab5246521907e3af.zones.catalog1.example. 3600 IN TXT "tsig_key"
+    update delete label1.primaries.ext.f0f989bc71c5c8ca3a1eb9c9ab5246521907e3af.zones.catalog1.example. 3600 IN TXT "tsig_key"
     send
 END
 if [ $ret -ne 0 ]; then echo_i "failed"; fi
@@ -1319,7 +1319,7 @@ ret=0
 $NSUPDATE -d <<END >> nsupdate.out.test$n 2>&1 || ret=1
     server 10.53.0.1 ${PORT}
     update add 8d7989c746b3f92b3bba2479e72afd977198363f.zones.catalog1.example. 3600 IN PTR dom13.example.
-    update add primaries.8d7989c746b3f92b3bba2479e72afd977198363f.zones.catalog1.example. 3600 IN A 10.53.0.1
+    update add primaries.ext.8d7989c746b3f92b3bba2479e72afd977198363f.zones.catalog1.example. 3600 IN A 10.53.0.1
     send
 END
 if [ $ret -ne 0 ]; then echo_i "failed"; fi
@@ -1405,7 +1405,7 @@ ret=0
 $NSUPDATE -d <<END >> nsupdate.out.test$n 2>&1 || ret=1
     server 10.53.0.1 ${PORT}
     update delete 8d7989c746b3f92b3bba2479e72afd977198363f.zones.catalog1.example. 3600 IN PTR dom13.example.
-    update delete primaries.8d7989c746b3f92b3bba2479e72afd977198363f.zones.catalog1.example. 3600 IN A 10.53.0.2
+    update delete primaries.ext.8d7989c746b3f92b3bba2479e72afd977198363f.zones.catalog1.example. 3600 IN A 10.53.0.2
     send
 END
 if [ $ret -ne 0 ]; then echo_i "failed"; fi
@@ -1755,6 +1755,279 @@ wait_for_no_soa @10.53.0.2 dom16.example. dig.out.test$n || ret=1
 if [ $ret -ne 0 ]; then echo_i "failed"; fi
 status=$((status+ret))
 
+##########################################################################
+echo_i "Testing custom properties version '1' and version '2' syntaxes"
+n=$((n+1))
+echo_i "checking that dom17.example. is not served by primary ($n)"
+ret=0
+wait_for_no_soa @10.53.0.1 dom17.example. dig.out.test$n || ret=1
+if [ $ret -ne 0 ]; then echo_i "failed"; fi
+status=$((status+ret))
+
+n=$((n+1))
+echo_i "checking that dom18.example. is not served by primary ($n)"
+ret=0
+wait_for_no_soa @10.53.0.1 dom18.example. dig.out.test$n || ret=1
+if [ $ret -ne 0 ]; then echo_i "failed"; fi
+status=$((status+ret))
+
+n=$((n+1))
+echo_i "adding domains dom17.example. and dom18.example. to primary ns1 via RNDC ($n)"
+ret=0
+echo "@ 3600 IN SOA . . 1 3600 3600 3600 3600" > ns1/dom17.example.db
+echo "@ IN NS invalid." >> ns1/dom17.example.db
+echo "@ IN A 192.0.2.1" >> ns1/dom17.example.db
+rndccmd 10.53.0.1 addzone dom17.example. '{type primary; file "dom17.example.db";};' || ret=1
+if [ $ret -ne 0 ]; then echo_i "failed"; fi
+status=$((status+ret))
+echo "@ 3600 IN SOA . . 1 3600 3600 3600 3600" > ns1/dom18.example.db
+echo "@ IN NS invalid." >> ns1/dom18.example.db
+echo "@ IN A 192.0.2.1" >> ns1/dom18.example.db
+rndccmd 10.53.0.1 addzone dom18.example. '{type primary; file "dom18.example.db";};' || ret=1
+if [ $ret -ne 0 ]; then echo_i "failed"; fi
+status=$((status+ret))
+
+n=$((n+1))
+echo_i "checking that dom17.example. is now served by primary ns1 ($n)"
+ret=0
+wait_for_soa @10.53.0.1 dom17.example. dig.out.test$n || ret=1
+if [ $ret -ne 0 ]; then echo_i "failed"; fi
+status=$((status+ret))
+
+n=$((n+1))
+echo_i "checking that dom18.example. is now served by primary ns1 ($n)"
+ret=0
+wait_for_soa @10.53.0.1 dom18.example. dig.out.test$n || ret=1
+if [ $ret -ne 0 ]; then echo_i "failed"; fi
+status=$((status+ret))
+
+n=$((n+1))
+echo_i "checking that dom17.example. is not served by primary ns3 ($n)"
+ret=0
+wait_for_no_soa @10.53.0.3 dom17.example. dig.out.test$n || ret=1
+if [ $ret -ne 0 ]; then echo_i "failed"; fi
+status=$((status+ret))
+
+n=$((n+1))
+echo_i "checking that dom18.example. is not served by primary ns3 ($n)"
+ret=0
+wait_for_no_soa @10.53.0.3 dom18.example. dig.out.test$n || ret=1
+if [ $ret -ne 0 ]; then echo_i "failed"; fi
+status=$((status+ret))
+
+n=$((n+1))
+echo_i "adding domains dom17.example. and dom18.example. to primary ns3 via RNDC ($n)"
+ret=0
+echo "@ 3600 IN SOA . . 1 3600 3600 3600 3600" > ns3/dom17.example.db
+echo "@ IN NS invalid." >> ns3/dom17.example.db
+echo "@ IN A 192.0.2.2" >> ns3/dom17.example.db
+rndccmd 10.53.0.3 addzone dom17.example. '{type primary; file "dom17.example.db";};' || ret=1
+if [ $ret -ne 0 ]; then echo_i "failed"; fi
+status=$((status+ret))
+echo "@ 3600 IN SOA . . 1 3600 3600 3600 3600" > ns3/dom18.example.db
+echo "@ IN NS invalid." >> ns3/dom18.example.db
+echo "@ IN A 192.0.2.2" >> ns3/dom18.example.db
+rndccmd 10.53.0.3 addzone dom18.example. '{type primary; file "dom18.example.db";};' || ret=1
+if [ $ret -ne 0 ]; then echo_i "failed"; fi
+status=$((status+ret))
+
+n=$((n+1))
+echo_i "checking that dom17.example. is now served by primary ns3 ($n)"
+ret=0
+wait_for_soa @10.53.0.3 dom17.example. dig.out.test$n || ret=1
+if [ $ret -ne 0 ]; then echo_i "failed"; fi
+status=$((status+ret))
+
+n=$((n+1))
+echo_i "checking that dom18.example. is now served by primary ns3 ($n)"
+ret=0
+wait_for_soa @10.53.0.3 dom17.example. dig.out.test$n || ret=1
+if [ $ret -ne 0 ]; then echo_i "failed"; fi
+status=$((status+ret))
+
+nextpart ns2/named.run >/dev/null
+
+n=$((n+1))
+echo_i "adding domains dom17.example. and dom18.example. to catalog1 zone with ns3 as custom primary using different custom properties syntax ($n)"
+ret=0
+$NSUPDATE -d <<END >> nsupdate.out.test$n 2>&1 || ret=1
+    server 10.53.0.1 ${PORT}
+    update add dom17.zones.catalog1.example. 3600 IN PTR dom17.example.
+    update add dom18.zones.catalog1.example. 3600 IN PTR dom18.example.
+    update add primaries.dom17.zones.catalog1.example. 3600 IN A 10.53.0.3
+    update add primaries.ext.dom18.zones.catalog1.example. 3600 IN A 10.53.0.3
+    send
+END
+if [ $ret -ne 0 ]; then echo_i "failed"; fi
+status=$((status+ret))
+
+n=$((n+1))
+echo_i "waiting for secondary to sync up ($n)"
+ret=0
+wait_for_message ns2/named.run "catz: unknown record in catalog zone - primaries.dom17.zones.catalog1.example IN A(failure) - ignoring" &&
+wait_for_message ns2/named.run "catz: adding zone 'dom17.example' from catalog 'catalog1.example'" &&
+wait_for_message ns2/named.run "catz: adding zone 'dom18.example' from catalog 'catalog1.example'" &&
+wait_for_message ns2/named.run "transfer of 'dom17.example/IN' from 10.53.0.1#${PORT}: Transfer status: success" &&
+wait_for_message ns2/named.run "transfer of 'dom18.example/IN' from 10.53.0.3#${PORT}: Transfer status: success" || ret=1
+if [ $ret -ne 0 ]; then echo_i "failed"; fi
+status=$((status+ret))
+
+# The "primaries" custom property for dom17.example. was added using the legacy
+# syntax into a version 2 catalog1 zone, so we expect that it was ignored, no
+# override of the default setting happened, and dom17.example. was transferred
+# from the ns1 primary (the default).
+n=$((n+1))
+echo_i "checking that dom17.example. is served by secondary and that it's the one from ns1 ($n)"
+ret=0
+wait_for_a @10.53.0.2 dom17.example. dig.out.test$n || ret=1
+grep "192.0.2.1" dig.out.test$n > /dev/null || ret=1
+if [ $ret -ne 0 ]; then echo_i "failed"; fi
+status=$((status+ret))
+
+# The "primaries" custom property for dom18.example. was added using a supported
+# syntax into a version 2 catalog1 zone, so we expect that it was processed,
+# will override the default setting, and dom18.example. was transferred
+# from the ns3 primary.
+n=$((n+1))
+echo_i "checking that dom18.example. is served by secondary and that it's the one from ns3 ($n)"
+ret=0
+wait_for_a @10.53.0.2 dom18.example. dig.out.test$n || ret=1
+grep "192.0.2.2" dig.out.test$n > /dev/null || ret=1
+if [ $ret -ne 0 ]; then echo_i "failed"; fi
+status=$((status+ret))
+
+nextpart ns2/named.run >/dev/null
+
+n=$((n+1))
+echo_i "deleting domain dom17.example. and dom18.example. from catalog1 ($n)"
+ret=0
+$NSUPDATE -d <<END >> nsupdate.out.test$n 2>&1 || ret=1
+    server 10.53.0.1 ${PORT}
+    update delete dom17.zones.catalog1.example. 3600 IN PTR dom17.example.
+    update delete dom18.zones.catalog1.example. 3600 IN PTR dom18.example.
+    update delete primaries.dom17.zones.catalog1.example. 3600 IN A 10.53.0.3
+    update delete primaries.ext.dom18.zones.catalog1.example. 3600 IN A 10.53.0.3
+    send
+END
+if [ $ret -ne 0 ]; then echo_i "failed"; fi
+status=$((status+ret))
+
+n=$((n+1))
+echo_i "waiting for secondary to sync up ($n)"
+ret=0
+wait_for_message ns2/named.run  "catz: deleting zone 'dom17.example' from catalog 'catalog1.example' - success" &&
+wait_for_message ns2/named.run  "catz: deleting zone 'dom18.example' from catalog 'catalog1.example' - success" &&
+wait_for_message ns2/named.run  "zone_shutdown: zone dom17.example/IN: shutting down" &&
+wait_for_message ns2/named.run  "zone_shutdown: zone dom18.example/IN: shutting down" || ret=1
+if [ $ret -ne 0 ]; then echo_i "failed"; fi
+status=$((status+ret))
+
+n=$((n+1))
+echo_i "checking that dom17.example. is not served by secondary ($n)"
+ret=0
+wait_for_no_soa @10.53.0.2 dom17.example. dig.out.test$n || ret=1
+if [ $ret -ne 0 ]; then echo_i "failed"; fi
+status=$((status+ret))
+
+n=$((n+1))
+echo_i "checking that dom18.example. is not served by secondary ($n)"
+ret=0
+wait_for_no_soa @10.53.0.2 dom18.example. dig.out.test$n || ret=1
+if [ $ret -ne 0 ]; then echo_i "failed"; fi
+status=$((status+ret))
+
+nextpart ns2/named.run >/dev/null
+
+n=$((n+1))
+echo_i "adding domains dom17.example. and dom18.example. to catalog2 zone with ns3 as custom primary using different custom properties syntax ($n)"
+ret=0
+$NSUPDATE -d <<END >> nsupdate.out.test$n 2>&1 || ret=1
+    server 10.53.0.3 ${PORT}
+    update add dom17.zones.catalog2.example. 3600 IN PTR dom17.example.
+    update add dom18.zones.catalog2.example. 3600 IN PTR dom18.example.
+    update add primaries.dom17.zones.catalog2.example. 3600 IN A 10.53.0.3
+    update add primaries.ext.dom18.zones.catalog2.example. 3600 IN A 10.53.0.3
+    send
+END
+if [ $ret -ne 0 ]; then echo_i "failed"; fi
+status=$((status+ret))
+
+n=$((n+1))
+echo_i "waiting for secondary to sync up ($n)"
+ret=0
+wait_for_message ns2/named.run "catz: unknown record in catalog zone - primaries.ext.dom18.zones.catalog2.example IN A(failure) - ignoring" &&
+wait_for_message ns2/named.run "catz: adding zone 'dom17.example' from catalog 'catalog2.example'" &&
+wait_for_message ns2/named.run "catz: adding zone 'dom18.example' from catalog 'catalog2.example'" &&
+wait_for_message ns2/named.run "transfer of 'dom17.example/IN' from 10.53.0.3#${PORT}: Transfer status: success" &&
+wait_for_message ns2/named.run "transfer of 'dom18.example/IN' from 10.53.0.1#${EXTRAPORT1}: Transfer status: success" || ret=1
+if [ $ret -ne 0 ]; then echo_i "failed"; fi
+status=$((status+ret))
+
+# The "primaries" custom property for dom17.example. was added using a supported
+# syntax into a version 1 catalog1 zone, so we expect that it was processed,
+# will override the default setting, and dom17.example. was transferred
+# from the ns3 primary.
+n=$((n+1))
+echo_i "checking that dom17.example. is served by secondary and that it's the one from ns3 ($n)"
+ret=0
+wait_for_a @10.53.0.2 dom17.example. dig.out.test$n || ret=1
+grep "192.0.2.2" dig.out.test$n > /dev/null || ret=1
+if [ $ret -ne 0 ]; then echo_i "failed"; fi
+status=$((status+ret))
+
+# The "primaries" custom property for dom18.example. was added using the new
+# syntax into a version 1 catalog1 zone, so we expect that it was ignored, no
+# override of the default setting happened, and dom18.example. was transferred
+# from the ns1 primary (the default).
+n=$((n+1))
+echo_i "checking that dom18.example. is served by secondary and that it's the one from ns1 ($n)"
+ret=0
+wait_for_a @10.53.0.2 dom18.example. dig.out.test$n || ret=1
+grep "192.0.2.1" dig.out.test$n > /dev/null || ret=1
+if [ $ret -ne 0 ]; then echo_i "failed"; fi
+status=$((status+ret))
+
+nextpart ns2/named.run >/dev/null
+
+n=$((n+1))
+echo_i "deleting domain dom17.example. and dom18.example. from catalog2 ($n)"
+ret=0
+$NSUPDATE -d <<END >> nsupdate.out.test$n 2>&1 || ret=1
+    server 10.53.0.3 ${PORT}
+    update delete dom17.zones.catalog2.example. 3600 IN PTR dom17.example.
+    update delete dom18.zones.catalog2.example. 3600 IN PTR dom18.example.
+    update delete primaries.dom17.zones.catalog2.example. 3600 IN A 10.53.0.3
+    update delete primaries.ext.dom18.zones.catalog2.example. 3600 IN A 10.53.0.3
+    send
+END
+if [ $ret -ne 0 ]; then echo_i "failed"; fi
+status=$((status+ret))
+
+n=$((n+1))
+echo_i "waiting for secondary to sync up ($n)"
+ret=0
+wait_for_message ns2/named.run  "catz: deleting zone 'dom17.example' from catalog 'catalog2.example' - success" &&
+wait_for_message ns2/named.run  "catz: deleting zone 'dom18.example' from catalog 'catalog2.example' - success" &&
+wait_for_message ns2/named.run  "zone_shutdown: zone dom17.example/IN: shutting down" &&
+wait_for_message ns2/named.run  "zone_shutdown: zone dom18.example/IN: shutting down" || ret=1
+if [ $ret -ne 0 ]; then echo_i "failed"; fi
+status=$((status+ret))
+
+n=$((n+1))
+echo_i "checking that dom17.example. is not served by secondary ($n)"
+ret=0
+wait_for_no_soa @10.53.0.2 dom17.example. dig.out.test$n || ret=1
+if [ $ret -ne 0 ]; then echo_i "failed"; fi
+status=$((status+ret))
+
+n=$((n+1))
+echo_i "checking that dom18.example. is not served by secondary ($n)"
+ret=0
+wait_for_no_soa @10.53.0.2 dom18.example. dig.out.test$n || ret=1
+if [ $ret -ne 0 ]; then echo_i "failed"; fi
+status=$((status+ret))
+
+##########################################################################
 n=$((n+1))
 echo_i "checking that reconfig can delete and restore catalog zone configuration ($n)"
 ret=0
index 18af8cc6ea7b7c295dbd4c21c2651fbd8249f15e..70521d33eb5f86bd54d3ee634e9b40a3e6234346 100644 (file)
@@ -154,35 +154,60 @@ then a catalog zone may not be used by that server.
 ::
 
    catalog.example.    IN SOA . . 2016022901 900 600 86400 1
-   catalog.example.    IN NS nsexample.
-   version.catalog.example.    IN TXT "1"
+   catalog.example.    IN NS invalid.
+   version.catalog.example.    IN TXT "2"
 
 Note that this record must have the domain name
 ``version.catalog-zone-name``. The data
 stored in a catalog zone is indicated by the domain name label
-immediately before the catalog zone domain.
+immediately before the catalog zone domain. Currently BIND supports catalog zone
+schema versions "1" and "2".
 
-Catalog zone options can be set either globally for the whole catalog
-zone or for a single member zone. Global options override the settings
-in the configuration file, and member zone options override global
-options.
+Also note that the catalog zone must have an NS record in order to be a valid
+DNS zone, and using the value "invalid." for NS is recommended.
 
-Global options are set at the apex of the catalog zone, e.g.:
+A member zone is added by including a ``PTR`` resource record in the
+``zones`` sub-domain of the catalog zone. The record label can be any unique label.
+The target of the PTR record is the member zone name. For example, to add member zones
+``domain.example`` and ``domain2.example``:
 
 ::
 
-    primaries.catalog.example.    IN AAAA 2001:db8::1
+   5960775ba382e7a4e09263fc06e7c00569b6a05c.zones.catalog.example. IN PTR domain.example.
+   uniquelabel.zones.catalog.example. IN PTR domain2.example.
+
+The label is necessary to identify custom properties (see below) for a specific member zone.
+Also, the zone state can be reset by changing its label.
+
+Catalog Zone Custom Properties
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+BIND uses catalog zones custom properties to define different properties which
+can be set either globally for the whole catalog
+zone or for a single member zone. Global custom properties override the settings
+in the configuration file, and member zone custom properties override global
+custom properties.
 
-BIND currently supports the following options:
+For the version "1" of the schema custom properties must be placed without a special suffix.
+
+For the version "2" of the schema custom properties must be placed under the ".ext" suffix.
+
+Global custom properties are set at the apex of the catalog zone, e.g.:
+
+::
+
+    primaries.ext.catalog.example.    IN AAAA 2001:db8::1
+
+BIND currently supports the following custom properties:
 
 -  A simple ``primaries`` definition:
 
    ::
 
-           primaries.catalog.example.    IN A 192.0.2.1
+           primaries.ext.catalog.example.    IN A 192.0.2.1
 
 
-   This option defines a primary server for the member zones, which can be
+   This custom property defines a primary server for the member zones, which can be
    either an A or AAAA record. If multiple primaries are set, the order in
    which they are used is random.
 
@@ -192,11 +217,11 @@ BIND currently supports the following options:
 
    ::
 
-               label.primaries.catalog.example.     IN A 192.0.2.2
-               label.primaries.catalog.example.     IN TXT "tsig_key_name"
+               label.primaries.ext.catalog.example.     IN A 192.0.2.2
+               label.primaries.ext.catalog.example.     IN TXT "tsig_key_name"
 
 
-   This option defines a primary server for the member zone with a TSIG
+   This custom property defines a primary server for the member zone with a TSIG
    key set. The TSIG key must be configured in the configuration file.
    ``label`` can be any valid DNS label.
 
@@ -206,43 +231,34 @@ BIND currently supports the following options:
 
    ::
 
-               allow-query.catalog.example.   IN APL 1:10.0.0.1/24
-               allow-transfer.catalog.example.    IN APL !1:10.0.0.1/32 1:10.0.0.0/24
+               allow-query.ext.catalog.example.   IN APL 1:10.0.0.1/24
+               allow-transfer.ext.catalog.example.    IN APL !1:10.0.0.1/32 1:10.0.0.0/24
 
 
-   These options are the equivalents of ``allow-query`` and
-   ``allow-transfer`` in a zone declaration in the :iscman:`named.conf`
+   These custom properties are the equivalents of ``allow-query`` and
+   ``allow-transfer`` options in a zone declaration in the :iscman:`named.conf`
    configuration file. The ACL is processed in order; if there is no
    match to any rule, the default policy is to deny access. For the
    syntax of the APL RR, see :rfc:`3123`.
 
-A member zone is added by including a ``PTR`` resource record in the
-``zones`` sub-domain of the catalog zone. The record label is a
-``SHA-1`` hash of the member zone name in wire format. The target of the
-PTR record is the member zone name. For example, to add the member zone
-``domain.example``:
-
-::
-
-   5960775ba382e7a4e09263fc06e7c00569b6a05c.zones.catalog.example. IN PTR domain.example.
-
-The hash is necessary to identify options for a specific member zone.
-The member zone-specific options are defined the same way as global
-options, but in the member zone subdomain:
+The member zone-specific custom properties are defined the same way as global
+custom properties, but in the member zone subdomain:
 
 ::
 
-   primaries.5960775ba382e7a4e09263fc06e7c00569b6a05c.zones.catalog.example. IN A 192.0.2.2
-   label.primaries.5960775ba382e7a4e09263fc06e7c00569b6a05c.zones.catalog.example. IN AAAA 2001:db8::2
-   label.primaries.5960775ba382e7a4e09263fc06e7c00569b6a05c.zones.catalog.example. IN TXT "tsig_key"
-   allow-query.5960775ba382e7a4e09263fc06e7c00569b6a05c.zones.catalog.example. IN APL 1:10.0.0.0/24
+   primaries.ext.5960775ba382e7a4e09263fc06e7c00569b6a05c.zones.catalog.example. IN A 192.0.2.2
+   label.primaries.ext.5960775ba382e7a4e09263fc06e7c00569b6a05c.zones.catalog.example. IN AAAA 2001:db8::2
+   label.primaries.ext.5960775ba382e7a4e09263fc06e7c00569b6a05c.zones.catalog.example. IN TXT "tsig_key_name"
+   allow-query.ext.5960775ba382e7a4e09263fc06e7c00569b6a05c.zones.catalog.example. IN APL 1:10.0.0.0/24
+   primaries.ext.uniquelabel.zones.catalog.example. IN A 192.0.2.3
 
-Options defined for a specific zone override the
-global options defined in the catalog zone. These in turn override the
+Custom properties defined for a specific zone override the
+global custom properties defined in the catalog zone. These in turn override the
 global options defined in the ``catalog-zones`` statement in the
 configuration file.
 
-Note that none of the global records for an option are inherited if any
-records are defined for that option for the specific zone. For example,
+Note that none of the global records for a custom property are inherited if any
+records are defined for that custom property for the specific zone. For example,
 if the zone had a ``primaries`` record of type A but not AAAA, it
-would *not* inherit the type AAAA record from the global option.
+would *not* inherit the type AAAA record from the global custom property
+or from global the option in the configuration file.
index bd1e76b1a5b863606dc7d51d070be5fe77c1d9ad..00540082c8e39be0bf9f32557a0b4c0f6e65ad96 100644 (file)
@@ -40,6 +40,8 @@
 #define DNS_CATZ_ZONES_VALID(catzs) ISC_MAGIC_VALID(catzs, DNS_CATZ_ZONES_MAGIC)
 #define DNS_CATZ_ENTRY_VALID(entry) ISC_MAGIC_VALID(entry, DNS_CATZ_ENTRY_MAGIC)
 
+#define DNS_CATZ_VERSION_UNDEFINED ((uint32_t)(-1))
+
 /*%
  * Single member zone in a catalog
  */
@@ -646,7 +648,7 @@ dns_catz_new_zone(dns_catz_zones_t *catzs, dns_catz_zone_t **zonep,
        dns_catz_options_init(&new_zone->zoneoptions);
        new_zone->active = true;
        new_zone->db_registered = false;
-       new_zone->version = (uint32_t)(-1);
+       new_zone->version = DNS_CATZ_VERSION_UNDEFINED;
        isc_refcount_init(&new_zone->refs, 1);
        new_zone->magic = DNS_CATZ_ZONE_MAGIC;
 
@@ -824,10 +826,12 @@ dns_catz_catzs_detach(dns_catz_zones_t **catzsp) {
 typedef enum {
        CATZ_OPT_NONE,
        CATZ_OPT_ZONES,
+       CATZ_OPT_VERSION,
+       CATZ_OPT_CUSTOM_START, /* CATZ custom properties must go below this */
+       CATZ_OPT_EXT,
        CATZ_OPT_MASTERS,
        CATZ_OPT_ALLOW_QUERY,
        CATZ_OPT_ALLOW_TRANSFER,
-       CATZ_OPT_VERSION,
 } catz_opt_t;
 
 static bool
@@ -844,7 +848,9 @@ catz_opt_cmp(const dns_label_t *option, const char *opt) {
 
 static catz_opt_t
 catz_get_option(const dns_label_t *option) {
-       if (catz_opt_cmp(option, "zones")) {
+       if (catz_opt_cmp(option, "ext")) {
+               return (CATZ_OPT_EXT);
+       } else if (catz_opt_cmp(option, "zones")) {
                return (CATZ_OPT_ZONES);
        } else if (catz_opt_cmp(option, "masters") ||
                   catz_opt_cmp(option, "primaries")) {
@@ -1279,18 +1285,32 @@ catz_process_zones_suboption(dns_catz_zone_t *zone, dns_rdataset_t *value,
        dns_label_t option;
        dns_name_t prefix;
        catz_opt_t opt;
+       unsigned int suffix_labels = 1;
 
        REQUIRE(DNS_CATZ_ZONE_VALID(zone));
        REQUIRE(mhash != NULL);
        REQUIRE(DNS_RDATASET_VALID(value));
        REQUIRE(ISC_MAGIC_VALID(name, DNS_NAME_MAGIC));
 
-       if (name->labels == 0) {
+       if (name->labels < 1) {
                return (ISC_R_FAILURE);
        }
        dns_name_getlabel(name, name->labels - 1, &option);
        opt = catz_get_option(&option);
 
+       /*
+        * The custom properties in version 2 schema must be placed under the
+        * "ext" label.
+        */
+       if (zone->version >= 2 && opt >= CATZ_OPT_CUSTOM_START) {
+               if (opt != CATZ_OPT_EXT || name->labels < 2) {
+                       return (ISC_R_FAILURE);
+               }
+               suffix_labels++;
+               dns_name_getlabel(name, name->labels - 2, &option);
+               opt = catz_get_option(&option);
+       }
+
        /*
         * We're adding this entry now, in case the option is invalid we'll get
         * rid of it in verification phase.
@@ -1308,7 +1328,7 @@ catz_process_zones_suboption(dns_catz_zone_t *zone, dns_rdataset_t *value,
        }
 
        dns_name_init(&prefix, NULL);
-       dns_name_split(name, 1, &prefix, NULL);
+       dns_name_split(name, suffix_labels, &prefix, NULL);
        switch (opt) {
        case CATZ_OPT_MASTERS:
                return (catz_process_primaries(zone, &entry->opts.masters,
@@ -1358,15 +1378,34 @@ catz_process_value(dns_catz_zone_t *zone, dns_name_t *name,
        dns_label_t option;
        dns_name_t prefix;
        catz_opt_t opt;
+       unsigned int suffix_labels = 1;
 
        REQUIRE(DNS_CATZ_ZONE_VALID(zone));
        REQUIRE(ISC_MAGIC_VALID(name, DNS_NAME_MAGIC));
        REQUIRE(DNS_RDATASET_VALID(rdataset));
 
+       if (name->labels < 1) {
+               return (ISC_R_FAILURE);
+       }
        dns_name_getlabel(name, name->labels - 1, &option);
        opt = catz_get_option(&option);
+
+       /*
+        * The custom properties in version 2 schema must be placed under the
+        * "ext" label.
+        */
+       if (zone->version >= 2 && opt >= CATZ_OPT_CUSTOM_START) {
+               if (opt != CATZ_OPT_EXT || name->labels < 2) {
+                       return (ISC_R_FAILURE);
+               }
+               suffix_labels++;
+               dns_name_getlabel(name, name->labels - 2, &option);
+               opt = catz_get_option(&option);
+       }
+
        dns_name_init(&prefix, NULL);
-       dns_name_split(name, 1, &prefix, NULL);
+       dns_name_split(name, suffix_labels, &prefix, NULL);
+
        switch (opt) {
        case CATZ_OPT_ZONES:
                return (catz_process_zones(zone, rdataset, &prefix));