From: Curtis Blackburn Date: Fri, 10 May 2013 21:12:27 +0000 (-0500) Subject: 3573. [bug] "rndc addzone" and "rndc delzone" incorrectly handled zone X-Git-Tag: v9.10.0a1~342 X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=428dd5c588cfe0dc1519af728e6e75c10aeb4439;p=thirdparty%2Fbind9.git 3573. [bug] "rndc addzone" and "rndc delzone" incorrectly handled zone names containing punctuation marks and other nonstandard characters. [RT #33419] --- diff --git a/CHANGES b/CHANGES index e8acb429ed5..4e19c572d64 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +3573. [bug] "rndc addzone" and "rndc delzone" incorrectly handled zone + names containing punctuation marks and other nonstandard + characters. [RT #33419] + 3572. [func] Threads are now enabled by default on most operating systems. [RT #25483] diff --git a/bin/named/server.c b/bin/named/server.c index b6c1d7aadef..98662e8a07b 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -8280,11 +8280,13 @@ ns_server_add_zone(ns_server_t *server, char *args) { const char *viewname = NULL; dns_rdataclass_t rdclass; dns_view_t *view = 0; - isc_buffer_t buf, *nbuf = NULL; - dns_name_t dnsname; + isc_buffer_t buf; + dns_fixedname_t fname; + dns_name_t *dnsname; dns_zone_t *zone = NULL; FILE *fp = NULL; struct cfg_context *cfg = NULL; + char namebuf[DNS_NAME_FORMATSIZE]; /* Try to parse the argument string */ arglen = strlen(args); @@ -8298,10 +8300,10 @@ ns_server_add_zone(ns_server_t *server, char *args) { zonename = cfg_obj_asstring(cfg_tuple_get(parms, "name")); isc_buffer_constinit(&buf, zonename, strlen(zonename)); isc_buffer_add(&buf, strlen(zonename)); - dns_name_init(&dnsname, NULL); - isc_buffer_allocate(server->mctx, &nbuf, 256); - dns_name_setbuffer(&dnsname, nbuf); - CHECK(dns_name_fromtext(&dnsname, &buf, dns_rootname, ISC_FALSE, NULL)); + + dns_fixedname_init(&fname); + dnsname = dns_fixedname_name(&fname); + CHECK(dns_name_fromtext(dnsname, &buf, dns_rootname, ISC_FALSE, NULL)); /* Make sense of optional class argument */ obj = cfg_tuple_get(parms, "class"); @@ -8330,7 +8332,7 @@ ns_server_add_zone(ns_server_t *server, char *args) { } /* Zone shouldn't already exist */ - result = dns_zt_find(view->zonetable, &dnsname, 0, NULL, &zone); + result = dns_zt_find(view->zonetable, dnsname, 0, NULL, &zone); if (result == ISC_R_SUCCESS) { result = ISC_R_EXISTS; goto cleanup; @@ -8372,7 +8374,7 @@ ns_server_add_zone(ns_server_t *server, char *args) { goto cleanup; /* Is it there yet? */ - CHECK(dns_zt_find(view->zonetable, &dnsname, 0, NULL, &zone)); + CHECK(dns_zt_find(view->zonetable, dnsname, 0, NULL, &zone)); /* * Load the zone from the master file. If this fails, we'll @@ -8400,10 +8402,13 @@ ns_server_add_zone(ns_server_t *server, char *args) { /* Flag the zone as having been added at runtime */ dns_zone_setadded(zone, ISC_TRUE); - /* Emit just the zone name from args */ - CHECK(isc_stdio_write("zone ", 5, 1, fp, NULL)); - CHECK(isc_stdio_write(zonename, strlen(zonename), 1, fp, NULL)); - CHECK(isc_stdio_write(" ", 1, 1, fp, NULL)); + /* Emit the zone name, quoted and escaped */ + isc_buffer_init(&buf, namebuf, sizeof(namebuf)); + CHECK(dns_name_totext(dnsname, ISC_TRUE, &buf)); + isc_buffer_putuint8(&buf, 0); + CHECK(isc_stdio_write("zone \"", 6, 1, fp, NULL)); + CHECK(isc_stdio_write(namebuf, strlen(namebuf), 1, fp, NULL)); + CHECK(isc_stdio_write("\" ", 2, 1, fp, NULL)); /* Classname, if not default */ if (classname != NULL && *classname != '\0') { @@ -8447,8 +8452,6 @@ ns_server_add_zone(ns_server_t *server, char *args) { dns_zone_detach(&zone); if (view != NULL) dns_view_detach(&view); - if (nbuf != NULL) - isc_buffer_free(&nbuf); return (result); } diff --git a/bin/tests/system/addzone/ns2/added.db b/bin/tests/system/addzone/ns2/added.db index 4c734cb6dac..3aa1debfeed 100644 --- a/bin/tests/system/addzone/ns2/added.db +++ b/bin/tests/system/addzone/ns2/added.db @@ -14,7 +14,7 @@ ; $Id: added.db,v 1.2 2010/08/11 18:14:18 each Exp $ -$ORIGIN added.example. +;$ORIGIN added.example. $TTL 300 ; 5 minutes @ IN SOA mname1. . ( 1 ; serial diff --git a/bin/tests/system/addzone/tests.sh b/bin/tests/system/addzone/tests.sh old mode 100644 new mode 100755 index 555a37bb226..28e9c657100 --- a/bin/tests/system/addzone/tests.sh +++ b/bin/tests/system/addzone/tests.sh @@ -51,6 +51,26 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` +echo "I:adding a zone that requires quotes ($n)" +ret=0 +$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 addzone '"32/1.0.0.127-in-addr.added.example" { check-names ignore; type master; file "added.db"; };' 2>&1 | sed 's/^/I:ns2 /' +$DIG $DIGOPTS @10.53.0.2 "a.32/1.0.0.127-in-addr.added.example" a > dig.out.ns2.$n || ret=1 +grep 'status: NOERROR' dig.out.ns2.$n > /dev/null || ret=1 +grep '^a.32/1.0.0.127-in-addr.added.example' dig.out.ns2.$n > /dev/null || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:adding a zone with a quote in the name ($n)" +ret=0 +$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 addzone '"foo\"bar.example" { check-names ignore; type master; file "added.db"; };' 2>&1 | sed 's/^/I:ns2 /' +$DIG $DIGOPTS @10.53.0.2 "a.foo\"bar.example" a > dig.out.ns2.$n || ret=1 +grep 'status: NOERROR' dig.out.ns2.$n > /dev/null || ret=1 +grep '^a.foo\\"bar.example' dig.out.ns2.$n > /dev/null || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + echo "I:adding new zone with missing master file ($n)" ret=0 $DIG $DIGOPTS +all @10.53.0.2 a.missing.example a > dig.out.ns2.pre.$n || ret=1 @@ -84,6 +104,16 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` +echo "I:deleting newly added zone with escaped quote ($n)" +ret=0 +$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 delzone "foo\\\"bar.example" 2>&1 | sed 's/^/I:ns2 /' +$DIG $DIGOPTS @10.53.0.2 "a.foo\"bar.example" a > dig.out.ns2.$n +grep 'status: REFUSED' dig.out.ns2.$n > /dev/null || ret=1 +grep "^a.foo\"bar.example" dig.out.ns2.$n > /dev/null && ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + echo "I:attempt to delete a normally-loaded zone ($n)" ret=0 $RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 delzone normal.example 2> rndc.out.ns2.$n