diff --git a/bin/tests/system/catz/.gitignore b/bin/tests/system/catz/.gitignore index 85e2e07384..b5ba95a12a 100644 --- a/bin/tests/system/catz/.gitignore +++ b/bin/tests/system/catz/.gitignore @@ -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 diff --git a/bin/tests/system/catz/clean.sh b/bin/tests/system/catz/clean.sh index c3600d305b..375587cc00 100644 --- a/bin/tests/system/catz/clean.sh +++ b/bin/tests/system/catz/clean.sh @@ -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 diff --git a/bin/tests/system/catz/ns1/catalog.example.db.in b/bin/tests/system/catz/ns1/catalog.example.db.in index a0bab0dfe2..6b52947922 100644 --- a/bin/tests/system/catz/ns1/catalog.example.db.in +++ b/bin/tests/system/catz/ns1/catalog.example.db.in @@ -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 index 0000000000..a0bab0dfe2 --- /dev/null +++ b/bin/tests/system/catz/ns3/catalog.example.db.in @@ -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" diff --git a/bin/tests/system/catz/setup.sh b/bin/tests/system/catz/setup.sh index 5e99898880..9f92499228 100644 --- a/bin/tests/system/catz/setup.sh +++ b/bin/tests/system/catz/setup.sh @@ -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 diff --git a/bin/tests/system/catz/tests.sh b/bin/tests/system/catz/tests.sh index 469acdcdb9..ae17b72e42 100644 --- a/bin/tests/system/catz/tests.sh +++ b/bin/tests/system/catz/tests.sh @@ -434,7 +434,7 @@ ret=0 $NSUPDATE -d <> 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 <> 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 <> 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 <> 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 <> 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 <> 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 <> 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 <> 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 <> 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 <> 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 <> 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 <> 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 <> 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 <> 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 <> 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 <> 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 <> 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 <> 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 diff --git a/doc/arm/catz.rst b/doc/arm/catz.rst index 18af8cc6ea..70521d33eb 100644 --- a/doc/arm/catz.rst +++ b/doc/arm/catz.rst @@ -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. -BIND currently supports the following options: +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. + +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``: +The member zone-specific custom properties are defined the same way as global +custom properties, but in the member zone subdomain: :: - 5960775ba382e7a4e09263fc06e7c00569b6a05c.zones.catalog.example. IN PTR domain.example. + 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 -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: - -:: - - 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 - -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. diff --git a/lib/dns/catz.c b/lib/dns/catz.c index bd1e76b1a5..00540082c8 100644 --- a/lib/dns/catz.c +++ b/lib/dns/catz.c @@ -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));