diff --git a/CHANGES b/CHANGES index f22abfe05e..cf53b7b0ca 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +3585. [func] "rndc delzone -clean" option removes zone files + when deleting a zone. [RT #33570] + 3584. [security] Caching data from an incompletely signed zone could trigger an assertion failure in resolver.c [RT #33690] diff --git a/bin/named/server.c b/bin/named/server.c index 2a705fba66..5828827e3a 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -8479,22 +8479,32 @@ inuse(const char* file, isc_boolean_t first, isc_buffer_t *text) { */ isc_result_t ns_server_del_zone(ns_server_t *server, char *args, isc_buffer_t *text) { - isc_result_t result; - dns_zone_t *zone = NULL; - dns_zone_t *raw = NULL; - dns_zone_t *mayberaw; - dns_view_t *view = NULL; - dns_db_t *dbp = NULL; - const char *filename = NULL; - char *tmpname = NULL; - char buf[1024]; - const char *zonename = NULL; - size_t znamelen = 0; - FILE *ifp = NULL, *ofp = NULL; - isc_boolean_t exclusive = ISC_FALSE; + isc_result_t result; + dns_zone_t *zone = NULL; + dns_zone_t *raw = NULL; + dns_zone_t *mayberaw; + dns_view_t *view = NULL; + dns_db_t *dbp = NULL; + const char *filename = NULL; + char *tmpname = NULL; + char buf[1024]; + const char *zonename = NULL; + size_t znamelen = 0; + FILE *ifp = NULL, *ofp = NULL; + isc_boolean_t exclusive = ISC_FALSE; + isc_boolean_t cleanup = ISC_FALSE; + const char *file, *arg; /* Parse parameters */ - CHECK(zone_from_args(server, args, NULL, &zone, &zonename, ISC_TRUE)); + (void) next_token(&args, " \t"); + arg = next_token(&args, " \t"); + if (arg != NULL && + (strcmp(arg, "-clean") == 0 || strcmp(arg, "-clear") == 0)) { + cleanup = ISC_TRUE; + arg = next_token(&args, " \t"); + } + + CHECK(zone_from_args(server, args, arg, &zone, &zonename, ISC_FALSE)); if (zone == NULL) { result = ISC_R_UNEXPECTEDEND; @@ -8620,9 +8630,30 @@ ns_server_del_zone(ns_server_t *server, char *args, isc_buffer_t *text) { /* Clean up stub / slave zone files */ dns_zone_getraw(zone, &raw); mayberaw = (raw != NULL) ? raw : zone; - if (dns_zone_gettype(mayberaw) == dns_zone_slave || - dns_zone_gettype(mayberaw) == dns_zone_stub) { - const char *file; + if (cleanup) { + file = dns_zone_getfile(mayberaw); + if (isc_file_exists(file)) + isc_file_remove(file); + + file = dns_zone_getjournal(mayberaw); + if (isc_file_exists(file)) + isc_file_remove(file); + + if (zone != mayberaw) { + file = dns_zone_getfile(zone); + if (isc_file_exists(file)) + isc_file_remove(file); + + file = dns_zone_getjournal(zone); + if (isc_file_exists(file)) + isc_file_remove(file); + } + isc_buffer_putstr(text, "zone "); + isc_buffer_putstr(text, zonename); + isc_buffer_putstr(text, " and associated files deleted"); + } else if (dns_zone_gettype(mayberaw) == dns_zone_slave || + dns_zone_gettype(mayberaw) == dns_zone_stub) + { isc_boolean_t first; file = dns_zone_getfile(mayberaw); diff --git a/bin/rndc/rndc.c b/bin/rndc/rndc.c index 0f69f5fcea..036b3544c7 100644 --- a/bin/rndc/rndc.c +++ b/bin/rndc/rndc.c @@ -159,9 +159,9 @@ command is one of the following:\n\ Delete a TKEY-negotiated TSIG key.\n\ validation newstate [view]\n\ Enable / disable DNSSEC validation.\n\ - addzone [\"file\"] zone [class [view]] { zone-options }\n\ + addzone zone [class [view]] { zone-options }\n\ Add zone to given view. Requires new-zone-file option.\n\ - delzone [\"file\"] zone [class [view]]\n\ + delzone [-clean] zone [class [view]]\n\ Removes zone from given view. Requires new-zone-file option.\n\ signing -list zone [class [view]]\n\ List the private records showing the state of DNSSEC\n\ diff --git a/bin/tests/system/addzone/tests.sh b/bin/tests/system/addzone/tests.sh index 28e9c65710..c7c22ec97d 100755 --- a/bin/tests/system/addzone/tests.sh +++ b/bin/tests/system/addzone/tests.sh @@ -182,6 +182,39 @@ grep '^inlineslave.bk.signed$' rndc.out2.test$n > /dev/null || { n=`expr $n + 1` status=`expr $status + $ret` +echo "I:restoring slave zone with inline signing ($n)" +$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 addzone 'inlineslave.example { type slave; masters { 10.53.0.1; }; file "inlineslave.bk"; inline-signing yes; };' 2>&1 | sed 's/^/I:ns2 /' +for i in 1 2 3 4 5 +do +ret=0 +$DIG $DIGOPTS @10.53.0.2 a.inlineslave.example a > dig.out.ns2.$n || ret=1 +grep 'status: NOERROR' dig.out.ns2.$n > /dev/null || ret=1 +grep '^a.inlineslave.example' dig.out.ns2.$n > /dev/null || ret=1 +[ $ret = 0 ] && break +sleep 1 +done +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:deleting slave zone with automatic zone file removal ($n)" +ret=0 +for i in 0 1 2 3 4 5 6 7 8 9 +do + test -f ns2/inlineslave.bk.signed -a -f ns2/inlineslave.bk && break + sleep 1 +done +$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 delzone -clean inlineslave.example 2>&1 > /dev/null +for i in 0 1 2 3 4 5 6 7 8 9 +do + ret=0 + test -f ns2/inlineslave.bk.signed -a -f ns2/inlineslave.bk && ret=1 + [ $ret = 0 ] && break + sleep 1 +done +n=`expr $n + 1` +status=`expr $status + $ret` + echo "I:reconfiguring server with multiple views" rm -f ns2/named.conf cp -f ns2/named2.conf ns2/named.conf diff --git a/doc/arm/Bv9ARM-book.xml b/doc/arm/Bv9ARM-book.xml index 0213beb150..7c06fbca61 100644 --- a/doc/arm/Bv9ARM-book.xml +++ b/doc/arm/Bv9ARM-book.xml @@ -1597,6 +1597,7 @@ zone "eng.example.com" { delzone + -clean zone class view @@ -1606,7 +1607,17 @@ zone "eng.example.com" { Delete a zone while the server is running. Only zones that were originally added via rndc addzone can be deleted - in this matter. + in this matter. + + + If the is specified, + the zone's master file (and journal file, if any) + will be deleted along with the zone. Without the + option, zone files must + be cleaned up by hand. (If the zone is of + type "slave" or "stub", the files needing to + be cleaned up will be reported in the output + of the rndc delzone command.)