From: Witold Krecicki Date: Wed, 22 Jun 2016 08:49:25 +0000 (+0200) Subject: 4387. [test] Rewritten test suite for catalog zones. [RT #42676] X-Git-Tag: v9.11.0b1~36 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4681ab1fc2c40e1d70fae38e64630c72c51c300e;p=thirdparty%2Fbind9.git 4387. [test] Rewritten test suite for catalog zones. [RT #42676] 4386. [func] Support for master entries with TSIG keys in catalog zones. [RT #42577] --- diff --git a/CHANGES b/CHANGES index e2db12abd37..f831e1bb981 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,8 @@ +4389. [test] Rewritten test suite for catalog zones. [RT #42676] + +4388. [func] Support for master entries with TSIG keys in catalog + zones. [RT #42577] + 4387. [bug] Change 4336 was not complete leading to SERVFAIL being return as NS records expired. [RT #42683] diff --git a/bin/named/config.c b/bin/named/config.c index fb061e7d3d9..e9c2d599a30 100644 --- a/bin/named/config.c +++ b/bin/named/config.c @@ -600,9 +600,12 @@ ns_config_getipandkeylist(const cfg_obj_t *config, const cfg_obj_t *list, } *stack = NULL; REQUIRE(ipkl != NULL); + REQUIRE(ipkl->count == 0); REQUIRE(ipkl->addrs == NULL); REQUIRE(ipkl->keys == NULL); REQUIRE(ipkl->dscps == NULL); + REQUIRE(ipkl->labels == NULL); + REQUIRE(ipkl->allocated == 0); /* * Get system defaults. @@ -859,6 +862,7 @@ ns_config_getipandkeylist(const cfg_obj_t *config, const cfg_obj_t *list, ipkl->dscps = dscps; ipkl->keys = keys; ipkl->count = addrcount; + ipkl->allocated = addrcount; return (ISC_R_SUCCESS); diff --git a/bin/named/server.c b/bin/named/server.c index 830369d63ea..8fc8ff6df49 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -2046,12 +2046,31 @@ catz_addmodzone_taskaction(isc_task_t *task, isc_event_t *event0) { if (result != ISC_R_SUCCESS) { isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "catz: error \"%s\" while trying to" + "catz: error \"%s\" while trying to " "modify zone \"%s\"", isc_result_totext(result), nameb); goto cleanup; } else { + if (!dns_zone_getadded(zone)) { + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_SERVER, + ISC_LOG_WARNING, + "catz: catz_addmodzone_taskaction: " + "zone '%s' is not a dynamically " + "added zone", + nameb); + goto cleanup; + } + if (dns_zone_get_parentcatz(zone) != ev->origin) { + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_SERVER, ISC_LOG_WARNING, + "catz: catz_delzone_taskaction: " + "zone '%s' exists in multiple " + "catalog zones", + nameb); + goto cleanup; + } dns_zone_detach(&zone); } @@ -2059,7 +2078,7 @@ catz_addmodzone_taskaction(isc_task_t *task, isc_event_t *event0) { if (result != ISC_R_NOTFOUND && result != DNS_R_PARTIALMATCH) { isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "catz: error \"%s\" while trying to" + "catz: error \"%s\" while trying to " "add zone \"%s\"", isc_result_totext(result), nameb); @@ -2141,6 +2160,7 @@ catz_addmodzone_taskaction(isc_task_t *task, isc_event_t *event0) { /* Flag the zone as having been added at runtime */ dns_zone_setadded(zone, ISC_TRUE); + dns_zone_set_parentcatz(zone, ev->origin); cleanup: if (zone != NULL) @@ -2177,8 +2197,6 @@ catz_delzone_taskaction(isc_task_t *task, isc_event_t *event0) { goto cleanup; } - /* TODO make other flag for CZ zones */ - /* TODO2 make sure that we delete only 'own' zones */ if (!dns_zone_getadded(zone)) { isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_WARNING, @@ -2188,6 +2206,15 @@ catz_delzone_taskaction(isc_task_t *task, isc_event_t *event0) { goto cleanup; } + if (dns_zone_get_parentcatz(zone) != ev->origin) { + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_SERVER, ISC_LOG_WARNING, + "catz: catz_delzone_taskaction: zone " + "'%s' exists in multiple catalog zones", + cname); + goto cleanup; + } + /* Stop answering for this zone */ if (dns_zone_getdb(zone, &dbp) == ISC_R_SUCCESS) { dns_db_detach(&dbp); @@ -2196,7 +2223,8 @@ catz_delzone_taskaction(isc_task_t *task, isc_event_t *event0) { CHECK(dns_zt_unmount(ev->view->zonetable, zone)); file = dns_zone_getfile(zone); - isc_file_remove(file); + if (file != NULL) + isc_file_remove(file); isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_WARNING, @@ -5408,8 +5436,11 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig, dns_db_t *db = NULL; tresult = dns_zone_getdb(zone, &db); - if (tresult == ISC_R_SUCCESS) + if (tresult == ISC_R_SUCCESS) { dns_catz_dbupdate_callback(db, view->catzs); + dns_db_detach(&db); + } + } /* diff --git a/bin/named/zoneconf.c b/bin/named/zoneconf.c index 6e81c0835ad..e21bf963c6f 100644 --- a/bin/named/zoneconf.c +++ b/bin/named/zoneconf.c @@ -1148,10 +1148,8 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig, ztype == dns_zone_master))) { dns_ipkeylist_t ipkl; - ipkl.count = 0; - ipkl.addrs = NULL; - ipkl.dscps = NULL; - ipkl.keys = NULL; + dns_ipkeylist_init(&ipkl); + RETERR(ns_config_getipandkeylist(config, obj, mctx, &ipkl)); result = dns_zone_setalsonotifydscpkeys(zone, @@ -1623,10 +1621,8 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig, (void)cfg_map_get(zoptions, "masters", &obj); if (obj != NULL) { dns_ipkeylist_t ipkl; - ipkl.count = 0; - ipkl.addrs = NULL; - ipkl.dscps = NULL; - ipkl.keys = NULL; + dns_ipkeylist_init(&ipkl); + RETERR(ns_config_getipandkeylist(config, obj, mctx, &ipkl)); result = dns_zone_setmasterswithkeys(mayberaw, diff --git a/bin/tests/system/catz/clean.sh b/bin/tests/system/catz/clean.sh index 46dc9c7e8d7..516324d48b1 100644 --- a/bin/tests/system/catz/clean.sh +++ b/bin/tests/system/catz/clean.sh @@ -13,13 +13,15 @@ # PERFORMANCE OF THIS SOFTWARE. rm -f dig.out.* -rm -f nsupdate.out.* +rm -f ns*/*.jnl +rm -f ns*/*.nzf +rm -f ns*/named.lock rm -f ns*/named.memstats rm -f ns*/named.run -rm -f ns*/named.lock rm -f ns1/*dom*example.db -rm -f ns{1,2}/catalog{1,2,3}.example.db rm -f ns2/__catz__*db +rm -f ns2/named.conf +rm -f ns3/dom{13,14}.example.db +rm -f nsupdate.out.* +rm -f ns{1,2,3}/catalog{1,2,3,4}.example.db rm -rf ns2/zonedir -rm -f ns*/*.jnl -rm -f ns*/*.nzf diff --git a/bin/tests/system/catz/ns1/named.conf b/bin/tests/system/catz/ns1/named.conf index ecdbb0b2d02..521d147a676 100644 --- a/bin/tests/system/catz/ns1/named.conf +++ b/bin/tests/system/catz/ns1/named.conf @@ -31,6 +31,7 @@ options { listen-on-v6 { none; }; notify no; recursion no; + allow-transfer { any; }; }; zone "catalog1.example" { @@ -42,20 +43,27 @@ zone "catalog1.example" { notify explicit; }; -zone "catalog2.example" { +zone "catalog3.example" { type master; - file "catalog2.example.db"; + file "catalog3.example.db"; allow-transfer { any; }; allow-update { any; }; also-notify { 10.53.0.2; }; notify explicit; }; -zone "catalog3.example" { +zone "catalog4.example" { type master; - file "catalog3.example.db"; + file "catalog4.example.db"; allow-transfer { any; }; allow-update { any; }; also-notify { 10.53.0.2; }; notify explicit; }; + +/* catalog5 is missing on purpose */ + +key tsig_key. { + secret "LSAnCU+Z"; + algorithm hmac-md5; +}; diff --git a/bin/tests/system/catz/ns2/named.conf b/bin/tests/system/catz/ns2/named.conf.in similarity index 83% rename from bin/tests/system/catz/ns2/named.conf rename to bin/tests/system/catz/ns2/named.conf.in index d989b9ebd83..f2ea7cbbb12 100644 --- a/bin/tests/system/catz/ns2/named.conf +++ b/bin/tests/system/catz/ns2/named.conf.in @@ -27,7 +27,7 @@ options { port 5300; pid-file "named.pid"; listen-on { 10.53.0.2; }; - listen-on-v6 { none; }; + listen-on-v6 { fd92:7065:b8e:ffff::2; }; notify no; recursion no; serial-query-rate 100; @@ -42,6 +42,10 @@ options { zone "catalog3.example" default-masters { 10.53.0.1; } zone-directory "nonexistent"; +#T1 zone "catalog4.example" +#T1 default-masters { 10.53.0.1; }; +#T2 zone "catalog5.example" +#T2 default-masters { 10.53.0.1; }; }; }; @@ -54,7 +58,7 @@ zone "catalog1.example" { zone "catalog2.example" { type slave; file "catalog2.example.db"; - masters { 10.53.0.1; }; + masters { 10.53.0.3; }; }; zone "catalog3.example" { @@ -62,3 +66,14 @@ zone "catalog3.example" { file "catalog3.example.db"; masters { 10.53.0.1; }; }; + +zone "catalog4.example" { + type slave; + file "catalog4.example.db"; + masters { 10.53.0.1; }; +}; + +key tsig_key. { + secret "LSAnCU+Z"; + algorithm hmac-md5; +}; diff --git a/bin/tests/system/catz/ns3/dom4.example.db b/bin/tests/system/catz/ns3/dom5.example.db similarity index 100% rename from bin/tests/system/catz/ns3/dom4.example.db rename to bin/tests/system/catz/ns3/dom5.example.db diff --git a/bin/tests/system/catz/ns3/dom6.example.db b/bin/tests/system/catz/ns3/dom6.example.db new file mode 100644 index 00000000000..2373dce3364 --- /dev/null +++ b/bin/tests/system/catz/ns3/dom6.example.db @@ -0,0 +1,16 @@ +; Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC") +; +; Permission to use, copy, modify, and/or distribute this software for any +; purpose with or without fee is hereby granted, provided that the above +; copyright notice and this permission notice appear in all copies. +; +; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +; PERFORMANCE OF THIS SOFTWARE. + +@ 3600 IN SOA . . 1 3600 3600 3600 3600 +@ IN NS invalid. diff --git a/bin/tests/system/catz/ns3/named.conf b/bin/tests/system/catz/ns3/named.conf index 0b9e5b4e7ff..5338752144c 100644 --- a/bin/tests/system/catz/ns3/named.conf +++ b/bin/tests/system/catz/ns3/named.conf @@ -25,16 +25,35 @@ options { notify-source 10.53.0.3; transfer-source 10.53.0.3; port 5300; + allow-new-zones yes; pid-file "named.pid"; + provide-ixfr no; listen-on { 10.53.0.3; }; - listen-on-v6 { none; }; + listen-on-v6 { fd92:7065:b8e:ffff::3; }; notify no; recursion no; }; -zone "dom4.example" { +zone "catalog2.example" { type master; - file "dom4.example.db"; + file "catalog2.example.db"; + allow-transfer { any; }; + allow-update { any; }; + also-notify { 10.53.0.2; }; + notify explicit; +}; + +zone "dom5.example" { + type master; + file "dom5.example.db"; + allow-transfer { any; }; + allow-update { any; }; + notify explicit; +}; + +zone "dom6.example" { + type master; + file "dom6.example.db"; allow-transfer { any; }; allow-update { any; }; notify explicit; diff --git a/bin/tests/system/catz/setup.sh b/bin/tests/system/catz/setup.sh index 2b8716cdcb8..c6607b09678 100644 --- a/bin/tests/system/catz/setup.sh +++ b/bin/tests/system/catz/setup.sh @@ -20,6 +20,8 @@ SYSTEMTESTTOP=.. $SHELL clean.sh cat ns1/catalog.example.db.in > ns1/catalog1.example.db -cat ns1/catalog.example.db.in > ns1/catalog2.example.db +cat ns1/catalog.example.db.in > ns3/catalog2.example.db cat ns1/catalog.example.db.in > ns1/catalog3.example.db +cat ns1/catalog.example.db.in > ns1/catalog4.example.db +cat ns2/named.conf.in > ns2/named.conf mkdir ns2/zonedir diff --git a/bin/tests/system/catz/tests.sh b/bin/tests/system/catz/tests.sh index c37b3503974..bb06559e9e9 100644 --- a/bin/tests/system/catz/tests.sh +++ b/bin/tests/system/catz/tests.sh @@ -19,47 +19,48 @@ SYSTEMTESTTOP=.. status=0 n=0 - +########################################################################## +echo "I:Testing adding/removing of domain in catalog zone" n=`expr $n + 1` -echo "I:checking that dom1.example is not served by master ($n)" +echo "I: checking that dom1.example is not served by master ($n)" ret=0 $DIG soa dom1.example @10.53.0.1 -p 5300 > dig.out.test$n grep "status: REFUSED" dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi +if [ $ret != 0 ]; then echo "I: failed"; fi status=`expr $status + $ret` n=`expr $n + 1` -echo "I:Adding a domain dom1.example to master via RNDC ($n)" +echo "I: Adding a domain dom1.example to master via RNDC ($n)" ret=0 echo "@ 3600 IN SOA . . 1 3600 3600 3600 3600" > ns1/dom1.example.db echo "@ IN NS invalid." >> ns1/dom1.example.db $RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 addzone dom1.example '{type master; file "dom1.example.db";};' || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi +if [ $ret != 0 ]; then echo "I: failed"; fi status=`expr $status + $ret` n=`expr $n + 1` -echo "I:checking that dom1.example is now served by master ($n)" +echo "I: checking that dom1.example is now served by master ($n)" ret=0 $DIG soa dom1.example @10.53.0.1 -p 5300 > dig.out.test$n grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi +if [ $ret != 0 ]; then echo "I: failed"; fi status=`expr $status + $ret` cur=`awk 'BEGIN {l=0} /^/ {l++} END { print l }' ns2/named.run` n=`expr $n + 1` -echo "I:Adding domain dom1.example to catalog1 zone ($n)" +echo "I: Adding domain dom1.example to catalog1 zone ($n)" ret=0 $NSUPDATE -d <> nsupdate.out.test$n 2>&1 || ret=1 server 10.53.0.1 5300 update add e721433b6160b450260d4f54b3ec8bab30cb3b83.zones.catalog1.example 3600 IN PTR dom1.example. send END -if [ $ret != 0 ]; then echo "I:failed"; fi +if [ $ret != 0 ]; then echo "I: failed"; fi status=`expr $status + $ret` n=`expr $n + 1` -echo "I:waiting for slave to sync up ($n)" +echo "I: waiting for slave to sync up ($n)" ret=1 try=0 while test $try -lt 45 @@ -81,30 +82,37 @@ do } try=`expr $try + 1` done -if [ $ret != 0 ]; then echo "I:failed"; fi +if [ $ret != 0 ]; then echo "I: failed"; fi status=`expr $status + $ret` n=`expr $n + 1` -echo "I:checking that dom1.example is served by slave ($n)" +echo "I: checking that dom1.example is served by slave ($n)" ret=0 $DIG soa dom1.example @10.53.0.2 -p 5300 > dig.out.test$n grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: checking that zone-directory is populated ($n)" +ret=0 +[ -f "ns2/zonedir/__catz___default_catalog1.example_dom1.example.db" ] || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi status=`expr $status + $ret` n=`expr $n + 1` -echo "I:Removing domain dom1.example from catalog1 zone ($n)" +echo "I: removing domain dom1.example from catalog1 zone ($n)" ret=0 $NSUPDATE -d <> nsupdate.out.test$n 2>&1 || ret=1 server 10.53.0.1 5300 update delete e721433b6160b450260d4f54b3ec8bab30cb3b83.zones.catalog1.example send END -if [ $ret != 0 ]; then echo "I:failed"; fi +if [ $ret != 0 ]; then echo "I: failed"; fi status=`expr $status + $ret` n=`expr $n + 1` -echo "I:waiting for slave to sync up ($n)" +echo "I: waiting for slave to sync up ($n)" ret=1 try=0 while test $try -lt 45 @@ -116,37 +124,46 @@ do } try=`expr $try + 1` done -if [ $ret != 0 ]; then echo "I:failed"; fi +if [ $ret != 0 ]; then echo "I: failed"; fi status=`expr $status + $ret` n=`expr $n + 1` -echo "I:checking that dom1.example is not served by slave ($n)" +echo "I: checking that dom1.example is not served by slave ($n)" ret=0 $DIG soa dom1.example @10.53.0.2 -p 5300 > dig.out.test$n grep "status: REFUSED" dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: checking that zone-directory is emptied ($n)" +ret=0 +[ -f "ns2/zonedir/__catz___default_catalog1.example_dom1.example.db" ] && ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi status=`expr $status + $ret` +########################################################################## +echo "I:Testing various simple operations on domains, including using multiple catalog zones and garbage in zone" n=`expr $n + 1` -echo "I:Adding a domain dom2.example to master via RNDC ($n)" +echo "I: adding domain dom2.example to master via RNDC ($n)" ret=0 echo "@ 3600 IN SOA . . 1 3600 3600 3600 3600" > ns1/dom2.example.db echo "@ IN NS invalid." >> ns1/dom2.example.db $RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 addzone dom2.example '{type master; file "dom2.example.db";};' || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi +if [ $ret != 0 ]; then echo "I: failed"; fi status=`expr $status + $ret` n=`expr $n + 1` -echo "I:Adding a domain dom5.example to master via RNDC ($n)" +echo "I: adding domain dom4.example to master via RNDC ($n)" ret=0 -echo "@ 3600 IN SOA . . 1 3600 3600 3600 3600" > ns1/dom5.example.db -echo "@ IN NS invalid." >> ns1/dom5.example.db -$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 addzone dom5.example '{type master; file "dom5.example.db";};' || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi +echo "@ 3600 IN SOA . . 1 3600 3600 3600 3600" > ns1/dom4.example.db +echo "@ IN NS invalid." >> ns1/dom4.example.db +$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 addzone dom4.example '{type master; file "dom4.example.db";};' || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi status=`expr $status + $ret` n=`expr $n + 1` -echo "I:Adding domains dom2.example, dom3.example and some trash to catalog1 zone ($n)" +echo "I: adding domains dom2.example, dom3.example and some garbage to catalog1 zone ($n)" ret=0 $NSUPDATE -d <> nsupdate.out.test$n 2>&1 || ret=1 server 10.53.0.1 5300 @@ -156,31 +173,37 @@ $NSUPDATE -d <> nsupdate.out.test$n 2>&1 || ret=1 update add trash.catalog1.example 3600 IN A 1.2.3.4 update add trash2.foo.catalog1.example 3600 IN A 1.2.3.4 update add trash3.zones.catalog1.example 3600 IN NS a.dom2.example. + update add foobarbaz.b901f492f3ebf6c1e5b597e51766f02f0479eb03.zones.catalog1.example 3600 IN PTR dom3.example. + update add blahblah.636722929740e507aaf27c502812fc395d30fb17.zones.catalog1.example 3600 IN PTR dom2.example. + update add foobarbaz.b901f492f3ebf6c1e5b597e51766f02f0479eb03.zones.catalog1.example 3600 IN APL 1:1.2.3.4/30 + update add blahblah.636722929740e507aaf27c502812fc395d30fb17.zones.catalog1.example 3600 IN TXT "blah blah" + update add version.catalog1.example 3600 IN A 1.2.3.4 send + END -if [ $ret != 0 ]; then echo "I:failed"; fi +if [ $ret != 0 ]; then echo "I: failed"; fi status=`expr $status + $ret` n=`expr $n + 1` -echo "I:Adding domains dom5.example to catalog2 zone ($n)" +echo "I: adding domain dom4.example to catalog2 zone ($n)" ret=0 $NSUPDATE -d <> nsupdate.out.test$n 2>&1 || ret=1 - server 10.53.0.1 5300 - update add de26b88d855397a03f77ff1162fd055d8b419584.zones.catalog2.example 3600 IN PTR dom5.example. + server 10.53.0.3 5300 + update add de26b88d855397a03f77ff1162fd055d8b419584.zones.catalog2.example 3600 IN PTR dom4.example. send END -if [ $ret != 0 ]; then echo "I:failed"; fi +if [ $ret != 0 ]; then echo "I: failed"; fi status=`expr $status + $ret` n=`expr $n + 1` -echo "I:waiting for slave to sync up ($n)" +echo "I: waiting for slave to sync up ($n)" ret=1 try=0 while test $try -lt 45 do sleep 1 - sed -n "$cur,"'$p' < ns2/named.run | grep "catz: adding zone 'dom5.example' from catalog 'catalog2.example'" > /dev/null && { + sed -n "$cur,"'$p' < ns2/named.run | grep "catz: adding zone 'dom4.example' from catalog 'catalog2.example'" > /dev/null && { ret=0 break } @@ -190,51 +213,51 @@ try=0 while test $try -lt 45 do sleep 1 - sed -n "$cur,"'$p' < ns2/named.run | grep "transfer of 'dom5.example/IN' from 10.53.0.1#5300: Transfer status: success" > /dev/null && { + sed -n "$cur,"'$p' < ns2/named.run | grep "transfer of 'dom4.example/IN' from 10.53.0.1#5300: Transfer status: success" > /dev/null && { ret=0 break } try=`expr $try + 1` done -if [ $ret != 0 ]; then echo "I:failed"; fi +if [ $ret != 0 ]; then echo "I: failed"; fi status=`expr $status + $ret` n=`expr $n + 1` -echo "I:checking that dom5.example is served by slave ($n)" +echo "I: checking that dom4.example is served by slave ($n)" ret=0 -$DIG soa dom5.example @10.53.0.2 -p 5300 > dig.out.test$n +$DIG soa dom4.example @10.53.0.2 -p 5300 > dig.out.test$n grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi +if [ $ret != 0 ]; then echo "I: failed"; fi status=`expr $status + $ret` n=`expr $n + 1` -echo "I:checking that dom3.example is not served by master ($n)" +echo "I: checking that dom3.example is not served by master ($n)" ret=0 $DIG soa dom3.example @10.53.0.1 -p 5300 > dig.out.test$n grep "status: REFUSED" dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi +if [ $ret != 0 ]; then echo "I: failed"; fi status=`expr $status + $ret` n=`expr $n + 1` -echo "I:Adding a domain dom3.example to master via RNDC ($n)" +echo "I: adding a domain dom3.example to master via RNDC ($n)" ret=0 echo "@ 3600 IN SOA . . 1 3600 3600 3600 3600" > ns1/dom3.example.db echo "@ IN NS invalid." >> ns1/dom3.example.db -$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 addzone dom3.example '{type master; file "dom3.example.db"; also-notify { 10.53.0.2; }; };' || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi +$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 addzone dom3.example '{type master; file "dom3.example.db"; also-notify { 10.53.0.2; }; notify explicit; };' || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi status=`expr $status + $ret` n=`expr $n + 1` -echo "I:checking that dom3.example is served by master ($n)" +echo "I: checking that dom3.example is served by master ($n)" ret=0 -$DIG soa dom2.example @10.53.0.1 -p 5300 > dig.out.test$n +$DIG soa dom3.example @10.53.0.1 -p 5300 > dig.out.test$n grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi +if [ $ret != 0 ]; then echo "I: failed"; fi status=`expr $status + $ret` n=`expr $n + 1` -echo "I:waiting for slave to sync up ($n)" +echo "I: waiting for slave to sync up ($n)" ret=1 try=0 while test $try -lt 45 @@ -256,161 +279,278 @@ do } try=`expr $try + 1` done -if [ $ret != 0 ]; then echo "I:failed"; fi +if [ $ret != 0 ]; then echo "I: failed"; fi status=`expr $status + $ret` n=`expr $n + 1` -echo "I:checking that dom3.example is served by slave ($n)" +echo "I: checking that dom3.example is served by slave ($n)" ret=0 $DIG soa dom3.example @10.53.0.2 -p 5300 > dig.out.test$n grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: removing all records from catalog1 zone ($n)" +ret=0 +$NSUPDATE -d <> nsupdate.out.test$n 2>&1 || ret=1 + server 10.53.0.1 5300 + update delete 636722929740e507aaf27c502812fc395d30fb17.zones.catalog1.example 3600 IN PTR dom2.example. + update delete b901f492f3ebf6c1e5b597e51766f02f0479eb03.zones.catalog1.example 3600 IN PTR dom3.example. + update delete e721433b6160b450260d4f54b3ec8bab30cb3b83.zones.catalog1.example 3600 IN NS foo.bar. + update delete trash.catalog1.example 3600 IN A 1.2.3.4 + update delete trash2.foo.catalog1.example 3600 IN A 1.2.3.4 + update delete trash3.zones.catalog1.example 3600 IN NS a.dom2.example. + update delete foobarbaz.b901f492f3ebf6c1e5b597e51766f02f0479eb03.zones.catalog1.example 3600 IN PTR dom3.example. + update delete blahblah.636722929740e507aaf27c502812fc395d30fb17.zones.catalog1.example 3600 IN PTR dom2.example. + update delete foobarbaz.b901f492f3ebf6c1e5b597e51766f02f0479eb03.zones.catalog1.example 3600 IN APL 1:1.2.3.4/30 + update delete blahblah.636722929740e507aaf27c502812fc395d30fb17.zones.catalog1.example 3600 IN TXT "blah blah" + update delete version.catalog1.example 3600 IN A 1.2.3.4 + send + +END +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: removing all records from catalog2 zone ($n)" +ret=0 +$NSUPDATE -d <> nsupdate.out.test$n 2>&1 || ret=1 + server 10.53.0.3 5300 + update delete de26b88d855397a03f77ff1162fd055d8b419584.zones.catalog2.example 3600 IN PTR dom4.example. + send +END +if [ $ret != 0 ]; then echo "I: failed"; fi status=`expr $status + $ret` +########################################################################## +echo "I:Testing masters suboption and random labels" n=`expr $n + 1` -echo "I:Adding dom4.example with 'masters' defined and a random label ($n)" +echo "I: adding dom5.example with 'masters' suboption set and a random label ($n)" ret=0 $NSUPDATE -d <> nsupdate.out.test$n 2>&1 || ret=1 server 10.53.0.1 5300 - update add somerandomlabel.zones.catalog1.example 3600 IN PTR dom4.example. + update add somerandomlabel.zones.catalog1.example 3600 IN PTR dom5.example. update add masters.somerandomlabel.zones.catalog1.example 3600 IN A 10.53.0.3 send END -if [ $ret != 0 ]; then echo "I:failed"; fi +if [ $ret != 0 ]; then echo "I: failed"; fi status=`expr $status + $ret` n=`expr $n + 1` -echo "I:waiting for slave to sync up ($n)" +echo "I: waiting for slave to sync up ($n)" ret=1 try=0 while test $try -lt 45 do sleep 1 - sed -n "$cur,"'$p' < ns2/named.run | grep "catz: adding zone 'dom4.example' from catalog 'catalog1.example'" > /dev/null && { + sed -n "$cur,"'$p' < ns2/named.run | grep "catz: adding zone 'dom5.example' from catalog 'catalog1.example'" > /dev/null && { ret=0 break } try=`expr $try + 1` done + try=0 while test $try -lt 45 do sleep 1 - sed -n "$cur,"'$p' < ns2/named.run | grep "transfer of 'dom4.example/IN' from 10.53.0.3#5300: Transfer status: success" > /dev/null && { + sed -n "$cur,"'$p' < ns2/named.run | grep "transfer of 'dom5.example/IN' from 10.53.0.3#5300: Transfer status: success" > /dev/null && { ret=0 break } try=`expr $try + 1` done -if [ $ret != 0 ]; then echo "I:failed"; fi +if [ $ret != 0 ]; then echo "I: failed"; fi status=`expr $status + $ret` n=`expr $n + 1` -echo "I:checking that dom4.example is served by slave ($n)" +echo "I: checking that dom5.example is served by slave ($n)" ret=0 -$DIG soa dom4.example @10.53.0.2 -p 5300 > dig.out.test$n +$DIG soa dom5.example @10.53.0.2 -p 5300 > dig.out.test$n grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi +if [ $ret != 0 ]; then echo "I: failed"; fi status=`expr $status + $ret` n=`expr $n + 1` -echo "I:Removing domain dom2.example from catalog1 zone ($n)" +echo "I: removing dom5.example ($n)" ret=0 $NSUPDATE -d <> nsupdate.out.test$n 2>&1 || ret=1 server 10.53.0.1 5300 - update delete 636722929740e507aaf27c502812fc395d30fb17.zones.catalog1.example + update delete somerandomlabel.zones.catalog1.example 3600 IN PTR dom5.example. + update delete masters.somerandomlabel.zones.catalog1.example 3600 IN A 10.53.0.3 send END -if [ $ret != 0 ]; then echo "I:failed"; fi +if [ $ret != 0 ]; then echo "I: failed"; fi status=`expr $status + $ret` n=`expr $n + 1` -echo "I:waiting for slave to sync up ($n)" +echo "I: waiting for slave to sync up ($n)" ret=1 try=0 while test $try -lt 45 do sleep 1 - sed -n "$cur,"'$p' < ns2/named.run | grep "catz: deleting zone 'dom2.example' from catalog 'catalog1.example'" > /dev/null && { + sed -n "$cur,"'$p' < ns2/named.run | grep "catz: deleting zone 'dom5.example' from catalog 'catalog1.example'" > /dev/null && { ret=0 break } try=`expr $try + 1` done -if [ $ret != 0 ]; then echo "I:failed"; fi +if [ $ret != 0 ]; then echo "I: failed"; fi status=`expr $status + $ret` - n=`expr $n + 1` -echo "I:checking that dom2.example is not served by slave ($n)" +echo "I: checking that dom5.example is no longer served by slave ($n)" ret=0 -$DIG soa dom2.example @10.53.0.2 -p 5300 > dig.out.test$n +$DIG soa dom5.example @10.53.0.2 -p 5300 > dig.out.test$n grep "status: REFUSED" dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi +if [ $ret != 0 ]; then echo "I: failed"; fi status=`expr $status + $ret` + +########################################################################## +echo "I:Testing masters global option" n=`expr $n + 1` -echo "I:checking that dom3.example is still served by slave ($n)" +echo "I: adding dom6.example and global masters option ($n)" ret=0 -$DIG soa dom3.example @10.53.0.2 -p 5300 > dig.out.test$n +$NSUPDATE -d <> nsupdate.out.test$n 2>&1 || ret=1 + server 10.53.0.1 5300 + update add masters.catalog1.example 3600 IN A 10.53.0.3 + update add masters.catalog1.example 3600 IN AAAA fd92:7065:b8e:ffff::3 + update add 4346f565b4d63ddb99e5d2497ff22d04e878e8f8.zones.catalog1.example 3600 IN PTR dom6.example. + send +END +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: waiting for slave to sync up ($n)" +ret=1 +try=0 +while test $try -lt 45 +do + sleep 1 + sed -n "$cur,"'$p' < ns2/named.run | grep "catz: adding zone 'dom6.example' from catalog 'catalog1.example'" > /dev/null && { + ret=0 + break + } + try=`expr $try + 1` +done + +try=0 +while test $try -lt 45 +do + sleep 1 + sed -n "$cur,"'$p' < ns2/named.run | grep "transfer of 'dom6.example/IN' from " > /dev/null && { + ret=0 + break + } + try=`expr $try + 1` +done +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: checking that dom6.example is served by slave ($n)" +ret=0 +$DIG soa dom6.example @10.53.0.2 -p 5300 > dig.out.test$n grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: removing dom6.example ($n)" +ret=0 +$NSUPDATE -d <> nsupdate.out.test$n 2>&1 || ret=1 + server 10.53.0.1 5300 + update delete masters.catalog1.example 3600 IN A 10.53.0.3 + update delete masters.catalog1.example 3600 IN AAAA fd92:7065:b8e:ffff::3 + update delete 4346f565b4d63ddb99e5d2497ff22d04e878e8f8.zones.catalog1.example 3600 IN PTR dom6.example. + send +END +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: waiting for slave to sync up ($n)" +ret=1 +try=0 +while test $try -lt 45 +do + sleep 1 + sed -n "$cur,"'$p' < ns2/named.run | grep "catz: deleting zone 'dom6.example' from catalog 'catalog1.example'" > /dev/null && { + ret=0 + break + } + try=`expr $try + 1` +done +if [ $ret != 0 ]; then echo "I: failed"; fi status=`expr $status + $ret` n=`expr $n + 1` -echo "I:checking that zone-directory is populated ($n)" +echo "I: checking that dom6.example is no longer served by slave ($n)" ret=0 -[ -f "ns2/zonedir/__catz___default_catalog1.example_dom3.example.db" ] || ret=1 -[ -f "ns2/zonedir/__catz___default_catalog1.example_dom4.example.db" ] || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi +$DIG soa dom6.example @10.53.0.2 -p 5300 > dig.out.test$n +grep "status: REFUSED" dig.out.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi status=`expr $status + $ret` + +########################################################################## n=`expr $n + 1` -echo "I:checking that a missing zone directory forces in-memory ($n)" +echo "I:Checking that a missing zone directory forces in-memory ($n)" ret=0 grep "'nonexistent' not found; zone files will not be saved" ns2/named.run > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi +if [ $ret != 0 ]; then echo "I: failed"; fi status=`expr $status + $ret` +########################################################################## +echo "I:Testing allow-query and allow-transfer ACLs" n=`expr $n + 1` -echo "I:Adding a domain dom6.example to master via RNDC ($n)" +echo "I: adding domains dom7.example and dom8.example to master via RNDC ($n)" ret=0 -echo "@ 3600 IN SOA . . 1 3600 3600 3600 3600" > ns1/dom6.example.db -echo "@ IN NS invalid." >> ns1/dom6.example.db -$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 addzone dom6.example '{type master; file "dom6.example.db";};' || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi +echo "@ 3600 IN SOA . . 1 3600 3600 3600 3600" > ns1/dom7.example.db +echo "@ IN NS invalid." >> ns1/dom7.example.db +$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 addzone dom7.example '{type master; file "dom7.example.db";};' || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` +echo "@ 3600 IN SOA . . 1 3600 3600 3600 3600" > ns1/dom8.example.db +echo "@ IN NS invalid." >> ns1/dom8.example.db +$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 addzone dom8.example '{type master; file "dom8.example.db";};' || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi status=`expr $status + $ret` n=`expr $n + 1` -echo "I:checking that dom6.example is now served by master ($n)" +echo "I: checking that dom7.example is now served by master ($n)" ret=0 -$DIG soa dom6.example @10.53.0.1 -p 5300 > dig.out.test$n +$DIG soa dom7.example @10.53.0.1 -p 5300 > dig.out.test$n grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi +if [ $ret != 0 ]; then echo "I: failed"; fi status=`expr $status + $ret` cur=`awk 'BEGIN {l=0} /^/ {l++} END { print l }' ns2/named.run` n=`expr $n + 1` -echo "I:Adding domain dom6.example to catalog1 zone with an allow-query statement ($n)" +echo "I: adding domain dom7.example to catalog1 zone with an allow-query statement ($n)" ret=0 $NSUPDATE -d <> nsupdate.out.test$n 2>&1 || ret=1 server 10.53.0.1 5300 - update add 4346f565b4d63ddb99e5d2497ff22d04e878e8f8.zones.catalog1.example 3600 IN PTR dom6.example. - update add allow-query.4346f565b4d63ddb99e5d2497ff22d04e878e8f8.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 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 send END -if [ $ret != 0 ]; then echo "I:failed"; fi +if [ $ret != 0 ]; then echo "I: failed"; fi status=`expr $status + $ret` n=`expr $n + 1` -echo "I:waiting for slave to sync up ($n)" +echo "I: waiting for slave to sync up ($n)" ret=1 try=0 while test $try -lt 45 do sleep 1 - sed -n "$cur,"'$p' < ns2/named.run | grep "catz: adding zone 'dom6.example' from catalog 'catalog1.example'" > /dev/null && { + sed -n "$cur,"'$p' < ns2/named.run | grep "catz: adding zone 'dom7.example' from catalog 'catalog1.example'" > /dev/null && { ret=0 break } @@ -420,104 +560,104 @@ try=0 while test $try -lt 45 do sleep 1 - sed -n "$cur,"'$p' < ns2/named.run | grep "transfer of 'dom6.example/IN' from 10.53.0.1#5300: Transfer status: success" > /dev/null && { + sed -n "$cur,"'$p' < ns2/named.run | grep "transfer of 'dom7.example/IN' from 10.53.0.1#5300: Transfer status: success" > /dev/null && { ret=0 break } try=`expr $try + 1` done -if [ $ret != 0 ]; then echo "I:failed"; fi +if [ $ret != 0 ]; then echo "I: failed"; fi status=`expr $status + $ret` n=`expr $n + 1` -echo "I:checking that dom6.example is accessible from 10.53.0.1 ($n)" +echo "I: checking that dom7.example is accessible from 10.53.0.1 ($n)" ret=0 -$DIG soa dom6.example -b 10.53.0.1 @10.53.0.2 -p 5300 > dig.out.test$n +$DIG soa dom7.example -b 10.53.0.1 @10.53.0.2 -p 5300 > dig.out.test$n grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi +if [ $ret != 0 ]; then echo "I: failed"; fi status=`expr $status + $ret` n=`expr $n + 1` -echo "I:checking that dom6.example is not accessible from 10.53.0.2 ($n)" +echo "I: checking that dom7.example is not accessible from 10.53.0.2 ($n)" ret=0 -$DIG soa dom6.example -b 10.53.0.2 @10.53.0.2 -p 5300 > dig.out.test$n +$DIG soa dom7.example -b 10.53.0.2 @10.53.0.2 -p 5300 > dig.out.test$n grep "status: REFUSED" dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi +if [ $ret != 0 ]; then echo "I: failed"; fi status=`expr $status + $ret` n=`expr $n + 1` -echo "I:checking that dom6.example is accessible from 10.53.0.5 ($n)" +echo "I: checking that dom7.example is accessible from 10.53.0.5 ($n)" ret=0 -$DIG soa dom6.example -b 10.53.0.5 @10.53.0.2 -p 5300 > dig.out.test$n +$DIG soa dom7.example -b 10.53.0.5 @10.53.0.2 -p 5300 > dig.out.test$n grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi +if [ $ret != 0 ]; then echo "I: failed"; fi status=`expr $status + $ret` cur=`awk 'BEGIN {l=0} /^/ {l++} END { print l }' ns2/named.run` n=`expr $n + 1` -echo "I:Adding global allow-query and allow-domain ACLs ($n)" +echo "I: adding dom8.example domain and global allow-query and allow-transfer ACLs ($n)" ret=0 $NSUPDATE -d <> nsupdate.out.test$n 2>&1 || ret=1 server 10.53.0.1 5300 - update add 636722929740e507aaf27c502812fc395d30fb17.zones.catalog1.example 3600 IN PTR dom2.example. + 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 send END -if [ $ret != 0 ]; then echo "I:failed"; fi +if [ $ret != 0 ]; then echo "I: failed"; fi status=`expr $status + $ret` n=`expr $n + 1` -echo "I:waiting for slave to sync up ($n)" +echo "I: waiting for slave to sync up ($n)" ret=1 try=0 while test $try -lt 45 do sleep 1 - sed -n "$cur,"'$p' < ns2/named.run | grep "catz: adding zone 'dom2.example' from catalog 'catalog1.example'" > /dev/null && { + sed -n "$cur,"'$p' < ns2/named.run | grep "catz: update_from_db: new zone merged" > /dev/null && { ret=0 break } try=`expr $try + 1` done -if [ $ret != 0 ]; then echo "I:failed"; fi +if [ $ret != 0 ]; then echo "I: failed"; fi status=`expr $status + $ret` n=`expr $n + 1` -echo "I:checking that dom3.example is accessible from 10.53.0.1 ($n)" +echo "I: checking that dom8.example is accessible from 10.53.0.1 ($n)" ret=0 -$DIG soa dom3.example -b 10.53.0.1 @10.53.0.2 -p 5300 > dig.out.test$n +$DIG soa dom8.example -b 10.53.0.1 @10.53.0.2 -p 5300 > dig.out.test$n grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi +if [ $ret != 0 ]; then echo "I: failed"; fi status=`expr $status + $ret` n=`expr $n + 1` -echo "I:checking that dom3.example is not accessible from 10.53.0.2 ($n)" +echo "I: checking that dom8.example is not accessible from 10.53.0.2 ($n)" ret=0 -$DIG soa dom3.example -b 10.53.0.2 @10.53.0.2 -p 5300 > dig.out.test$n +$DIG soa dom8.example -b 10.53.0.2 @10.53.0.2 -p 5300 > dig.out.test$n grep "status: REFUSED" dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi +if [ $ret != 0 ]; then echo "I: failed"; fi status=`expr $status + $ret` n=`expr $n + 1` -echo "I:checking that dom3.example is not AXFR accessible from 10.53.0.1 ($n)" +echo "I: checking that dom8.example is not AXFR accessible from 10.53.0.1 ($n)" ret=0 -$DIG axfr dom3.example -b 10.53.0.1 @10.53.0.2 -p 5300 > dig.out.test$n +$DIG axfr dom8.example -b 10.53.0.1 @10.53.0.2 -p 5300 > dig.out.test$n grep "Transfer failed." dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi +if [ $ret != 0 ]; then echo "I: failed"; fi status=`expr $status + $ret` n=`expr $n + 1` -echo "I:checking that dom3.example is AXFR accessible from 10.53.0.2 ($n)" +echo "I: checking that dom8.example is AXFR accessible from 10.53.0.2 ($n)" ret=0 -$DIG axfr dom3.example -b 10.53.0.2 @10.53.0.2 -p 5300 > dig.out.test$n +$DIG axfr dom8.example -b 10.53.0.2 @10.53.0.2 -p 5300 > dig.out.test$n grep -v "Transfer failed." dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi +if [ $ret != 0 ]; then echo "I: failed"; fi status=`expr $status + $ret` cur=`awk 'BEGIN {l=0} /^/ {l++} END { print l }' ns2/named.run` n=`expr $n + 1` -echo "I:Deleting global allow-query and allow-domain ACLs ($n)" +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 5300 @@ -525,7 +665,7 @@ $NSUPDATE -d <> nsupdate.out.test$n 2>&1 || ret=1 update delete allow-transfer.catalog1.example 3600 IN APL 1:10.53.0.2/32 send END -if [ $ret != 0 ]; then echo "I:failed"; fi +if [ $ret != 0 ]; then echo "I: failed"; fi status=`expr $status + $ret` ret=0 try=0 @@ -538,42 +678,982 @@ do } try=`expr $try + 1` done -if [ $ret != 0 ]; then echo "I:failed"; fi +if [ $ret != 0 ]; then echo "I: failed"; fi status=`expr $status + $ret` n=`expr $n + 1` -echo "I:checking that dom3.example is accessible from 10.53.0.1 ($n)" +echo "I: checking that dom8.example is accessible from 10.53.0.1 ($n)" ret=0 -$DIG soa dom3.example -b 10.53.0.1 @10.53.0.2 -p 5300 > dig.out.test$n +$DIG soa dom8.example -b 10.53.0.1 @10.53.0.2 -p 5300 > dig.out.test$n grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi +if [ $ret != 0 ]; then echo "I: failed"; fi status=`expr $status + $ret` n=`expr $n + 1` -echo "I:checking that dom3.example is accessible from 10.53.0.2 ($n)" +echo "I: checking that dom8.example is accessible from 10.53.0.2 ($n)" ret=0 -$DIG soa dom3.example -b 10.53.0.2 @10.53.0.2 -p 5300 > dig.out.test$n +$DIG soa dom8.example -b 10.53.0.2 @10.53.0.2 -p 5300 > dig.out.test$n grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi +if [ $ret != 0 ]; then echo "I: failed"; fi status=`expr $status + $ret` n=`expr $n + 1` -echo "I:checking that dom3.example is AXFR accessible from 10.53.0.1 ($n)" +echo "I: checking that dom8.example is AXFR accessible from 10.53.0.1 ($n)" ret=0 -$DIG axfr dom3.example -b 10.53.0.1 @10.53.0.2 -p 5300 > dig.out.test$n +$DIG axfr dom8.example -b 10.53.0.1 @10.53.0.2 -p 5300 > dig.out.test$n grep -v "Transfer failed." dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi +if [ $ret != 0 ]; then echo "I: failed"; fi status=`expr $status + $ret` n=`expr $n + 1` -echo "I:checking that dom3.example is AXFR accessible from 10.53.0.2 ($n)" +echo "I: checking that dom8.example is AXFR accessible from 10.53.0.2 ($n)" ret=0 -$DIG axfr dom3.example -b 10.53.0.2 @10.53.0.2 -p 5300 > dig.out.test$n +$DIG axfr dom8.example -b 10.53.0.2 @10.53.0.2 -p 5300 > dig.out.test$n grep -v "Transfer failed." dig.out.test$n > /dev/null || ret=1 -if [ $ret != 0 ]; then echo "I:failed"; fi +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + + +########################################################################## +echo "I:Testing TSIG keys for masters set per-domain" +n=`expr $n + 1` +echo "I: adding a domain dom9.example to master via RNDC, with transfers allowed only with TSIG key ($n)" +ret=0 +echo "@ 3600 IN SOA . . 1 3600 3600 3600 3600" > ns1/dom9.example.db +echo "@ IN NS invalid." >> ns1/dom9.example.db +$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 addzone dom9.example '{type master; file "dom9.example.db"; allow-transfer { key tsig_key; }; };' || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: checking that dom9.example is now served by master ($n)" +ret=0 +$DIG soa dom9.example @10.53.0.1 -p 5300 > dig.out.test$n +grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +cur=`awk 'BEGIN {l=0} /^/ {l++} END { print l }' ns2/named.run` + +n=`expr $n + 1` +echo "I: adding domain dom9.example to catalog1 zone with masters and tsig key($n)" +ret=0 +$NSUPDATE -d <> nsupdate.out.test$n 2>&1 || ret=1 + server 10.53.0.1 5300 + update add f0f989bc71c5c8ca3a1eb9c9ab5246521907e3af.zones.catalog1.example 3600 IN PTR dom9.example. + update add label1.masters.f0f989bc71c5c8ca3a1eb9c9ab5246521907e3af.zones.catalog1.example 3600 IN A 10.53.0.1 + update add label1.masters.f0f989bc71c5c8ca3a1eb9c9ab5246521907e3af.zones.catalog1.example 3600 IN TXT "tsig_key" + send +END +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: waiting for slave to sync up ($n)" +ret=1 +try=0 +while test $try -lt 45 +do + sleep 1 + sed -n "$cur,"'$p' < ns2/named.run | grep "catz: adding zone 'dom9.example' from catalog 'catalog1.example'" > /dev/null && { + ret=0 + break + } + try=`expr $try + 1` +done +try=0 +while test $try -lt 45 +do + sleep 1 + sed -n "$cur,"'$p' < ns2/named.run | grep "transfer of 'dom9.example/IN' from 10.53.0.1#5300: Transfer status: success" > /dev/null && { + ret=0 + break + } + try=`expr $try + 1` +done +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: checking that dom9.example is accessible on slave ($n)" +ret=0 +$DIG soa dom9.example @10.53.0.2 -p 5300 > dig.out.test$n +grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: deleting domain dom9.example from catalog1 zone($n)" +ret=0 +$NSUPDATE -d <> nsupdate.out.test$n 2>&1 || ret=1 + server 10.53.0.1 5300 + update delete f0f989bc71c5c8ca3a1eb9c9ab5246521907e3af.zones.catalog1.example 3600 IN PTR dom9.example. + update delete label1.masters.f0f989bc71c5c8ca3a1eb9c9ab5246521907e3af.zones.catalog1.example 3600 IN A 10.53.0.1 + update delete label1.masters.f0f989bc71c5c8ca3a1eb9c9ab5246521907e3af.zones.catalog1.example 3600 IN TXT "tsig_key" + send +END +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: waiting for slave to sync up ($n)" +ret=1 +try=0 +while test $try -lt 45 +do + sleep 1 + sed -n "$cur,"'$p' < ns2/named.run | grep "catz: deleting zone 'dom9.example' from catalog 'catalog1.example'" > /dev/null && { + ret=0 + break + } + try=`expr $try + 1` +done +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: checking that dom9.example is no longer accessible on slave ($n)" +ret=0 +$DIG soa dom9.example @10.53.0.2 -p 5300 > dig.out.test$n +grep "status: REFUSED" dig.out.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +########################################################################## +echo "I:Testing very long domain in catalog" +n=`expr $n + 1` +echo "I: checking that this.is.a.very.very.long.long.long.domain.that.will.cause.catalog.zones.to.generate.hash.instead.of.using.regular.filename.dom10.example is not served by master ($n)" +ret=0 +$DIG soa this.is.a.very.very.long.long.long.domain.that.will.cause.catalog.zones.to.generate.hash.instead.of.using.regular.filename.dom10.example @10.53.0.1 -p 5300 > dig.out.test$n +grep "status: REFUSED" dig.out.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: Adding a domain this.is.a.very.very.long.long.long.domain.that.will.cause.catalog.zones.to.generate.hash.instead.of.using.regular.filename.dom10.example to master via RNDC ($n)" +ret=0 +echo "@ 3600 IN SOA . . 1 3600 3600 3600 3600" > ns1/dom10.example.db +echo "@ IN NS invalid." >> ns1/dom10.example.db +$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 addzone this.is.a.very.very.long.long.long.domain.that.will.cause.catalog.zones.to.generate.hash.instead.of.using.regular.filename.dom10.example '{type master; file "dom10.example.db";};' || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: checking that this.is.a.very.very.long.long.long.domain.that.will.cause.catalog.zones.to.generate.hash.instead.of.using.regular.filename.dom10.example is now served by master ($n)" +ret=0 +$DIG soa this.is.a.very.very.long.long.long.domain.that.will.cause.catalog.zones.to.generate.hash.instead.of.using.regular.filename.dom10.example @10.53.0.1 -p 5300 > dig.out.test$n +grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +cur=`awk 'BEGIN {l=0} /^/ {l++} END { print l }' ns2/named.run` + +n=`expr $n + 1` +echo "I: Adding domain this.is.a.very.very.long.long.long.domain.that.will.cause.catalog.zones.to.generate.hash.instead.of.using.regular.filename.dom10.example to catalog1 zone ($n)" +ret=0 +$NSUPDATE -d <> nsupdate.out.test$n 2>&1 || ret=1 + server 10.53.0.1 5300 + update add 825f48b1ce1b4cf5a041d20255a0c8e98d114858.zones.catalog1.example 3600 IN PTR this.is.a.very.very.long.long.long.domain.that.will.cause.catalog.zones.to.generate.hash.instead.of.using.regular.filename.dom10.example. + send +END +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: waiting for slave to sync up ($n)" +ret=1 +try=0 +while test $try -lt 45 +do + sleep 1 + sed -n "$cur,"'$p' < ns2/named.run | grep "catz: adding zone 'this.is.a.very.very.long.long.long.domain.that.will.cause.catalog.zones.to.generate.hash.instead.of.using.regular.filename.dom10.example' from catalog 'catalog1.example'" > /dev/null && { + ret=0 + break + } + try=`expr $try + 1` +done +try=0 +while test $try -lt 45 +do + sleep 1 + sed -n "$cur,"'$p' < ns2/named.run | grep "transfer of 'this.is.a.very.very.long.long.long.domain.that.will.cause.catalog.zones.to.generate.hash.instead.of.using.regular.filename.dom10.example/IN' from 10.53.0.1#5300: Transfer status: success" > /dev/null && { + ret=0 + break + } + try=`expr $try + 1` +done +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: checking that this.is.a.very.very.long.long.long.domain.that.will.cause.catalog.zones.to.generate.hash.instead.of.using.regular.filename.dom10.example is served by slave ($n)" +ret=0 +$DIG soa this.is.a.very.very.long.long.long.domain.that.will.cause.catalog.zones.to.generate.hash.instead.of.using.regular.filename.dom10.example @10.53.0.2 -p 5300 > dig.out.test$n +grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: checking that zone-directory is populated with a hashed filename($n)" +ret=0 +[ -f "ns2/zonedir/__catz__4d70696f2335687069467f11f5d5378c480383f97782e553fb2d04a7bb2a23ed.db" ] || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: removing domain this.is.a.very.very.long.long.long.domain.that.will.cause.catalog.zones.to.generate.hash.instead.of.using.regular.filename.dom10.example from catalog1 zone ($n)" +ret=0 +$NSUPDATE -d <> nsupdate.out.test$n 2>&1 || ret=1 + server 10.53.0.1 5300 + update delete 825f48b1ce1b4cf5a041d20255a0c8e98d114858.zones.catalog1.example + send +END +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: waiting for slave to sync up ($n)" +ret=1 +try=0 +while test $try -lt 45 +do + sleep 1 + sed -n "$cur,"'$p' < ns2/named.run | grep "catz: deleting zone 'this.is.a.very.very.long.long.long.domain.that.will.cause.catalog.zones.to.generate.hash.instead.of.using.regular.filename.dom10.example' from catalog 'catalog1.example'" > /dev/null && { + ret=0 + break + } + try=`expr $try + 1` +done +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: checking that this.is.a.very.very.long.long.long.domain.that.will.cause.catalog.zones.to.generate.hash.instead.of.using.regular.filename.dom10.example is not served by slave ($n)" +ret=0 +$DIG soa this.is.a.very.very.long.long.long.domain.that.will.cause.catalog.zones.to.generate.hash.instead.of.using.regular.filename.dom10.example @10.53.0.2 -p 5300 > dig.out.test$n +grep "status: REFUSED" dig.out.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi status=`expr $status + $ret` +n=`expr $n + 1` +echo "I: checking that zone-directory is emptied ($n)" +ret=0 +[ -f "ns2/zonedir/__catz__4d70696f2335687069467f11f5d5378c480383f97782e553fb2d04a7bb2a23ed.db" ] && ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` +########################################################################## +echo "I:Testing adding a domain and a subdomain of it" +n=`expr $n + 1` +echo "I: checking that dom11.example is not served by master ($n)" +ret=0 +$DIG soa dom11.example @10.53.0.1 -p 5300 > dig.out.test$n +grep "status: REFUSED" dig.out.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: Adding a domain dom11.example to master via RNDC ($n)" +ret=0 +echo "@ 3600 IN SOA . . 1 3600 3600 3600 3600" > ns1/dom11.example.db +echo "@ IN NS invalid." >> ns1/dom11.example.db +$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 addzone dom11.example '{type master; file "dom11.example.db";};' || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: checking that dom11.example is now served by master ($n)" +ret=0 +$DIG soa dom11.example @10.53.0.1 -p 5300 > dig.out.test$n +grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +cur=`awk 'BEGIN {l=0} /^/ {l++} END { print l }' ns2/named.run` + +n=`expr $n + 1` +echo "I: Adding domain dom11.example to catalog1 zone ($n)" +ret=0 +$NSUPDATE -d <> nsupdate.out.test$n 2>&1 || ret=1 + server 10.53.0.1 5300 + update add 0580d70e769c86c8b951a488d8b776627f427d7a.zones.catalog1.example 3600 IN PTR dom11.example. + send +END +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: waiting for slave to sync up ($n)" +ret=1 +try=0 +while test $try -lt 45 +do + sleep 1 + sed -n "$cur,"'$p' < ns2/named.run | grep "catz: adding zone 'dom11.example' from catalog 'catalog1.example'" > /dev/null && { + ret=0 + break + } + try=`expr $try + 1` +done +try=0 +while test $try -lt 45 +do + sleep 1 + sed -n "$cur,"'$p' < ns2/named.run | grep "transfer of 'dom11.example/IN' from 10.53.0.1#5300: Transfer status: success" > /dev/null && { + ret=0 + break + } + try=`expr $try + 1` +done +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: checking that dom11.example is served by slave ($n)" +ret=0 +$DIG soa dom11.example @10.53.0.2 -p 5300 > dig.out.test$n +grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: checking that subdomain.of.dom11.example is not served by master ($n)" +ret=0 +$DIG soa subdomain.of.dom11.example @10.53.0.1 -p 5300 > dig.out.test$n +grep "status: NXDOMAIN" dig.out.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: Adding a domain subdomain.of.dom11.example to master via RNDC ($n)" +ret=0 +echo "@ 3600 IN SOA . . 1 3600 3600 3600 3600" > ns1/subdomain.of.dom11.example.db +echo "@ IN NS invalid." >> ns1/subdomain.of.dom11.example.db +$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 addzone subdomain.of.dom11.example '{type master; file "subdomain.of.dom11.example.db";};' || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: checking that subdomain.of.dom11.example is now served by master ($n)" +ret=0 +$DIG soa subdomain.of.dom11.example @10.53.0.1 -p 5300 > dig.out.test$n +grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +cur=`awk 'BEGIN {l=0} /^/ {l++} END { print l }' ns2/named.run` + +n=`expr $n + 1` +echo "I: Adding domain subdomain.of.dom11.example to catalog1 zone ($n)" +ret=0 +$NSUPDATE -d <> nsupdate.out.test$n 2>&1 || ret=1 + server 10.53.0.1 5300 + update add 25557e0bdd10cb3710199bb421b776df160f241e.zones.catalog1.example 3600 IN PTR subdomain.of.dom11.example. + send +END +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: waiting for slave to sync up ($n)" +ret=1 +try=0 +while test $try -lt 45 +do + sleep 1 + sed -n "$cur,"'$p' < ns2/named.run | grep "catz: adding zone 'subdomain.of.dom11.example' from catalog 'catalog1.example'" > /dev/null && { + ret=0 + break + } + try=`expr $try + 1` +done +try=0 +while test $try -lt 45 +do + sleep 1 + sed -n "$cur,"'$p' < ns2/named.run | grep "transfer of 'subdomain.of.dom11.example/IN' from 10.53.0.1#5300: Transfer status: success" > /dev/null && { + ret=0 + break + } + try=`expr $try + 1` +done +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: checking that subdomain.of.dom11.example is served by slave ($n)" +ret=0 +$DIG soa subdomain.of.dom11.example @10.53.0.2 -p 5300 > dig.out.test$n +grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + + + +n=`expr $n + 1` +echo "I: removing domain dom11.example from catalog1 zone ($n)" +ret=0 +$NSUPDATE -d <> nsupdate.out.test$n 2>&1 || ret=1 + server 10.53.0.1 5300 + update delete 0580d70e769c86c8b951a488d8b776627f427d7a.zones.catalog1.example + send +END +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: waiting for slave to sync up ($n)" +ret=1 +try=0 +while test $try -lt 45 +do + sleep 1 + sed -n "$cur,"'$p' < ns2/named.run | grep "catz: deleting zone 'dom11.example' from catalog 'catalog1.example'" > /dev/null && { + ret=0 + break + } + try=`expr $try + 1` +done +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: checking that dom11.example is not served by slave ($n)" +ret=0 +$DIG soa dom11.example @10.53.0.2 -p 5300 > dig.out.test$n +grep "status: REFUSED" dig.out.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: checking that subdomain.of.dom11.example is still served by slave ($n)" +ret=0 +$DIG soa subdomain.of.dom11.example @10.53.0.2 -p 5300 > dig.out.test$n +grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: removing domain subdomain.of.dom11.example from catalog1 zone ($n)" +ret=0 +$NSUPDATE -d <> nsupdate.out.test$n 2>&1 || ret=1 + server 10.53.0.1 5300 + update delete 25557e0bdd10cb3710199bb421b776df160f241e.zones.catalog1.example + send +END +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: waiting for slave to sync up ($n)" +ret=1 +try=0 +while test $try -lt 45 +do + sleep 1 + sed -n "$cur,"'$p' < ns2/named.run | grep "catz: deleting zone 'subdomain.of.dom11.example' from catalog 'catalog1.example'" > /dev/null && { + ret=0 + break + } + try=`expr $try + 1` +done +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: checking that subdomain.of.dom11.example is not served by slave ($n)" +ret=0 +$DIG soa subdomain.of.dom11.example @10.53.0.2 -p 5300 > dig.out.test$n +grep "status: REFUSED" dig.out.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + + +########################################################################## +echo "I:Testing adding a catalog zone at runtime with rndc reconfig" +n=`expr $n + 1` +echo "I: checking that dom12.example is not served by master ($n)" +ret=0 +$DIG soa dom12.example @10.53.0.1 -p 5300 > dig.out.test$n +grep "status: REFUSED" dig.out.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: Adding a domain dom12.example to master via RNDC ($n)" +ret=0 +echo "@ 3600 IN SOA . . 1 3600 3600 3600 3600" > ns1/dom12.example.db +echo "@ IN NS invalid." >> ns1/dom12.example.db +$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 addzone dom12.example '{type master; file "dom12.example.db";};' || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: checking that dom12.example is now served by master ($n)" +ret=0 +$DIG soa dom12.example @10.53.0.1 -p 5300 > dig.out.test$n +grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +cur=`awk 'BEGIN {l=0} /^/ {l++} END { print l }' ns2/named.run` + +n=`expr $n + 1` +echo "I: Adding domain dom12.example to catalog4 zone ($n)" +ret=0 +$NSUPDATE -d <> nsupdate.out.test$n 2>&1 || ret=1 + server 10.53.0.1 5300 + update add 871d51e5433543c0f6fb263c40f359fbc152c8ae.zones.catalog4.example 3600 IN PTR dom12.example. + send +END +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: checking that dom12.example is not served by slave ($n)" +ret=0 +$DIG soa dom12.example @10.53.0.2 -p 5300 > dig.out.test$n +grep "status: REFUSED" dig.out.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + + +n=`expr $n + 1` +echo "I: reconfiguring slave - adding catalog4 catalog zone ($n)" +ret=0 +cat ns2/named.conf.in |sed -e "s/^#T1//g" > ns2/named.conf +$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 reconfig || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: waiting for slave to sync up ($n)" +ret=1 +try=0 +while test $try -lt 45 +do + sleep 1 + sed -n "$cur,"'$p' < ns2/named.run | grep "catz: adding zone 'dom12.example' from catalog 'catalog4.example'" > /dev/null && { + ret=0 + break + } + try=`expr $try + 1` +done +try=0 +while test $try -lt 45 +do + sleep 1 + sed -n "$cur,"'$p' < ns2/named.run | grep "transfer of 'dom12.example/IN' from 10.53.0.1#5300: Transfer status: success" > /dev/null && { + ret=0 + break + } + try=`expr $try + 1` +done +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: checking that dom12.example is served by slave ($n)" +ret=0 +$DIG soa dom12.example @10.53.0.2 -p 5300 > dig.out.test$n +grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: reconfiguring slave - removing catalog4 catalog zone ($n)" +ret=0 +cat ns2/named.conf.in > ns2/named.conf +$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 reconfig || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: checking that dom12.example is not served by slave ($n)" +ret=0 +$DIG soa dom12.example @10.53.0.2 -p 5300 > dig.out.test$n +grep "status: REFUSED" dig.out.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: removing domain dom12.example from catalog4 zone ($n)" +ret=0 +$NSUPDATE -d <> nsupdate.out.test$n 2>&1 || ret=1 + server 10.53.0.1 5300 + update delete 871d51e5433543c0f6fb263c40f359fbc152c8ae.zones.catalog4.example 3600 IN PTR dom12.example. + send +END +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +########################################################################## +echo "I:Testing having a zone in two different catalogs" +n=`expr $n + 1` +echo "I: checking that dom13.example is not served by master ($n)" +ret=0 +$DIG soa dom13.example @10.53.0.1 -p 5300 > dig.out.test$n +grep "status: REFUSED" dig.out.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: Adding a domain dom13.example to master ns1 via RNDC ($n)" +ret=0 +echo "@ 3600 IN SOA . . 1 3600 3600 3600 3600" > ns1/dom13.example.db +echo "@ IN NS invalid." >> ns1/dom13.example.db +echo "@ IN A 192.0.2.1" >> ns1/dom13.example.db +$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 addzone dom13.example '{type master; file "dom13.example.db";};' || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: checking that dom13.example is now served by master ns1 ($n)" +ret=0 +$DIG soa dom13.example @10.53.0.1 -p 5300 > dig.out.test$n +grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: Adding a domain dom13.example to master ns3 via RNDC ($n)" +ret=0 +echo "@ 3600 IN SOA . . 1 3600 3600 3600 3600" > ns3/dom13.example.db +echo "@ IN NS invalid." >> ns3/dom13.example.db +echo "@ IN A 192.0.2.2" >> ns3/dom13.example.db +$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 addzone dom13.example '{type master; file "dom13.example.db";};' || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: checking that dom13.example is now served by master ns3 ($n)" +ret=0 +$DIG soa dom13.example @10.53.0.3 -p 5300 > dig.out.test$n +grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + + +cur=`awk 'BEGIN {l=0} /^/ {l++} END { print l }' ns2/named.run` + +n=`expr $n + 1` +echo "I: Adding domain dom13.example to catalog1 zone with ns1 as master($n)" +ret=0 +$NSUPDATE -d <> nsupdate.out.test$n 2>&1 || ret=1 + server 10.53.0.1 5300 + update add 8d7989c746b3f92b3bba2479e72afd977198363f.zones.catalog1.example 3600 IN PTR dom13.example. + update add masters.8d7989c746b3f92b3bba2479e72afd977198363f.zones.catalog1.example 3600 IN A 10.53.0.1 + send +END +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: waiting for slave to sync up ($n)" +ret=1 +try=0 +while test $try -lt 45 +do + sleep 1 + sed -n "$cur,"'$p' < ns2/named.run | grep "catz: adding zone 'dom13.example' from catalog 'catalog1.example'" > /dev/null && { + ret=0 + break + } + try=`expr $try + 1` +done +try=0 +while test $try -lt 45 +do + sleep 1 + sed -n "$cur,"'$p' < ns2/named.run | grep "transfer of 'dom13.example/IN' from 10.53.0.1#5300: Transfer status: success" > /dev/null && { + ret=0 + break + } + try=`expr $try + 1` +done +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +cur=`awk 'BEGIN {l=0} /^/ {l++} END { print l }' ns2/named.run` + +n=`expr $n + 1` +echo "I: checking that dom13.example is served by slave and that it's the one from ns1 ($n)" +ret=0 +$DIG a dom13.example @10.53.0.2 -p 5300 > dig.out.test$n +grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1 +grep "192.0.2.1" dig.out.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: Adding domain dom13.example to catalog2 zone with ns3 as master($n)" +ret=0 +$NSUPDATE -d <> nsupdate.out.test$n 2>&1 || ret=1 + server 10.53.0.3 5300 + update add 8d7989c746b3f92b3bba2479e72afd977198363f.zones.catalog2.example 3600 IN PTR dom13.example. + update add masters.8d7989c746b3f92b3bba2479e72afd977198363f.zones.catalog2.example 3600 IN A 10.53.0.3 + send +END +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: waiting for slave to sync up ($n)" +ret=1 +try=0 +while test $try -lt 45 +do + sleep 1 + sed -n "$cur,"'$p' < ns2/named.run | grep "catz: update_from_db: new zone merged" > /dev/null && { + ret=0 + break + } + try=`expr $try + 1` +done +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: checking that dom13.example is served by slave and that it's still the one from ns1 ($n)" +ret=0 +$DIG a dom13.example @10.53.0.2 -p 5300 > dig.out.test$n +grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1 +grep "192.0.2.1" dig.out.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +cur=`awk 'BEGIN {l=0} /^/ {l++} END { print l }' ns2/named.run` + +n=`expr $n + 1` +echo "I: Deleting domain dom13.example from catalog2 ($n)" +ret=0 +$NSUPDATE -d <> nsupdate.out.test$n 2>&1 || ret=1 + server 10.53.0.3 5300 + update delete 8d7989c746b3f92b3bba2479e72afd977198363f.zones.catalog2.example 3600 IN PTR dom13.example. + update delete masters.8d7989c746b3f92b3bba2479e72afd977198363f.zones.catalog2.example 3600 IN A 10.53.0.3 + send +END +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: waiting for slave to sync up ($n)" +ret=1 +try=0 +while test $try -lt 45 +do + sleep 1 + sed -n "$cur,"'$p' < ns2/named.run | grep "catz: update_from_db: new zone merged" > /dev/null && { + ret=0 + break + } + try=`expr $try + 1` +done +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: checking that dom13.example is served by slave and that it's still the one from ns1 ($n)" +ret=0 +$DIG a dom13.example @10.53.0.2 -p 5300 > dig.out.test$n +grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1 +grep "192.0.2.1" dig.out.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: Deleting domain dom13.example from catalog1 ($n)" +ret=0 +$NSUPDATE -d <> nsupdate.out.test$n 2>&1 || ret=1 + server 10.53.0.1 5300 + update delete 8d7989c746b3f92b3bba2479e72afd977198363f.zones.catalog1.example 3600 IN PTR dom13.example. + update delete masters.8d7989c746b3f92b3bba2479e72afd977198363f.zones.catalog1.example 3600 IN A 10.53.0.2 + send +END +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: waiting for slave to sync up ($n)" +ret=1 +try=0 +while test $try -lt 45 +do + sleep 1 + sed -n "$cur,"'$p' < ns2/named.run | grep "catz: update_from_db: new zone merged" > /dev/null && { + ret=0 + break + } + try=`expr $try + 1` +done +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: checking that dom13.example is no longer served by slave ($n)" +ret=0 +$DIG a dom13.example @10.53.0.2 -p 5300 > dig.out.test$n +grep "status: REFUSED" dig.out.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +########################################################################## +echo "I:Testing having a regular zone and a zone in catalog zone of the same name" +n=`expr $n + 1` +echo "I: checking that dom14.example is not served by master ($n)" +ret=0 +$DIG soa dom14.example @10.53.0.1 -p 5300 > dig.out.test$n +grep "status: REFUSED" dig.out.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: Adding a domain dom14.example to master ns1 via RNDC ($n)" +ret=0 +echo "@ 3600 IN SOA . . 1 3600 3600 3600 3600" > ns1/dom14.example.db +echo "@ IN NS invalid." >> ns1/dom14.example.db +echo "@ IN A 192.0.2.1" >> ns1/dom14.example.db +$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 addzone dom14.example '{type master; file "dom14.example.db";};' || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: checking that dom14.example is now served by master ns1 ($n)" +ret=0 +$DIG soa dom14.example @10.53.0.1 -p 5300 > dig.out.test$n +grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: Adding a domain dom14.example to master ns3 via RNDC ($n)" +ret=0 +echo "@ 3600 IN SOA . . 1 3600 3600 3600 3600" > ns3/dom14.example.db +echo "@ IN NS invalid." >> ns3/dom14.example.db +echo "@ IN A 192.0.2.2" >> ns3/dom14.example.db +$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 addzone dom14.example '{type master; file "dom14.example.db";};' || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: checking that dom14.example is now served by master ns3 ($n)" +ret=0 +$DIG soa dom14.example @10.53.0.3 -p 5300 > dig.out.test$n +grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +cur=`awk 'BEGIN {l=0} /^/ {l++} END { print l }' ns2/named.run` + +n=`expr $n + 1` +echo "I: Adding domain dom14.example with rndc with ns1 as master($n)" +ret=0 +$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 addzone dom14.example '{type slave; masters {10.53.0.1;};};' || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: waiting for slave to sync up ($n)" +ret=1 +try=0 +while test $try -lt 45 +do + sleep 1 + sed -n "$cur,"'$p' < ns2/named.run | grep "transfer of 'dom14.example/IN' from 10.53.0.1#5300: Transfer status: success" > /dev/null && { + ret=0 + break + } + try=`expr $try + 1` +done +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +cur=`awk 'BEGIN {l=0} /^/ {l++} END { print l }' ns2/named.run` + +n=`expr $n + 1` +echo "I: checking that dom14.example is served by slave and that it's the one from ns1 ($n)" +ret=0 +$DIG a dom14.example @10.53.0.2 -p 5300 > dig.out.test$n +grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1 +grep "192.0.2.1" dig.out.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: Adding domain dom14.example to catalog2 zone with ns3 as master($n)" +ret=0 +$NSUPDATE -d <> nsupdate.out.test$n 2>&1 || ret=1 + server 10.53.0.3 5300 + update add 45e3d45ea5f7bd01c395ccbde6ae2e750a3ee8ab.zones.catalog2.example 3600 IN PTR dom14.example. + update add masters.45e3d45ea5f7bd01c395ccbde6ae2e750a3ee8ab.zones.catalog2.example 3600 IN A 10.53.0.3 + send +END +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: waiting for slave to sync up ($n)" +ret=1 +try=0 +while test $try -lt 45 +do + sleep 1 + sed -n "$cur,"'$p' < ns2/named.run | grep "catz: update_from_db: new zone merged" > /dev/null && { + ret=0 + break + } + try=`expr $try + 1` +done +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: checking that dom14.example is served by slave and that it's still the one from ns1 ($n)" +ret=0 +$DIG a dom14.example @10.53.0.2 -p 5300 > dig.out.test$n +grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1 +grep "192.0.2.1" dig.out.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +cur=`awk 'BEGIN {l=0} /^/ {l++} END { print l }' ns2/named.run` + +n=`expr $n + 1` +echo "I: Deleting domain dom14.example from catalog2 ($n)" +ret=0 +$NSUPDATE -d <> nsupdate.out.test$n 2>&1 || ret=1 + server 10.53.0.3 5300 + update delete 45e3d45ea5f7bd01c395ccbde6ae2e750a3ee8ab.zones.catalog2.example 3600 IN PTR dom14.example. + update delete masters.45e3d45ea5f7bd01c395ccbde6ae2e750a3ee8ab.zones.catalog2.example 3600 IN A 10.53.0.3 + send +END +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: waiting for slave to sync up ($n)" +ret=1 +try=0 +while test $try -lt 45 +do + sleep 1 + sed -n "$cur,"'$p' < ns2/named.run | grep "catz: update_from_db: new zone merged" > /dev/null && { + ret=0 + break + } + try=`expr $try + 1` +done +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: checking that dom14.example is served by slave and that it's still the one from ns1 ($n)" +ret=0 +$DIG a dom14.example @10.53.0.2 -p 5300 > dig.out.test$n +grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1 +grep "192.0.2.1" dig.out.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo "I: failed"; fi +status=`expr $status + $ret` echo "I:exit status: $status" [ $status -eq 0 ] || exit 1 diff --git a/lib/dns/catz.c b/lib/dns/catz.c index fc97c7fe178..e1ba568c724 100644 --- a/lib/dns/catz.c +++ b/lib/dns/catz.c @@ -68,10 +68,18 @@ struct dns_catz_zone { isc_event_t updateevent; isc_boolean_t active; + isc_boolean_t db_registered; isc_refcount_t refs; }; +static isc_result_t +catz_process_zones_entry(dns_catz_zone_t *zone, dns_rdataset_t *value, + dns_label_t *mhash); +static isc_result_t +catz_process_zones_suboption(dns_catz_zone_t *zone, dns_rdataset_t *value, + dns_label_t *mhash, dns_name_t *name); + /*% * Collection of catalog zones for a view */ @@ -89,10 +97,10 @@ struct dns_catz_zones { void dns_catz_options_init(dns_catz_options_t *options) { - options->masters.addrs = NULL; - options->masters.dscps = NULL; - options->masters.keys = NULL; - options->masters.count = 0; + dns_ipkeylist_init(&options->masters); + + options->allow_query = NULL; + options->allow_transfer = NULL; options->allow_query = NULL; options->allow_transfer = NULL; @@ -120,7 +128,6 @@ isc_result_t dns_catz_options_copy(isc_mem_t *mctx, const dns_catz_options_t *src, dns_catz_options_t *dst) { - /* TODO error handling */ REQUIRE(dst != NULL); REQUIRE(dst->masters.count == 0); REQUIRE(dst->allow_query == NULL); @@ -143,7 +150,6 @@ dns_catz_options_copy(isc_mem_t *mctx, const dns_catz_options_t *src, if (src->allow_transfer != NULL) isc_buffer_dup(mctx, &dst->allow_transfer, src->allow_transfer); - return (ISC_R_SUCCESS); } @@ -176,16 +182,17 @@ dns_catz_entry_new(isc_mem_t *mctx, const dns_name_t *domain, isc_result_t result; REQUIRE(nentryp != NULL && *nentryp == NULL); - REQUIRE(domain != NULL); nentry = isc_mem_get(mctx, sizeof(dns_catz_entry_t)); if (nentry == NULL) return (ISC_R_NOMEMORY); dns_name_init(&nentry->name, NULL); - result = dns_name_dup(domain, mctx, &nentry->name); - if (result != ISC_R_SUCCESS) - goto cleanup; + if (domain != NULL) { + result = dns_name_dup(domain, mctx, &nentry->name); + if (result != ISC_R_SUCCESS) + goto cleanup; + } dns_catz_options_init(&nentry->opts); isc_refcount_init(&nentry->refs, 1); @@ -245,7 +252,8 @@ dns_catz_entry_detach(dns_catz_zone_t *zone, dns_catz_entry_t **entryp) { isc_refcount_decrement(&entry->refs, &refs); if (refs == 0) { dns_catz_options_free(&entry->opts, mctx); - dns_name_free(&entry->name, mctx); + if (dns_name_dynamic(&entry->name)) + dns_name_free(&entry->name, mctx); isc_refcount_destroy(&entry->refs); isc_mem_put(mctx, entry, sizeof(dns_catz_entry_t)); } @@ -261,6 +269,10 @@ dns_catz_entry_validate(const dns_catz_entry_t *entry) { isc_boolean_t dns_catz_entry_cmp(const dns_catz_entry_t *ea, const dns_catz_entry_t *eb) { isc_region_t ra, rb; + + if (ea == eb) + return (ISC_TRUE); + if (ea->opts.masters.count != eb->opts.masters.count) return (ISC_FALSE); @@ -269,8 +281,7 @@ dns_catz_entry_cmp(const dns_catz_entry_t *ea, const dns_catz_entry_t *eb) { return (ISC_FALSE); /* If one is NULL and the other isn't, the entries don't match */ - if ((ea->opts.allow_query == NULL) != - (eb->opts.allow_query == NULL)) + if ((ea->opts.allow_query == NULL) != (eb->opts.allow_query == NULL)) return (ISC_FALSE); /* If one is non-NULL, then they both are */ @@ -322,12 +333,11 @@ dns_catz_zone_resetdefoptions(dns_catz_zone_t *zone) { isc_result_t dns_catz_zones_merge(dns_catz_zone_t *target, dns_catz_zone_t *newzone) { isc_result_t result; - isc_ht_iter_t *iter = NULL; - char cznamebuf[DNS_NAME_FORMATSIZE]; - char znamebuf[DNS_NAME_FORMATSIZE]; - isc_buffer_t czname; - isc_buffer_t zname; + isc_ht_iter_t *iter1 = NULL, *iter2 = NULL; + char czname[DNS_NAME_FORMATSIZE]; + char zname[DNS_NAME_FORMATSIZE]; dns_catz_zoneop_fn_t addzone, modzone, delzone; + REQUIRE(target != NULL); REQUIRE(newzone != NULL); @@ -345,35 +355,47 @@ dns_catz_zones_merge(dns_catz_zone_t *target, dns_catz_zone_t *newzone) { dns_catz_options_setdefault(target->catzs->mctx, &target->defoptions, &target->zoneoptions); - isc_buffer_init(&czname, cznamebuf, DNS_NAME_FORMATSIZE); - isc_buffer_init(&zname, znamebuf, DNS_NAME_FORMATSIZE); - dns_name_totext(&target->name, ISC_TRUE, &czname); - isc_buffer_putuint8(&czname, 0); + dns_name_format(&target->name, czname, DNS_NAME_FORMATSIZE); + + result = isc_ht_iter_create(newzone->entries, &iter1); + if (result != ISC_R_SUCCESS) + return (result); + + result = isc_ht_iter_create(target->entries, &iter2); + if (result != ISC_R_SUCCESS) { + isc_ht_iter_destroy(&iter1); + return (result); + } /* - * first - walk the new zone and find all nodes that are not in the - * old zone, or are in both zones and are modified + * First - walk the new zone and find all nodes that are not in the + * old zone, or are in both zones and are modified. */ - result = isc_ht_iter_create(newzone->entries, &iter); - INSIST(result == ISC_R_SUCCESS); - - result = isc_ht_iter_first(iter); - for (result = isc_ht_iter_first(iter); + for (result = isc_ht_iter_first(iter1); result == ISC_R_SUCCESS; - result = isc_ht_iter_next(iter)) + result = isc_ht_iter_next(iter1)) { dns_catz_entry_t *nentry; dns_catz_entry_t *oentry; unsigned char * key; size_t keysize; - isc_ht_iter_current(iter, (void **) &nentry); - isc_ht_iter_currentkey(iter, &key, &keysize); + isc_ht_iter_current(iter1, (void **) &nentry); + isc_ht_iter_currentkey(iter1, &key, &keysize); - isc_buffer_clear(&zname); - dns_name_totext(&nentry->name, ISC_TRUE, &zname); - isc_buffer_putuint8(&zname, 0); + /* + * Spurious record that came from suboption without main + * record, ignored. + */ + if (dns_name_countlabels(&nentry->name) == 0) + continue; + + dns_name_format(&nentry->name, zname, DNS_NAME_FORMATSIZE); + isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, + DNS_LOGMODULE_MASTER, ISC_LOG_DEBUG(3), + "catz: iterating over '%s' from catalog '%s'", + zname, czname); dns_catz_options_setdefault(target->catzs->mctx, &target->zoneoptions, &nentry->opts); @@ -388,7 +410,7 @@ dns_catz_zones_merge(dns_catz_zone_t *target, dns_catz_zone_t *newzone) { DNS_LOGMODULE_MASTER, ISC_LOG_INFO, "catz: adding zone '%s' from catalog " "'%s' - %s", - znamebuf, cznamebuf, + zname, czname, isc_result_totext(result)); continue; } @@ -401,7 +423,7 @@ dns_catz_zones_merge(dns_catz_zone_t *target, dns_catz_zone_t *newzone) { DNS_LOGMODULE_MASTER, ISC_LOG_INFO, "catz: modifying zone '%s' from catalog " "'%s' - %s", - znamebuf, cznamebuf, + zname, czname, isc_result_totext(result)); } @@ -410,37 +432,32 @@ dns_catz_zones_merge(dns_catz_zone_t *target, dns_catz_zone_t *newzone) { RUNTIME_CHECK(result == ISC_R_SUCCESS); } RUNTIME_CHECK(result == ISC_R_NOMORE); - isc_ht_iter_destroy(&iter); + isc_ht_iter_destroy(&iter1); /* - * then - walk the old zone; only deleted entries should remain + * Then - walk the old zone; only deleted entries should remain. */ - result = isc_ht_iter_create(target->entries, &iter); - INSIST(result == ISC_R_SUCCESS); - - for (result = isc_ht_iter_first(iter); + for (result = isc_ht_iter_first(iter2); result == ISC_R_SUCCESS; - result = isc_ht_iter_delcurrent_next(iter)) + result = isc_ht_iter_delcurrent_next(iter2)) { dns_catz_entry_t *entry; - isc_ht_iter_current(iter, (void **) &entry); + isc_ht_iter_current(iter2, (void **) &entry); - isc_buffer_clear(&zname); - dns_name_totext(&entry->name, ISC_TRUE, &zname); - isc_buffer_putuint8(&zname, 0); + dns_name_format(&entry->name, zname, DNS_NAME_FORMATSIZE); result = delzone(entry, target, target->catzs->view, target->catzs->taskmgr, target->catzs->zmm->udata); isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_MASTER, ISC_LOG_INFO, "catz: deleting zone '%s' from catalog '%s' - %s", - znamebuf, cznamebuf, isc_result_totext(result)); + zname, czname, isc_result_totext(result)); dns_catz_entry_detach(target, &entry); } RUNTIME_CHECK(result == ISC_R_NOMORE); - isc_ht_iter_destroy(&iter); + isc_ht_iter_destroy(&iter2); - /* at this moment target->entries has to be be empty */ + /* At this moment target->entries has to be be empty. */ INSIST(isc_ht_count(target->entries) == 0); isc_ht_destroy(&target->entries); @@ -506,7 +523,7 @@ void dns_catz_catzs_set_view(dns_catz_zones_t *catzs, dns_view_t *view) { REQUIRE(catzs != NULL); REQUIRE(view != NULL); - /* either it's a new one or it's being reconfigured */ + /* Either it's a new one or it's being reconfigured. */ REQUIRE(catzs->view == NULL || !strcmp(catzs->view->name, view->name)); catzs->view = view; @@ -514,7 +531,8 @@ dns_catz_catzs_set_view(dns_catz_zones_t *catzs, dns_view_t *view) { isc_result_t dns_catz_new_zone(dns_catz_zones_t *catzs, dns_catz_zone_t **zonep, - const dns_name_t *name) { + const dns_name_t *name) +{ isc_result_t result; dns_catz_zone_t *new_zone; @@ -552,6 +570,7 @@ dns_catz_new_zone(dns_catz_zones_t *catzs, dns_catz_zone_t **zonep, dns_catz_options_init(&new_zone->defoptions); dns_catz_options_init(&new_zone->zoneoptions); new_zone->active = ISC_TRUE; + new_zone->db_registered = ISC_FALSE; new_zone->version = (isc_uint32_t)(-1); isc_refcount_init(&new_zone->refs, 1); @@ -575,10 +594,15 @@ dns_catz_add_zone(dns_catz_zones_t *catzs, const dns_name_t *name, { dns_catz_zone_t *new_zone = NULL; isc_result_t result; + char zname[DNS_NAME_FORMATSIZE]; REQUIRE(catzs != NULL); REQUIRE(name != NULL); REQUIRE(zonep != NULL && *zonep == NULL); + dns_name_format(name, zname, DNS_NAME_FORMATSIZE); + isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, + DNS_LOGMODULE_MASTER, ISC_LOG_DEBUG(3), + "catz: dns_catz_add_zone %s", zname); LOCK(&catzs->lock); @@ -633,12 +657,14 @@ dns_catz_catzs_attach(dns_catz_zones_t *catzs, dns_catz_zones_t **catzsp) { void dns_catz_zone_attach(dns_catz_zone_t *zone, dns_catz_zone_t **zonep) { REQUIRE(zonep != NULL && *zonep == NULL); + isc_refcount_increment(&zone->refs, NULL); *zonep = zone; } void dns_catz_zone_detach(dns_catz_zone_t **zonep) { + isc_result_t result; dns_catz_zone_t *zone; isc_ht_iter_t *iter = NULL; isc_mem_t *mctx; @@ -651,8 +677,6 @@ dns_catz_zone_detach(dns_catz_zone_t **zonep) { isc_refcount_decrement(&zone->refs, &refs); if (refs == 0) { if (zone->entries != NULL) { - isc_result_t result; - result = isc_ht_iter_create(zone->entries, &iter); INSIST(result == ISC_R_SUCCESS); for (result = isc_ht_iter_first(iter); @@ -660,22 +684,36 @@ dns_catz_zone_detach(dns_catz_zone_t **zonep) { result = isc_ht_iter_delcurrent_next(iter)) { dns_catz_entry_t *entry; + isc_ht_iter_current(iter, (void **) &entry); dns_catz_entry_detach(zone, &entry); } INSIST(result == ISC_R_NOMORE); isc_ht_iter_destroy(&iter); - /* the hashtable has to be empty now */ + /* The hashtable has to be empty now. */ INSIST(isc_ht_count(zone->entries) == 0); isc_ht_destroy(&zone->entries); } mctx = zone->catzs->mctx; isc_timer_detach(&zone->updatetimer); isc_refcount_destroy(&zone->refs); + if (zone->db_registered == ISC_TRUE) { + result = dns_db_updatenotify_unregister(zone->db, + dns_catz_dbupdate_callback, + zone->catzs); + INSIST(result == ISC_R_SUCCESS); + } + if (zone->dbversion) + dns_db_closeversion(zone->db, &zone->dbversion, + ISC_FALSE); + if (zone->db != NULL) + dns_db_detach(&zone->db); + dns_name_free(&zone->name, mctx); dns_catz_options_free(&zone->defoptions, mctx); dns_catz_options_free(&zone->zoneoptions, mctx); + zone->catzs = NULL; isc_mem_put(mctx, zone, sizeof(dns_catz_zone_t)); } @@ -703,10 +741,10 @@ dns_catz_catzs_detach(dns_catz_zones_t ** catzsp) { result = isc_ht_iter_create(catzs->zones, &iter); INSIST(result == ISC_R_SUCCESS); for (result = isc_ht_iter_first(iter); - result == ISC_R_SUCCESS; - result = isc_ht_iter_delcurrent_next(iter)) + result == ISC_R_SUCCESS;) { isc_ht_iter_current(iter, (void **) &zone); + result = isc_ht_iter_delcurrent_next(iter); dns_catz_zone_detach(&zone); } INSIST(result == ISC_R_NOMORE); @@ -756,80 +794,92 @@ catz_get_option(const dns_label_t *option) { } static isc_result_t -catz_process_global_list(dns_catz_zone_t *zone, catz_opt_t opt, - dns_rdataset_t *value, dns_label_t *mhash) +catz_process_zones(dns_catz_zone_t *zone, dns_rdataset_t *value, + dns_name_t *name) +{ + dns_label_t mhash; + dns_name_t opt; + + REQUIRE(zone != NULL); + REQUIRE(DNS_RDATASET_VALID(value)); + REQUIRE(name != NULL); + + if (value->rdclass != dns_rdataclass_in) + + if (name->labels == 0) + return (ISC_R_FAILURE); + + dns_name_getlabel(name, name->labels-1, &mhash); + + if (name->labels == 1) + return (catz_process_zones_entry(zone, value, &mhash)); + else { + dns_name_init(&opt, NULL); + dns_name_split(name, 1, &opt, NULL); + return (catz_process_zones_suboption(zone, value, &mhash, &opt)); + } +} + +static isc_result_t +catz_process_zones_entry(dns_catz_zone_t *zone, dns_rdataset_t *value, + dns_label_t *mhash) { isc_result_t result; dns_rdata_t rdata; dns_rdata_ptr_t ptr; dns_catz_entry_t *entry = NULL; - dns_name_t emptyname; - REQUIRE(zone != NULL); - REQUIRE(DNS_RDATASET_VALID(value)); - REQUIRE(mhash != NULL); - - dns_name_init(&emptyname, NULL); - switch (opt) { - case CATZ_OPT_ZONES: - if (value->rdclass != dns_rdataclass_in || - value->type != dns_rdatatype_ptr) { - break; - } + /* + * We only take -first- value, as mhash must be + * different. + */ + if (value->type != dns_rdatatype_ptr) + return (ISC_R_FAILURE); - /* - * We only take -first- value, as mhash must be - * different - */ - result = dns_rdataset_first(value); - if (result != ISC_R_SUCCESS) - break; + result = dns_rdataset_first(value); + if (result != ISC_R_SUCCESS) + return (ISC_R_FAILURE); - dns_rdata_init(&rdata); - dns_rdataset_current(value, &rdata); + dns_rdata_init(&rdata); + dns_rdataset_current(value, &rdata); - result = dns_rdata_tostruct(&rdata, &ptr, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); + result = dns_rdata_tostruct(&rdata, &ptr, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); - result = isc_ht_find(zone->entries, mhash->base, - mhash->length, (void **) &entry); - if (result == ISC_R_SUCCESS) { - if (dns_name_countlabels(&entry->name) != 0) { - /* we have a duplicate */ - dns_rdata_freestruct(&ptr); - return (ISC_R_FAILURE); - } else { - result = dns_name_dup(&ptr.ptr, - zone->catzs->mctx, - &entry->name); - if (result != ISC_R_SUCCESS) { - dns_rdata_freestruct(&ptr); - return (result); - } - } + result = isc_ht_find(zone->entries, mhash->base, + mhash->length, (void **) &entry); + if (result == ISC_R_SUCCESS) { + if (dns_name_countlabels(&entry->name) != 0) { + /* We have a duplicate. */ + dns_rdata_freestruct(&ptr); + return (ISC_R_FAILURE); } else { - result = dns_catz_entry_new(zone->catzs->mctx, &ptr.ptr, - &entry); + result = dns_name_dup(&ptr.ptr, zone->catzs->mctx, + &entry->name); if (result != ISC_R_SUCCESS) { dns_rdata_freestruct(&ptr); return (result); } - - result = isc_ht_add(zone->entries, mhash->base, - mhash->length, entry); - if (result != ISC_R_SUCCESS) { - dns_rdata_freestruct(&ptr); - dns_catz_entry_detach(zone, &entry); - return (result); - } + } + } else { + result = dns_catz_entry_new(zone->catzs->mctx, &ptr.ptr, + &entry); + if (result != ISC_R_SUCCESS) { + dns_rdata_freestruct(&ptr); + return (result); } - dns_rdata_freestruct(&ptr); - break; - default: - return (ISC_R_FAILURE); + result = isc_ht_add(zone->entries, mhash->base, + mhash->length, entry); + if (result != ISC_R_SUCCESS) { + dns_rdata_freestruct(&ptr); + dns_catz_entry_detach(zone, &entry); + return (result); + } } + dns_rdata_freestruct(&ptr); + return (ISC_R_SUCCESS); } @@ -866,6 +916,7 @@ catz_process_version(dns_catz_zone_t *zone, dns_rdataset_t *value) { result = dns_rdata_txt_current(&rdatatxt, &rdatastr); if (result != ISC_R_SUCCESS) goto cleanup; + result = dns_rdata_txt_next(&rdatatxt); if (result != ISC_R_NOMORE) { result = ISC_R_FAILURE; @@ -890,35 +941,164 @@ cleanup: } static isc_result_t -catz_process_ipkl(dns_catz_zone_t *zone, dns_ipkeylist_t *ipkl, - dns_rdataset_t *value) +catz_process_masters(dns_catz_zone_t *zone, dns_ipkeylist_t *ipkl, + dns_rdataset_t *value, dns_name_t *name) { isc_result_t result; dns_rdata_t rdata; dns_rdata_in_a_t rdata_a; + dns_rdata_in_aaaa_t rdata_aaaa; + dns_rdata_txt_t rdata_txt; + dns_rdata_txt_string_t rdatastr; + dns_name_t *keyname = NULL; + isc_mem_t *mctx; + char keycbuf[DNS_NAME_FORMATSIZE]; + isc_buffer_t keybuf; unsigned int rcount; + unsigned int i; REQUIRE(zone != NULL); REQUIRE(ipkl != NULL); REQUIRE(DNS_RDATASET_VALID(value)); REQUIRE(dns_rdataset_isassociated(value)); + REQUIRE(name != NULL); - if (value->rdclass != dns_rdataclass_in || - value->type != dns_rdatatype_a) + mctx = zone->catzs->mctx; + memset(&rdata_a, 0, sizeof(rdata_a)); + memset(&rdata_aaaa, 0, sizeof(rdata_aaaa)); + memset(&rdata_txt, 0, sizeof(rdata_txt)); + isc_buffer_init(&keybuf, keycbuf, sizeof(keycbuf)); + + /* + * We have three possibilities here: + * - either empty name and IN A/IN AAAA record + * - label and IN A/IN AAAA + * - label and IN TXT - TSIG key name + */ + if (value->rdclass != dns_rdataclass_in) return (ISC_R_FAILURE); - rcount = dns_rdataset_count(value); + if (name->labels > 0) { + isc_sockaddr_t sockaddr; - ipkl->addrs = isc_mem_reallocate(zone->catzs->mctx, ipkl->addrs, - (rcount * sizeof(isc_sockaddr_t))); - if (ipkl->addrs == NULL) - return (ISC_R_NOMEMORY); + /* + * We're pre-preparing the data once, we'll put it into + * the right spot in the masters array once we find it. + */ + result = dns_rdataset_first(value); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + dns_rdata_init(&rdata); + dns_rdataset_current(value, &rdata); + switch (value->type) { + case dns_rdatatype_a: + result = dns_rdata_tostruct(&rdata, &rdata_a, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + isc_sockaddr_fromin(&sockaddr, &rdata_a.in_addr, 0); + break; + case dns_rdatatype_aaaa: + result = dns_rdata_tostruct(&rdata, &rdata_aaaa, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + isc_sockaddr_fromin6(&sockaddr, &rdata_aaaa.in6_addr, 0); + break; + case dns_rdatatype_txt: + result = dns_rdata_tostruct(&rdata, &rdata_txt, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); - ipkl->keys = isc_mem_reallocate(zone->catzs->mctx, ipkl->keys, - (rcount * sizeof(dns_name_t *))); - if (ipkl->keys == NULL) { - isc_mem_free(zone->catzs->mctx, ipkl->addrs); - return (ISC_R_NOMEMORY); + result = dns_rdata_txt_first(&rdata_txt); + if (result != ISC_R_SUCCESS) + return (result); + + result = dns_rdata_txt_current(&rdata_txt, &rdatastr); + if (result != ISC_R_SUCCESS) + return (result); + + result = dns_rdata_txt_next(&rdata_txt); + if (result != ISC_R_NOMORE) + return (ISC_R_FAILURE); + + /* rdatastr.length < DNS_NAME_MAXTEXT */ + keyname = isc_mem_get(mctx, sizeof(dns_name_t)); + if (keyname == NULL) + return (ISC_R_NOMEMORY); + dns_name_init(keyname, 0); + memcpy(keycbuf, rdatastr.data, rdatastr.length); + keycbuf[rdatastr.length] = 0; + result = dns_name_fromstring(keyname, keycbuf, 0, mctx); + if (result != ISC_R_SUCCESS) { + dns_name_free(keyname, mctx); + isc_mem_put(mctx, keyname, sizeof(dns_name_t)); + return (result); + } + break; + default: + return (ISC_R_FAILURE); + } + + /* + * We have to find the appropriate labeled record in masters + * if it exists. + * In common case we'll have no more than 3-4 records here so + * no optimization. + */ + for (i = 0; i < ipkl->count; i++) { + if (ipkl->labels != NULL && + !dns_name_compare(name, ipkl->labels[i])) + break; + } + + if (i < ipkl->count) { /* we have this record already */ + if (value->type == dns_rdatatype_txt) + ipkl->keys[i] = keyname; + else /* A/AAAA */ + memcpy(&ipkl->addrs[i], &sockaddr, + sizeof(isc_sockaddr_t)); + } else { + result = dns_ipkeylist_resize(mctx, ipkl, + i+1); + if (result != ISC_R_SUCCESS) { + return (result); + } + + ipkl->labels[i] = isc_mem_get(mctx, sizeof(dns_name_t)); + if (ipkl->labels == NULL) { + if (keyname != NULL) { + dns_name_free(keyname, mctx); + isc_mem_put(mctx, keyname, + sizeof(dns_name_t)); + } + return (ISC_R_NOMEMORY); + } + dns_name_init(ipkl->labels[i], NULL); + result = dns_name_dup(name, mctx, ipkl->labels[i]); + if (result != ISC_R_SUCCESS) { + if (keyname != NULL) { + dns_name_free(keyname, mctx); + isc_mem_put(mctx, keyname, + sizeof(dns_name_t)); + } + return (result); + } + + if (value->type == dns_rdatatype_txt) + ipkl->keys[i] = keyname; + else /* A/AAAA */ + memcpy(&ipkl->addrs[i], &sockaddr, + sizeof(isc_sockaddr_t)); + ipkl->count++; + } + return (ISC_R_SUCCESS); + } + /* else - 'simple' case - without labels */ + + if (value->type != dns_rdatatype_a && + value->type != dns_rdatatype_aaaa) + return (ISC_R_FAILURE); + + rcount = dns_rdataset_count(value) + ipkl->count; + + result = dns_ipkeylist_resize(mctx, ipkl, rcount); + if (result != ISC_R_SUCCESS) { + return (result); } for (result = dns_rdataset_first(value); @@ -927,16 +1107,22 @@ catz_process_ipkl(dns_catz_zone_t *zone, dns_ipkeylist_t *ipkl, { dns_rdata_init(&rdata); dns_rdataset_current(value, &rdata); - - result = dns_rdata_tostruct(&rdata, &rdata_a, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - /* * port 0 == take the default */ - isc_sockaddr_fromin(&ipkl->addrs[ipkl->count], - &rdata_a.in_addr, 0); + if (value->type == dns_rdatatype_a) { + result = dns_rdata_tostruct(&rdata, &rdata_a, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + isc_sockaddr_fromin(&ipkl->addrs[ipkl->count], + &rdata_a.in_addr, 0); + } else { + result = dns_rdata_tostruct(&rdata, &rdata_aaaa, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + isc_sockaddr_fromin6(&ipkl->addrs[ipkl->count], + &rdata_aaaa.in6_addr, 0); + } ipkl->keys[ipkl->count] = NULL; + ipkl->labels[ipkl->count] = NULL; ipkl->count++; dns_rdata_freestruct(&rdata_a); } @@ -1022,22 +1208,30 @@ cleanup: } static isc_result_t -catz_process_suboption(dns_catz_zone_t *zone, dns_label_t *mhash, - catz_opt_t subopt, dns_rdataset_t *value) +catz_process_zones_suboption(dns_catz_zone_t *zone, dns_rdataset_t *value, + dns_label_t *mhash, dns_name_t *name) { isc_result_t result; dns_catz_entry_t *entry = NULL; + dns_label_t option; + dns_name_t prefix; + catz_opt_t opt; REQUIRE(zone != NULL); REQUIRE(mhash != NULL); REQUIRE(DNS_RDATASET_VALID(value)); + if (name->labels == 0) + return (ISC_R_FAILURE); + dns_name_getlabel(name, name->labels - 1, &option); + opt = catz_get_option(&option); + /* - * we're adding this entry now, in case the option is invalid we'll get - * rid of in verification phase + * We're adding this entry now, in case the option is invalid we'll get + * rid of it in verification phase. */ - result = isc_ht_find(zone->entries, mhash->base, - mhash->length, (void **) &entry); + result = isc_ht_find(zone->entries, mhash->base, mhash->length, + (void **) &entry); if (result != ISC_R_SUCCESS) { result = dns_catz_entry_new(zone->catzs->mctx, NULL, &entry); if (result != ISC_R_SUCCESS) @@ -1050,14 +1244,20 @@ catz_process_suboption(dns_catz_zone_t *zone, dns_label_t *mhash, } } - switch (subopt) { + dns_name_init(&prefix, NULL); + dns_name_split(name, 1, &prefix, NULL); + switch (opt) { case CATZ_OPT_MASTERS: - return (catz_process_ipkl(zone, &entry->opts.masters, value)); - break; + return (catz_process_masters(zone, &entry->opts.masters, value, + &prefix)); case CATZ_OPT_ALLOW_QUERY: + if (prefix.labels != 0) + return (ISC_R_FAILURE); return (catz_process_apl(zone, &entry->opts.allow_query, value)); case CATZ_OPT_ALLOW_TRANSFER: + if (prefix.labels != 0) + return (ISC_R_FAILURE); return (catz_process_apl(zone, &entry->opts.allow_transfer, value)); default: @@ -1068,72 +1268,45 @@ catz_process_suboption(dns_catz_zone_t *zone, dns_label_t *mhash, } static isc_result_t -catz_process_global_option(dns_catz_zone_t *zone, catz_opt_t option, - dns_rdataset_t *value) +catz_process_value(dns_catz_zone_t *zone, dns_name_t *name, + dns_rdataset_t *rdataset) { + dns_label_t option; + dns_name_t prefix; + catz_opt_t opt; + REQUIRE(zone != NULL); - REQUIRE(DNS_RDATASET_VALID(value)); + REQUIRE(name != NULL); + REQUIRE(DNS_RDATASET_VALID(rdataset)); - switch (option) { + dns_name_getlabel(name, name->labels - 1, &option); + opt = catz_get_option(&option); + dns_name_init(&prefix, NULL); + dns_name_split(name, 1, &prefix, NULL); + switch (opt) { + case CATZ_OPT_ZONES: + return (catz_process_zones(zone, rdataset, &prefix)); case CATZ_OPT_MASTERS: - return (catz_process_ipkl(zone, &zone->zoneoptions.masters, - value)); - case CATZ_OPT_VERSION: - return (catz_process_version(zone, value)); + return (catz_process_masters(zone, &zone->zoneoptions.masters, + rdataset, &prefix)); case CATZ_OPT_ALLOW_QUERY: + if (prefix.labels != 0) + return (ISC_R_FAILURE); return (catz_process_apl(zone, &zone->zoneoptions.allow_query, - value)); + rdataset)); case CATZ_OPT_ALLOW_TRANSFER: - return (catz_process_apl(zone, &zone->zoneoptions.allow_transfer, - value)); + if (prefix.labels != 0) + return (ISC_R_FAILURE); + return (catz_process_apl(zone, + &zone->zoneoptions.allow_transfer, + rdataset)); + case CATZ_OPT_VERSION: + if (prefix.labels != 0) + return (ISC_R_FAILURE); + return (catz_process_version(zone, rdataset)); default: return (ISC_R_FAILURE); } - return (ISC_R_FAILURE); -} - -static isc_result_t -catz_process_value(dns_catz_zone_t *zone, dns_name_t *value, - dns_rdataset_t *rdataset) -{ - dns_label_t suboption, option, mhash; - catz_opt_t opt, subopt; - - REQUIRE(zone != NULL); - REQUIRE(value != NULL); - REQUIRE(DNS_RDATASET_VALID(rdataset)); - - switch (value->labels) { - case 1: - /* Catalog zone-wide option */ - dns_name_getlabel(value, 0, &option); - opt = catz_get_option(&option); - return (catz_process_global_option(zone, opt, rdataset)); - - case 2: - /* Global list (eg. 'zones') */ - dns_name_getlabel(value, 0, &mhash); - dns_name_getlabel(value, 1, &option); - opt = catz_get_option(&option); - return (catz_process_global_list(zone, opt, rdataset, &mhash)); - - case 3: - /* Zone option */ - dns_name_getlabel(value, 0, &suboption); - dns_name_getlabel(value, 1, &mhash); - dns_name_getlabel(value, 2, &option); - opt = catz_get_option(&option); - subopt = catz_get_option(&suboption); - if (opt == CATZ_OPT_ZONES) - return (catz_process_suboption(zone, &mhash, subopt, - rdataset)); - break; - - default: - break; - } - - return (ISC_R_FAILURE); } isc_result_t @@ -1349,7 +1522,6 @@ dns_catz_update_taskaction(isc_task_t *task, isc_event_t *event) { LOCK(&zone->catzs->lock); zone->updatepending = ISC_FALSE; dns_catz_update_from_db(zone->db, zone->catzs); - dns_db_detach(&zone->db); result = isc_timer_reset(zone->updatetimer, isc_timertype_inactive, NULL, NULL, ISC_TRUE); RUNTIME_CHECK(result == ISC_R_SUCCESS); @@ -1379,20 +1551,34 @@ dns_catz_dbupdate_callback(dns_db_t *db, void *fn_arg) { if (result != ISC_R_SUCCESS) goto cleanup; + /* New zone came as AXFR */ + if (zone->db != NULL && zone->db != db) { + if (zone->dbversion != NULL) + dns_db_closeversion(zone->db, &zone->dbversion, + ISC_FALSE); + dns_db_detach(&zone->db); + /* + * We're not registering db update callback, it will be + * registered at the end of update_from_db + */ + zone->db_registered = ISC_FALSE; + } + if (zone->db == NULL) + dns_db_attach(db, &zone->db); + if (zone->updatepending == ISC_FALSE) { zone->updatepending = ISC_TRUE; isc_time_now(&now); tdiff = isc_time_microdiff(&now, &zone->lastupdated)/1000000; if (tdiff < zone->defoptions.min_update_interval) { isc_interval_t interval; - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_MASTER, ISC_LOG_INFO, "catz: new zone version came too soon, " "deferring update"); isc_interval_set(&interval, - 5 - (unsigned int)tdiff, 0); - dns_db_attach(db, &zone->db); + zone->defoptions.min_update_interval - + (unsigned int)tdiff, 0); dns_db_currentversion(db, &zone->dbversion); result = isc_timer_reset(zone->updatetimer, isc_timertype_once, @@ -1402,7 +1588,6 @@ dns_catz_dbupdate_callback(dns_db_t *db, void *fn_arg) { } else { isc_event_t *event; - dns_db_attach(db, &zone->db); dns_db_currentversion(db, &zone->dbversion); ISC_EVENT_INIT(&zone->updateevent, sizeof(zone->updateevent), 0, NULL, @@ -1413,11 +1598,12 @@ dns_catz_dbupdate_callback(dns_db_t *db, void *fn_arg) { isc_task_send(catzs->updater, &event); } } else { - INSIST(db == zone->db); isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_MASTER, ISC_LOG_DEBUG(3), "catz: update already queued"); - dns_db_closeversion(zone->db, &zone->dbversion, ISC_FALSE); + if (zone->dbversion != NULL) + dns_db_closeversion(zone->db, &zone->dbversion, + ISC_FALSE); dns_db_currentversion(zone->db, &zone->dbversion); } @@ -1446,12 +1632,12 @@ dns_catz_update_from_db(dns_db_t *db, dns_catz_zones_t *catzs) { REQUIRE(catzs != NULL); /* - * Create a new catz in the same context as current catz + * Create a new catz in the same context as current catz. */ dns_name_toregion(&db->origin, &r); result = isc_ht_find(catzs->zones, r.base, r.length, (void **)&oldzone); if (result != ISC_R_SUCCESS) { - /* this can happen if we remove the zone in the meantime */ + /* This can happen if we remove the zone in the meantime. */ isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_MASTER, ISC_LOG_ERROR, "catz: zone '%s' not in config", @@ -1503,7 +1689,7 @@ dns_catz_update_from_db(dns_db_t *db, dns_catz_zones_t *catzs) { name = dns_fixedname_name(&fixname); /* - * Iterate over database to fill the new zone + * Iterate over database to fill the new zone. */ result = dns_dbiterator_first(it); if (result != ISC_R_SUCCESS) { @@ -1542,21 +1728,27 @@ dns_catz_update_from_db(dns_db_t *db, dns_catz_zones_t *catzs) { &rdataset); if (result != ISC_R_SUCCESS) { char cname[DNS_NAME_FORMATSIZE]; + char type[DNS_RDATATYPE_FORMATSIZE]; + char class[DNS_RDATACLASS_FORMATSIZE]; + dns_name_format(name, cname, DNS_NAME_FORMATSIZE); + dns_rdataclass_format(rdataset.rdclass, class, + sizeof(class)); + dns_rdatatype_format(rdataset.type, type, + sizeof(type)); isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_MASTER, ISC_LOG_WARNING, "catz: unknown record in catalog " - "zone - %s (%s) - ignoring", - cname, + "zone - %s %s %s(%s) - ignoring", + cname, class, type, isc_result_totext(result)); } dns_rdataset_disassociate(&rdataset); if (result != ISC_R_SUCCESS) { break; } - result = dns_rdatasetiter_next(rdsiter); } @@ -1573,9 +1765,10 @@ dns_catz_update_from_db(dns_db_t *db, dns_catz_zones_t *catzs) { "catz: update_from_db: iteration finished"); /* - * Finally merge new zone into old zone + * Finally merge new zone into old zone. */ result = dns_catz_zones_merge(oldzone, newzone); + dns_catz_zone_detach(&newzone); if (result != ISC_R_SUCCESS) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_MASTER, @@ -1586,11 +1779,23 @@ dns_catz_update_from_db(dns_db_t *db, dns_catz_zones_t *catzs) { return; } - dns_catz_zone_detach(&newzone); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_MASTER, ISC_LOG_DEBUG(3), "catz: update_from_db: new zone merged"); + + /* + * When we're doing reconfig and setting a new catalog zone + * from an existing zone we won't have a chance to set up + * update callback in zone_startload or axfr_makedb, but we will + * call onupdate() artificially so we can register the callback here. + */ + if (oldzone->db_registered == ISC_FALSE) { + result = dns_db_updatenotify_register(db, + dns_catz_dbupdate_callback, + oldzone->catzs); + if (result == ISC_R_SUCCESS) + oldzone->db_registered = ISC_TRUE; + } } void @@ -1621,11 +1826,11 @@ dns_catz_postreconfig(dns_catz_zones_t *catzs) { isc_ht_iter_t *iter = NULL; dns_catz_zone_t *zone; + LOCK(&catzs->lock); result = isc_ht_iter_create(catzs->zones, &iter); INSIST(result == ISC_R_SUCCESS); for (result = isc_ht_iter_first(iter); - result == ISC_R_SUCCESS; - result = isc_ht_iter_next(iter)) + result == ISC_R_SUCCESS;) { isc_ht_iter_current(iter, (void **) &zone); if (zone->active == ISC_FALSE) { @@ -1639,7 +1844,7 @@ dns_catz_postreconfig(dns_catz_zones_t *catzs) { /* * Merge the old zone with an empty one to remove - * all members + * all members. */ result = dns_catz_new_zone(catzs, &newzone, &zone->name); @@ -1647,11 +1852,15 @@ dns_catz_postreconfig(dns_catz_zones_t *catzs) { dns_catz_zones_merge(zone, newzone); dns_catz_zone_detach(&newzone); - /* Make sure that we have an empty catalog zone */ + /* Make sure that we have an empty catalog zone. */ INSIST(isc_ht_count(zone->entries) == 0); + result = isc_ht_iter_delcurrent_next(iter); dns_catz_zone_detach(&zone); + } else { + result = isc_ht_iter_next(iter); } } + UNLOCK(&catzs->lock); RUNTIME_CHECK(result == ISC_R_NOMORE); isc_ht_iter_destroy(&iter); } diff --git a/lib/dns/include/dns/ipkeylist.h b/lib/dns/include/dns/ipkeylist.h index 55c094e5446..769c7483824 100644 --- a/lib/dns/include/dns/ipkeylist.h +++ b/lib/dns/include/dns/ipkeylist.h @@ -28,9 +28,20 @@ struct dns_ipkeylist { isc_sockaddr_t *addrs; isc_dscp_t *dscps; dns_name_t **keys; + dns_name_t **labels; isc_uint32_t count; + isc_uint32_t allocated; }; +void +dns_ipkeylist_init(dns_ipkeylist_t *ipkl); +/*%< + * Reset ipkl to empty state + * + * Requires: + *\li 'ipkl' to be non NULL. + */ + void dns_ipkeylist_clear(isc_mem_t *mctx, dns_ipkeylist_t *ipkl); /*%< @@ -41,8 +52,7 @@ dns_ipkeylist_clear(isc_mem_t *mctx, dns_ipkeylist_t *ipkl); * * Requires: *\li 'mctx' to be a valid memory context. - *\li 'ipkl' to be non NULL and have its members `addrs` and `keys` - * allocated. 'dscps' might be NULL. + *\li 'ipkl' to be non NULL. */ isc_result_t @@ -61,5 +71,20 @@ dns_ipkeylist_copy(isc_mem_t *mctx, const dns_ipkeylist_t *src, *\li #ISC_R_SUCCESS -- success *\li any other value -- failure */ +isc_result_t +dns_ipkeylist_resize(isc_mem_t *mctx, dns_ipkeylist_t *ipkl, unsigned int n); +/*%< + * Resize ipkl to contain n elements. Size (count) is not changed, and the + * added space is zeroed. + * + * Requires: + * \li 'mctx' to be a valid memory context. + * \li 'ipk' to be non NULL + * \li 'n' >= ipkl->count + * + * Returns: + * \li #ISC_R_SUCCESS if successs + * \li #ISC_R_NOMEMORY if there's no memory, ipkeylist is left untoched + */ #endif diff --git a/lib/dns/include/dns/zone.h b/lib/dns/include/dns/zone.h index 25db4cd5bac..d708f368d6c 100644 --- a/lib/dns/include/dns/zone.h +++ b/lib/dns/include/dns/zone.h @@ -2415,6 +2415,27 @@ dns_zone_catz_enable_db(dns_zone_t *zone, dns_db_t *db); * \li 'zone' is a valid zone object * \li 'db' is not NULL */ +void +dns_zone_set_parentcatz(dns_zone_t *zone, dns_catz_zone_t *catz); +/*%< + * Set parent catalog zone for this zone + * + * Requires: + * + * \li 'zone' is a valid zone object + * \li 'catz' is not NULL + */ + +dns_catz_zone_t * +dns_zone_get_parentcatz(const dns_zone_t *zone); +/*%< + * Get parent catalog zone for this zone + * + * Requires: + * + * \li 'zone' is a valid zone object + */ + void dns_zone_setstatlevel(dns_zone_t *zone, dns_zonestat_level_t level); diff --git a/lib/dns/ipkeylist.c b/lib/dns/ipkeylist.c index 10770985c45..5beebfa5648 100644 --- a/lib/dns/ipkeylist.c +++ b/lib/dns/ipkeylist.c @@ -25,38 +25,58 @@ #include #include +void +dns_ipkeylist_init(dns_ipkeylist_t *ipkl) { + ipkl->count = 0; + ipkl->allocated = 0; + ipkl->addrs = NULL; + ipkl->dscps = NULL; + ipkl->keys = NULL; + ipkl->labels = NULL; +} + void dns_ipkeylist_clear(isc_mem_t *mctx, dns_ipkeylist_t *ipkl) { isc_uint32_t i; REQUIRE(ipkl != NULL); - REQUIRE(ipkl->count == 0 || ipkl->keys != NULL); - if (ipkl->count == 0) + if (ipkl->allocated == 0) return; if (ipkl->addrs != NULL) isc_mem_put(mctx, ipkl->addrs, - ipkl->count * sizeof(isc_sockaddr_t)); + ipkl->allocated * sizeof(isc_sockaddr_t)); if (ipkl->dscps != NULL) isc_mem_put(mctx, ipkl->dscps, - ipkl->count * sizeof(isc_dscp_t)); - - for (i = 0; i < ipkl->count; i++) { - if (ipkl->keys[i] == NULL) - continue; - if (dns_name_dynamic(ipkl->keys[i])) - dns_name_free(ipkl->keys[i], mctx); - isc_mem_put(mctx, ipkl->keys[i], sizeof(dns_name_t)); + ipkl->allocated * sizeof(isc_dscp_t)); + + if (ipkl->keys != NULL) { + for (i = 0; i < ipkl->allocated; i++) { + if (ipkl->keys[i] == NULL) + continue; + if (dns_name_dynamic(ipkl->keys[i])) + dns_name_free(ipkl->keys[i], mctx); + isc_mem_put(mctx, ipkl->keys[i], sizeof(dns_name_t)); + } + isc_mem_put(mctx, ipkl->keys, + ipkl->allocated * sizeof(dns_name_t *)); } - isc_mem_put(mctx, ipkl->keys, ipkl->count * sizeof(dns_name_t *)); + if (ipkl->labels != NULL) { + for (i = 0; i < ipkl->allocated; i++) { + if (ipkl->labels[i] == NULL) + continue; + if (dns_name_dynamic(ipkl->labels[i])) + dns_name_free(ipkl->labels[i], mctx); + isc_mem_put(mctx, ipkl->labels[i], sizeof(dns_name_t)); + } + isc_mem_put(mctx, ipkl->labels, + ipkl->allocated * sizeof(dns_name_t *)); + } - ipkl->count = 0; - ipkl->addrs = NULL; - ipkl->dscps = NULL; - ipkl->keys = NULL; + dns_ipkeylist_init(ipkl); } isc_result_t @@ -67,40 +87,24 @@ dns_ipkeylist_copy(isc_mem_t *mctx, const dns_ipkeylist_t *src, isc_uint32_t i; REQUIRE(dst != NULL); - REQUIRE(dst->count == 0 && - dst->addrs == NULL && dst->keys == NULL && dst->dscps == NULL); + /* dst might be preallocated, we don't care, but it must be empty */ + REQUIRE(dst->count == 0); if (src->count == 0) return (ISC_R_SUCCESS); - dst->count = src->count; - - dst->addrs = isc_mem_get(mctx, - src->count * sizeof(isc_sockaddr_t)); - if (dst->addrs == NULL) - return (ISC_R_NOMEMORY); + result = dns_ipkeylist_resize(mctx, dst, src->count); + if (result != ISC_R_SUCCESS) + return (result); memmove(dst->addrs, src->addrs, src->count * sizeof(isc_sockaddr_t)); if (src->dscps != NULL) { - dst->dscps = isc_mem_get(mctx, - src->count * sizeof(isc_dscp_t)); - if (dst->dscps == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup_addrs; - } memmove(dst->dscps, src->dscps, src->count * sizeof(isc_dscp_t)); } if (src->keys != NULL) { - dst->keys = isc_mem_get(mctx, - src->count * sizeof(dns_name_t *)); - if (dst->keys == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup_dscps; - } - for (i = 0; i < src->count; i++) { if (src->keys[i] != NULL) { dst->keys[i] = isc_mem_get(mctx, @@ -120,20 +124,121 @@ dns_ipkeylist_copy(isc_mem_t *mctx, const dns_ipkeylist_t *src, } } + if (src->labels != NULL) { + for (i = 0; i < src->count; i++) { + if (src->labels[i] != NULL) { + dst->labels[i] = isc_mem_get(mctx, + sizeof(dns_name_t)); + if (dst->labels[i] == NULL) { + result = ISC_R_NOMEMORY; + goto cleanup_labels; + } + dns_name_init(dst->labels[i], NULL); + result = dns_name_dup(src->labels[i], mctx, + dst->labels[i]); + if (result != ISC_R_SUCCESS) + goto cleanup_labels; + } else { + dst->labels[i] = NULL; + } + } + } + dst->count = src->count; return (ISC_R_SUCCESS); + cleanup_labels: + do { + if (dst->labels[i] != NULL) { + if (dns_name_dynamic(dst->labels[i])) + dns_name_free(dst->labels[i], mctx); + isc_mem_put(mctx, dst->labels[i], sizeof(dns_name_t)); + dst->labels[i] = NULL; + } + } while (i-- > 0); + cleanup_keys: do { if (dst->keys[i] != NULL) { if (dns_name_dynamic(dst->keys[i])) dns_name_free(dst->keys[i], mctx); isc_mem_put(mctx, dst->keys[i], sizeof(dns_name_t)); + dst->keys[i] = NULL; } } while (i-- > 0); - isc_mem_put(mctx, dst->keys, src->count * sizeof(dns_name_t *)); - cleanup_dscps: - isc_mem_put(mctx, dst->dscps, src->count * sizeof(isc_dscp_t)); - cleanup_addrs: - isc_mem_put(mctx, dst->addrs, src->count * sizeof(isc_sockaddr_t)); + return (result); } + +isc_result_t +dns_ipkeylist_resize(isc_mem_t *mctx, dns_ipkeylist_t *ipkl, unsigned int n) { + isc_sockaddr_t *addrs = NULL; + isc_dscp_t *dscps = NULL; + dns_name_t **keys = NULL; + dns_name_t **labels = NULL; + + REQUIRE(ipkl != NULL); + REQUIRE(n > ipkl->count); + + if (n <= ipkl->allocated) + return (ISC_R_SUCCESS); + + addrs = isc_mem_get(mctx, n * sizeof(isc_sockaddr_t)); + if (addrs == NULL) + goto nomemory; + dscps = isc_mem_get(mctx, n * sizeof(isc_dscp_t)); + if (dscps == NULL) + goto nomemory; + keys = isc_mem_get(mctx, n * sizeof(dns_name_t *)); + if (keys == NULL) + goto nomemory; + labels = isc_mem_get(mctx, n * sizeof(dns_name_t *)); + if (labels == NULL) + goto nomemory; + + memmove(addrs, ipkl->addrs, ipkl->allocated * sizeof(isc_sockaddr_t)); + if (ipkl->addrs != NULL) + isc_mem_put(mctx, ipkl->addrs, + ipkl->allocated * sizeof(isc_sockaddr_t)); + ipkl->addrs = addrs; + memset(&ipkl->addrs[ipkl->allocated], 0, + (n - ipkl->allocated) * sizeof(isc_sockaddr_t)); + + memmove(dscps, ipkl->dscps, ipkl->allocated * sizeof(isc_dscp_t)); + if (ipkl->dscps != NULL) + isc_mem_put(mctx, ipkl->dscps, + ipkl->allocated * sizeof(isc_dscp_t)); + ipkl->dscps = dscps; + memset(&ipkl->dscps[ipkl->allocated], 0, + (n - ipkl->allocated) * sizeof(isc_dscp_t)); + + memmove(keys, ipkl->keys, ipkl->allocated * sizeof(dns_name_t *)); + if (ipkl->keys) + isc_mem_put(mctx, ipkl->keys, + ipkl->allocated * sizeof(dns_name_t *)); + ipkl->keys = keys; + memset(&ipkl->keys[ipkl->allocated], 0, + (n - ipkl->allocated) * sizeof(dns_name_t *)); + + memmove(labels, ipkl->labels, ipkl->allocated * sizeof(dns_name_t *)); + if (ipkl->labels) + isc_mem_put(mctx, ipkl->labels, + ipkl->allocated * sizeof(dns_name_t *)); + ipkl->labels = labels; + memset(&ipkl->labels[ipkl->allocated], 0, + (n - ipkl->allocated) * sizeof(dns_name_t *)); + + ipkl->allocated = n; + return (ISC_R_SUCCESS); + +nomemory: + if (addrs != NULL) + isc_mem_put(mctx, addrs, n * sizeof(isc_sockaddr_t)); + if (dscps != NULL) + isc_mem_put(mctx, dscps, n * sizeof(isc_dscp_t)); + if (keys != NULL) + isc_mem_put(mctx, keys, n * sizeof(dns_name_t *)); + if (labels != NULL) + isc_mem_put(mctx, labels, n * sizeof(dns_name_t *)); + + return (ISC_R_NOMEMORY); +} diff --git a/lib/dns/name.c b/lib/dns/name.c index 85345bcb073..2d4a247f35b 100644 --- a/lib/dns/name.c +++ b/lib/dns/name.c @@ -2176,7 +2176,7 @@ dns_name_split(dns_name_t *name, unsigned int suffixlabels, REQUIRE(VALID_NAME(name)); REQUIRE(suffixlabels > 0); - REQUIRE(suffixlabels < name->labels); + REQUIRE(suffixlabels <= name->labels); REQUIRE(prefix != NULL || suffix != NULL); REQUIRE(prefix == NULL || (VALID_NAME(prefix) && diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 74ae734f8e2..4b7a45e57fa 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -384,7 +384,12 @@ struct dns_zone { /*% * catalog zone data */ - dns_catz_zones_t *catzs; + dns_catz_zones_t *catzs; + + /*% + * parent catalog zone + */ + dns_catz_zone_t *parentcatz; /*% * Serial number update method. @@ -1044,6 +1049,7 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) { zone->rpz_num = DNS_RPZ_INVALID_NUM; zone->catzs = NULL; + zone->parentcatz = NULL; ISC_LIST_INIT(zone->forwards); zone->raw = NULL; @@ -1787,6 +1793,25 @@ dns_zone_catz_enable_db(dns_zone_t *zone, dns_db_t *db) { } } +/* + * Set catalog zone ownership of the zone + */ +void +dns_zone_set_parentcatz(dns_zone_t *zone, dns_catz_zone_t *catz) { + REQUIRE(DNS_ZONE_VALID(zone)); + REQUIRE(catz != NULL); + LOCK_ZONE(zone); + INSIST(zone->parentcatz == NULL || zone->parentcatz == catz); + zone->parentcatz = catz; + UNLOCK_ZONE(zone); +} + +dns_catz_zone_t * +dns_zone_get_parentcatz(const dns_zone_t *zone) { + REQUIRE(DNS_ZONE_VALID(zone)); + return (zone->parentcatz); +} + static isc_boolean_t zone_touched(dns_zone_t *zone) {