diff --git a/CHANGES b/CHANGES index e28565fb8d..556633512d 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +6058. [bug] Prevent named from crashing when "rndc delzone" + attempts to delete a zone added by a catalog zone. + [GL #3745] + 6057. [bug] Fix shutdown and error path bugs in the rpz unit. [GL #3735] diff --git a/bin/named/server.c b/bin/named/server.c index 7019256dd3..62a260ae5b 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -14372,10 +14372,11 @@ typedef struct { static void rmzone(isc_task_t *task, isc_event_t *event) { ns_dzctx_t *dz = (ns_dzctx_t *)event->ev_arg; - dns_zone_t *zone, *raw = NULL, *mayberaw; + dns_zone_t *zone = NULL, *raw = NULL, *mayberaw = NULL; + dns_catz_zone_t *catz = NULL; char zonename[DNS_NAME_FORMATSIZE]; - dns_view_t *view; - ns_cfgctx_t *cfg; + dns_view_t *view = NULL; + ns_cfgctx_t *cfg = NULL; dns_db_t *dbp = NULL; bool added; isc_result_t result; @@ -14399,10 +14400,14 @@ rmzone(isc_task_t *task, isc_event_t *event) { "deleting zone %s in view %s via delzone", zonename, view->name); - /* Remove the zone from configuration (and NZF file if applicable) */ + /* + * Remove the zone from configuration (and NZF file if applicable) + * (If this is a catalog zone member then nzf_config can be NULL) + */ added = dns_zone_getadded(zone); + catz = dns_zone_get_parentcatz(zone); - if (added && cfg != NULL) { + if (added && catz == NULL && cfg != NULL) { #ifdef HAVE_LMDB /* Make sure we can open the NZD database */ LOCK(&view->new_zone_lock); @@ -14419,8 +14424,7 @@ rmzone(isc_task_t *task, isc_event_t *event) { if (result != ISC_R_SUCCESS) { isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR, - "unable to " - "delete zone configuration: %s", + "unable to delete zone configuration: %s", isc_result_totext(result)); } @@ -14435,8 +14439,7 @@ rmzone(isc_task_t *task, isc_event_t *event) { if (result != ISC_R_SUCCESS) { isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR, - "unable to " - "delete zone configuration: %s", + "unable to delete zone configuration: %s", isc_result_totext(result)); } #endif /* HAVE_LMDB */ @@ -14457,8 +14460,7 @@ rmzone(isc_task_t *task, isc_event_t *event) { if (result != ISC_R_SUCCESS) { isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR, - "unable to " - "delete zone configuration: %s", + "unable to delete zone configuration: %s", isc_result_totext(result)); } } @@ -14575,8 +14577,8 @@ named_server_delzone(named_server_t *server, isc_lex_t *lex, if (dns_zone_get_rpz_num(zone) != DNS_RPZ_INVALID_NUM) { TCHECK(putstr(text, "zone '")); TCHECK(putstr(text, zonename)); - TCHECK(putstr(text, "' cannot be deleted: response-policy " - "zone.")); + TCHECK(putstr(text, + "' cannot be deleted: response-policy zone.")); result = ISC_R_FAILURE; goto cleanup; } diff --git a/bin/tests/system/catz/tests.sh b/bin/tests/system/catz/tests.sh index 09c7ba5d04..796786366b 100644 --- a/bin/tests/system/catz/tests.sh +++ b/bin/tests/system/catz/tests.sh @@ -1903,6 +1903,130 @@ wait_for_no_soa @10.53.0.2 dom13.example. dig.out.test$n || ret=1 if [ $ret -ne 0 ]; then echo_i "failed"; fi status=$((status+ret)) +########################################################################## +echo_i "Testing recreation of a manually deleted zone after a reload" +n=$((n+1)) +echo_i "checking that dom16.example. is not served by primary ($n)" +ret=0 +wait_for_no_soa @10.53.0.1 dom16.example. dig.out.test$n || ret=1 +if [ $ret -ne 0 ]; then echo_i "failed"; fi +status=$((status+ret)) + +n=$((n+1)) +echo_i "Adding a domain dom16.example. to primary ns1 via RNDC ($n)" +ret=0 +echo "@ 3600 IN SOA . . 1 3600 3600 3600 3600" > ns1/dom16.example.db +echo "@ IN NS invalid." >> ns1/dom16.example.db +echo "@ IN A 192.0.2.1" >> ns1/dom16.example.db +rndccmd 10.53.0.1 addzone dom16.example. in default '{type primary; file "dom16.example.db";};' || ret=1 +if [ $ret -ne 0 ]; then echo_i "failed"; fi +status=$((status+ret)) + +n=$((n+1)) +echo_i "checking that dom16.example. is now served by primary ns1 ($n)" +ret=0 +wait_for_soa @10.53.0.1 dom16.example. dig.out.test$n || ret=1 +if [ $ret -ne 0 ]; then echo_i "failed"; fi +status=$((status+ret)) + +nextpart ns2/named.run >/dev/null + +n=$((n+1)) +echo_i "Adding domain dom16.example. to catalog1 zone with ns1 as primary ($n)" +ret=0 +$NSUPDATE -d <> nsupdate.out.test$n 2>&1 || ret=1 + server 10.53.0.1 ${PORT} + update add efe725d0cf430ffb113b9bcf59266f066a21216b.zones.catalog1.example. 3600 IN PTR dom16.example. + update add masters.efe725d0cf430ffb113b9bcf59266f066a21216b.zones.catalog1.example. 3600 IN A 10.53.0.1 + send +END +if [ $ret -ne 0 ]; then echo_i "failed"; fi +status=$((status+ret)) + +n=$((n+1)) +echo_i "waiting for secondary to sync up ($n)" +ret=0 +wait_for_message ns2/named.run "catz: adding zone 'dom16.example' from catalog 'catalog1.example'" && +wait_for_message ns2/named.run "transfer of 'dom16.example/IN/default' from 10.53.0.1#${PORT}: Transfer status: success" || ret=1 +if [ $ret -ne 0 ]; then echo_i "failed"; fi +status=$((status+ret)) + +nextpart ns2/named.run >/dev/null + +n=$((n+1)) +echo_i "checking that dom16.example. is served by secondary and that it's the one from ns1 ($n)" +ret=0 +wait_for_a @10.53.0.2 dom16.example. dig.out.test$n || ret=1 +grep "192.0.2.1" dig.out.test$n > /dev/null || ret=1 +if [ $ret -ne 0 ]; then echo_i "failed"; fi +status=$((status+ret)) + +nextpart ns2/named.run >/dev/null + +echo_i "Deleting dom16.example. from secondary ns2 via RNDC ($n)" +ret=0 +rndccmd 10.53.0.2 delzone dom16.example. in default >/dev/null 2>&1 || ret=1 +if [ $ret -ne 0 ]; then echo_i "failed"; fi +status=$((status+ret)) + +n=$((n+1)) +echo_i "checking that dom16.example. is no longer served by secondary ($n)" +ret=0 +wait_for_no_soa @10.53.0.2 dom16.example. dig.out.test$n || ret=1 +if [ $ret -ne 0 ]; then echo_i "failed"; fi +status=$((status+ret)) + +nextpart ns2/named.run >/dev/null + +echo_i "Reloading secondary ns2 via RNDC ($n)" +ret=0 +rndccmd 10.53.0.2 reload >/dev/null 2>&1 || ret=1 +if [ $ret -ne 0 ]; then echo_i "failed"; fi +status=$((status+ret)) + +n=$((n+1)) +echo_i "waiting for secondary to sync up ($n)" +ret=0 +wait_for_message ns2/named.run "catz: update_from_db: new zone merged" || ret=1 +if [ $ret -ne 0 ]; then echo_i "failed"; fi +status=$((status+ret)) + +n=$((n+1)) +echo_i "checking that dom16.example. is served by secondary and that it's the one from ns1 ($n)" +ret=0 +wait_for_a @10.53.0.2 dom16.example. dig.out.test$n || ret=1 +grep "192.0.2.1" dig.out.test$n > /dev/null || ret=1 +if [ $ret -ne 0 ]; then echo_i "failed"; fi +status=$((status+ret)) + +nextpart ns2/named.run >/dev/null + +n=$((n+1)) +echo_i "Deleting domain dom16.example. from catalog1 ($n)" +ret=0 +$NSUPDATE -d <> nsupdate.out.test$n 2>&1 || ret=1 + server 10.53.0.1 ${PORT} + update delete efe725d0cf430ffb113b9bcf59266f066a21216b.zones.catalog1.example. 3600 IN PTR dom16.example. + update delete masters.efe725d0cf430ffb113b9bcf59266f066a21216b.zones.catalog1.example. 3600 IN A 10.53.0.1 + send +END +if [ $ret -ne 0 ]; then echo_i "failed"; fi +status=$((status+ret)) + +n=$((n+1)) +echo_i "waiting for secondary to sync up ($n)" +ret=0 +wait_for_message ns2/named.run "catz: update_from_db: new zone merged" || ret=1 +if [ $ret -ne 0 ]; then echo_i "failed"; fi +status=$((status+ret)) + +n=$((n+1)) +echo_i "checking that dom16.example. is no longer served by secondary ($n)" +ret=0 +wait_for_no_soa @10.53.0.2 dom16.example. dig.out.test$n || ret=1 +if [ $ret -ne 0 ]; then echo_i "failed"; fi +status=$((status+ret)) + ########################################################################## echo_i "Testing having a regular zone and a zone in catalog zone of the same name" n=$((n+1)) @@ -2109,130 +2233,6 @@ wait_for_soa @10.53.0.2 dom15.example. dig.out.test$n || ret=1 if [ $ret -ne 0 ]; then echo_i "failed"; fi status=$((status+ret)) -########################################################################## -echo_i "Testing recreation of a manually deleted zone after a reload" -n=$((n+1)) -echo_i "checking that dom16.example. is not served by primary ($n)" -ret=0 -wait_for_no_soa @10.53.0.1 dom16.example. dig.out.test$n || ret=1 -if [ $ret -ne 0 ]; then echo_i "failed"; fi -status=$((status+ret)) - -n=$((n+1)) -echo_i "Adding a domain dom16.example. to primary ns1 via RNDC ($n)" -ret=0 -echo "@ 3600 IN SOA . . 1 3600 3600 3600 3600" > ns1/dom16.example.db -echo "@ IN NS invalid." >> ns1/dom16.example.db -echo "@ IN A 192.0.2.1" >> ns1/dom16.example.db -rndccmd 10.53.0.1 addzone dom16.example. in default '{type primary; file "dom16.example.db";};' || ret=1 -if [ $ret -ne 0 ]; then echo_i "failed"; fi -status=$((status+ret)) - -n=$((n+1)) -echo_i "checking that dom16.example. is now served by primary ns1 ($n)" -ret=0 -wait_for_soa @10.53.0.1 dom16.example. dig.out.test$n || ret=1 -if [ $ret -ne 0 ]; then echo_i "failed"; fi -status=$((status+ret)) - -nextpart ns2/named.run >/dev/null - -n=$((n+1)) -echo_i "Adding domain dom16.example. to catalog1 zone with ns1 as primary ($n)" -ret=0 -$NSUPDATE -d <> nsupdate.out.test$n 2>&1 || ret=1 - server 10.53.0.1 ${PORT} - update add efe725d0cf430ffb113b9bcf59266f066a21216b.zones.catalog1.example. 3600 IN PTR dom16.example. - update add masters.efe725d0cf430ffb113b9bcf59266f066a21216b.zones.catalog1.example. 3600 IN A 10.53.0.1 - send -END -if [ $ret -ne 0 ]; then echo_i "failed"; fi -status=$((status+ret)) - -n=$((n+1)) -echo_i "waiting for secondary to sync up ($n)" -ret=0 -wait_for_message ns2/named.run "catz: adding zone 'dom16.example' from catalog 'catalog1.example'" && -wait_for_message ns2/named.run "transfer of 'dom16.example/IN/default' from 10.53.0.1#${PORT}: Transfer status: success" || ret=1 -if [ $ret -ne 0 ]; then echo_i "failed"; fi -status=$((status+ret)) - -nextpart ns2/named.run >/dev/null - -n=$((n+1)) -echo_i "checking that dom16.example. is served by secondary and that it's the one from ns1 ($n)" -ret=0 -wait_for_a @10.53.0.2 dom16.example. dig.out.test$n || ret=1 -grep "192.0.2.1" dig.out.test$n > /dev/null || ret=1 -if [ $ret -ne 0 ]; then echo_i "failed"; fi -status=$((status+ret)) - -nextpart ns2/named.run >/dev/null - -echo_i "Deleting dom16.example. from secondary ns2 via RNDC ($n)" -ret=0 -rndccmd 10.53.0.2 delzone dom16.example. in default >/dev/null 2>&1 || ret=1 -if [ $ret -ne 0 ]; then echo_i "failed"; fi -status=$((status+ret)) - -n=$((n+1)) -echo_i "checking that dom16.example. is no longer served by secondary ($n)" -ret=0 -wait_for_no_soa @10.53.0.2 dom16.example. dig.out.test$n || ret=1 -if [ $ret -ne 0 ]; then echo_i "failed"; fi -status=$((status+ret)) - -nextpart ns2/named.run >/dev/null - -echo_i "Reloading secondary ns2 via RNDC ($n)" -ret=0 -rndccmd 10.53.0.2 reload >/dev/null 2>&1 || ret=1 -if [ $ret -ne 0 ]; then echo_i "failed"; fi -status=$((status+ret)) - -n=$((n+1)) -echo_i "waiting for secondary to sync up ($n)" -ret=0 -wait_for_message ns2/named.run "catz: update_from_db: new zone merged" || ret=1 -if [ $ret -ne 0 ]; then echo_i "failed"; fi -status=$((status+ret)) - -n=$((n+1)) -echo_i "checking that dom16.example. is served by secondary and that it's the one from ns1 ($n)" -ret=0 -wait_for_a @10.53.0.2 dom16.example. dig.out.test$n || ret=1 -grep "192.0.2.1" dig.out.test$n > /dev/null || ret=1 -if [ $ret -ne 0 ]; then echo_i "failed"; fi -status=$((status+ret)) - -nextpart ns2/named.run >/dev/null - -n=$((n+1)) -echo_i "Deleting domain dom16.example. from catalog1 ($n)" -ret=0 -$NSUPDATE -d <> nsupdate.out.test$n 2>&1 || ret=1 - server 10.53.0.1 ${PORT} - update delete efe725d0cf430ffb113b9bcf59266f066a21216b.zones.catalog1.example. 3600 IN PTR dom16.example. - update delete masters.efe725d0cf430ffb113b9bcf59266f066a21216b.zones.catalog1.example. 3600 IN A 10.53.0.1 - send -END -if [ $ret -ne 0 ]; then echo_i "failed"; fi -status=$((status+ret)) - -n=$((n+1)) -echo_i "waiting for secondary to sync up ($n)" -ret=0 -wait_for_message ns2/named.run "catz: update_from_db: new zone merged" || ret=1 -if [ $ret -ne 0 ]; then echo_i "failed"; fi -status=$((status+ret)) - -n=$((n+1)) -echo_i "checking that dom16.example. is no longer served by secondary ($n)" -ret=0 -wait_for_no_soa @10.53.0.2 dom16.example. dig.out.test$n || ret=1 -if [ $ret -ne 0 ]; then echo_i "failed"; fi -status=$((status+ret)) - ########################################################################## echo_i "Testing custom properties version '1' and version '2' syntaxes" n=$((n+1))