diff --git a/CHANGES b/CHANGES index 85e4fd90b9..64894bb7c2 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +5691. [bug] 'rndc freeze' with in-view zones present would + spuriously report failures. [GL #2844] + 5690. [func] Change "dnssec-signzone" to honor the Predecessor and Successor metadata values, and allow for gradual replacement of RRSIGs. In other words, don't sign diff --git a/bin/tests/system/rndc/clean.sh b/bin/tests/system/rndc/clean.sh index 25ec6c8f68..9faf948262 100644 --- a/bin/tests/system/rndc/clean.sh +++ b/bin/tests/system/rndc/clean.sh @@ -18,6 +18,7 @@ rm -f ns2/nil.db ns2/other.db ns2/static.db ns2/*.jnl rm -f ns2/session.key rm -f ns3/named_dump.db* rm -f ns4/*.nta +rm -f ns4/example.db ns4/example.db.jnl rm -f ns4/key?.conf rm -f ns6/huge.zone.db rm -f ns*/named.conf diff --git a/bin/tests/system/rndc/ns4/named.conf.in b/bin/tests/system/rndc/ns4/named.conf.in index 4f009a7c2d..674e63904b 100644 --- a/bin/tests/system/rndc/ns4/named.conf.in +++ b/bin/tests/system/rndc/ns4/named.conf.in @@ -15,13 +15,22 @@ options { listen-on { 10.53.0.4; }; listen-on-v6 { none; }; recursion yes; - dnssec-validation yes; + dnssec-validation yes; }; view normal { match-clients { any; }; + + zone example { + type primary; + file "example.db"; + allow-update { any; }; + }; }; view "view with a space" { match-clients { none; }; + zone example { + in-view normal; + }; }; diff --git a/bin/tests/system/rndc/setup.sh b/bin/tests/system/rndc/setup.sh index e4bd9ae134..fb56de80a4 100644 --- a/bin/tests/system/rndc/setup.sh +++ b/bin/tests/system/rndc/setup.sh @@ -15,6 +15,8 @@ $SHELL ${TOP_SRCDIR}/bin/tests/system/genzone.sh 2 >ns2/nil.db $SHELL ${TOP_SRCDIR}/bin/tests/system/genzone.sh 2 >ns2/other.db $SHELL ${TOP_SRCDIR}/bin/tests/system/genzone.sh 2 >ns2/static.db +$SHELL ${TOP_SRCDIR}/bin/tests/system/genzone.sh 2 >ns4/example.db + $SHELL ${TOP_SRCDIR}/bin/tests/system/genzone.sh 2 >ns6/huge.zone.db # we make the huge zone less huge if we're running under diff --git a/bin/tests/system/rndc/tests.sh b/bin/tests/system/rndc/tests.sh index f847b2ad0b..c3dda378f8 100644 --- a/bin/tests/system/rndc/tests.sh +++ b/bin/tests/system/rndc/tests.sh @@ -40,7 +40,7 @@ if [ $ret != 0 ]; then echo_i "failed"; fi status=$((status+ret)) echo_i "rndc freeze" -$RNDCCMD 10.53.0.2 freeze | sed 's/^/ns2 /' | cat_i | cat_i +$RNDCCMD 10.53.0.2 freeze | sed 's/^/ns2 /' | cat_i n=$((n+1)) echo_i "checking zone was dumped ($n)" @@ -426,7 +426,7 @@ n=$((n+1)) echo_i "testing automatic zones are reported ($n)" ret=0 $RNDC -s 10.53.0.4 -p ${EXTRAPORT6} -c ns4/key6.conf status > rndc.out.1.test$n || ret=1 -grep "number of zones: 200 (198 automatic)" rndc.out.1.test$n > /dev/null || ret=1 +grep "number of zones: 201 (198 automatic)" rndc.out.1.test$n > /dev/null || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi status=$((status+ret)) @@ -689,5 +689,49 @@ lines=`cat rndc.out.test$n | wc -l` if [ $ret != 0 ]; then echo_i "failed"; fi status=$((status+ret)) +n=$((n+1)) +echo_i "check 'rndc freeze' with in-view zones works ($n)" +ret=0 +$RNDC -s 10.53.0.4 -p ${EXTRAPORT6} -c ns4/key6.conf freeze > rndc.out.test$n 2>&1 || ret=1 +test -s rndc.out.test$n && sed 's/^/ns2 /' rndc.out.test$n | cat_i +if [ $ret != 0 ]; then echo_i "failed"; fi +status=$((status+ret)) + +n=$((n+1)) +echo_i "checking non in-view zone instance is not writable ($n)" +ret=0 +$NSUPDATE -p ${PORT} > /dev/null 2>&1 < dig.out.1.test$n +grep 'addition 3' dig.out.1.test$n >/dev/null && ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi +status=$((status+ret)) + +n=$((n+1)) +echo_i "check 'rndc thaw' with in-view zones works ($n)" +ret=0 +$RNDC -s 10.53.0.4 -p ${EXTRAPORT6} -c ns4/key6.conf thaw > rndc.out.test$n 2>&1 || ret=1 +test -s rndc.out.test$n && sed 's/^/ns2 /' rndc.out.test$n | cat_i +if [ $ret != 0 ]; then echo_i "failed"; fi +status=$((status+ret)) + +n=$((n+1)) +echo_i "checking non in-view zone instance is now writable ($n)" +ret=0 +$NSUPDATE -p ${PORT} > nsupdate.out.test$n 2>&1 < dig.out.1.test$n +grep 'addition 3' dig.out.1.test$n >/dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi +status=$((status+ret)) + echo_i "exit status: $status" [ $status -eq 0 ] || exit 1 diff --git a/lib/dns/include/dns/zt.h b/lib/dns/include/dns/zt.h index ef5982732b..4a1b2639a8 100644 --- a/lib/dns/include/dns/zt.h +++ b/lib/dns/include/dns/zt.h @@ -160,7 +160,7 @@ dns_zt_asyncload(dns_zt_t *zt, bool newonly, dns_zt_allloaded_t alldone, */ isc_result_t -dns_zt_freezezones(dns_zt_t *zt, bool freeze); +dns_zt_freezezones(dns_zt_t *zt, dns_view_t *view, bool freeze); /*%< * Freeze/thaw updates to master zones. * Any pending updates will be flushed. diff --git a/lib/dns/view.c b/lib/dns/view.c index 5de3108d45..27df703811 100644 --- a/lib/dns/view.c +++ b/lib/dns/view.c @@ -1855,7 +1855,7 @@ dns_view_freezezones(dns_view_t *view, bool value) { REQUIRE(DNS_VIEW_VALID(view)); REQUIRE(view->zonetable != NULL); - return (dns_zt_freezezones(view->zonetable, value)); + return (dns_zt_freezezones(view->zonetable, view, value)); } void diff --git a/lib/dns/zt.c b/lib/dns/zt.c index cfe7d31e45..3fde5f16e1 100644 --- a/lib/dns/zt.c +++ b/lib/dns/zt.c @@ -55,6 +55,11 @@ struct dns_zt { dns_rbt_t *table; }; +struct zt_freeze_params { + dns_view_t *view; + bool freeze; +}; + #define ZTMAGIC ISC_MAGIC('Z', 'T', 'b', 'l') #define VALID_ZT(zt) ISC_MAGIC_VALID(zt, ZTMAGIC) @@ -375,13 +380,14 @@ asyncload(dns_zone_t *zone, void *zt_) { } isc_result_t -dns_zt_freezezones(dns_zt_t *zt, bool freeze) { +dns_zt_freezezones(dns_zt_t *zt, dns_view_t *view, bool freeze) { isc_result_t result, tresult; + struct zt_freeze_params params = { view, freeze }; REQUIRE(VALID_ZT(zt)); RWLOCK(&zt->rwlock, isc_rwlocktype_read); - result = dns_zt_apply(zt, false, &tresult, freezezones, &freeze); + result = dns_zt_apply(zt, false, &tresult, freezezones, ¶ms); RWUNLOCK(&zt->rwlock, isc_rwlocktype_read); if (tresult == ISC_R_NOTFOUND) { tresult = ISC_R_SUCCESS; @@ -391,7 +397,7 @@ dns_zt_freezezones(dns_zt_t *zt, bool freeze) { static isc_result_t freezezones(dns_zone_t *zone, void *uap) { - bool freeze = *(bool *)uap; + struct zt_freeze_params *params = uap; bool frozen; isc_result_t result = ISC_R_SUCCESS; char classstr[DNS_RDATACLASS_FORMATSIZE]; @@ -406,6 +412,12 @@ freezezones(dns_zone_t *zone, void *uap) { if (raw != NULL) { zone = raw; } + if (params->view != dns_zone_getview(zone)) { + if (raw != NULL) { + dns_zone_detach(&raw); + } + return (ISC_R_SUCCESS); + } if (dns_zone_gettype(zone) != dns_zone_master) { if (raw != NULL) { dns_zone_detach(&raw); @@ -420,7 +432,7 @@ freezezones(dns_zone_t *zone, void *uap) { } frozen = dns_zone_getupdatedisabled(zone); - if (freeze) { + if (params->freeze) { if (frozen) { result = DNS_R_FROZEN; } @@ -428,7 +440,7 @@ freezezones(dns_zone_t *zone, void *uap) { result = dns_zone_flush(zone); } if (result == ISC_R_SUCCESS) { - dns_zone_setupdatedisabled(zone, freeze); + dns_zone_setupdatedisabled(zone, params->freeze); } } else { if (frozen) { @@ -455,8 +467,8 @@ freezezones(dns_zone_t *zone, void *uap) { level = (result != ISC_R_SUCCESS) ? ISC_LOG_ERROR : ISC_LOG_DEBUG(1); isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE, level, "%s zone '%s/%s'%s%s: %s", - freeze ? "freezing" : "thawing", zonename, classstr, sep, - vname, isc_result_totext(result)); + params->freeze ? "freezing" : "thawing", zonename, + classstr, sep, vname, isc_result_totext(result)); if (raw != NULL) { dns_zone_detach(&raw); }