diff --git a/CHANGES b/CHANGES index d34243d064..02a932688b 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,11 @@ +5033. [bug] When adding NTAs to multiple views using "rndc nta", + the text returned via rndc was incorrectly terminated + after the first line, making it look as if only one + NTA had been added. Also, it was not possible to + differentiate between views with the same name but + different classes; this has been corrected with the + addition of a "-class" option. [GL #105] + 5032. [func] Add krb5-selfsub and ms-selfsub update policy rules. [GL #511] diff --git a/bin/named/server.c b/bin/named/server.c index 602023c914..374a365ecb 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -938,7 +938,8 @@ configure_view_dnsseckeys(dns_view_t *view, const cfg_obj_t *vconfig, /* We don't need trust anchors for the _bind view */ if (strcmp(view->name, "_bind") == 0 && - view->rdclass == dns_rdataclass_chaos) { + view->rdclass == dns_rdataclass_chaos) + { return (ISC_R_SUCCESS); } @@ -14231,6 +14232,7 @@ named_server_nta(named_server_t *server, isc_lex_t *lex, dns_name_t *fname; dns_ttl_t ntattl; bool ttlset = false, excl = false; + dns_rdataclass_t rdclass = dns_rdataclass_in; UNUSED(force); @@ -14238,18 +14240,20 @@ named_server_nta(named_server_t *server, isc_lex_t *lex, /* Skip the command name. */ ptr = next_token(lex, text); - if (ptr == NULL) + if (ptr == NULL) { return (ISC_R_UNEXPECTEDEND); + } for (;;) { /* Check for options */ ptr = next_token(lex, text); - if (ptr == NULL) + if (ptr == NULL) { return (ISC_R_UNEXPECTEDEND); + } - if (argcheck(ptr, "dump")) + if (argcheck(ptr, "dump")) { dump = true; - else if (argcheck(ptr, "remove")) { + } else if (argcheck(ptr, "remove")) { ntattl = 0; ttlset = true; } else if (argcheck(ptr, "force")) { @@ -14279,8 +14283,22 @@ named_server_nta(named_server_t *server, isc_lex_t *lex, ttlset = true; continue; - } else + } else if (argcheck(ptr, "class")) { + isc_textregion_t tr; + + ptr = next_token(lex, text); + if (ptr == NULL) { + msg = "No class specified"; + CHECK(ISC_R_UNEXPECTEDEND); + } + + tr.base = ptr; + tr.length = strlen(ptr); + CHECK(dns_rdataclass_fromtext(&rdclass, &tr)); + continue; + } else { nametext = ptr; + } break; } @@ -14293,11 +14311,13 @@ named_server_nta(named_server_t *server, isc_lex_t *lex, view != NULL; view = ISC_LIST_NEXT(view, link)) { - if (ntatable != NULL) + if (ntatable != NULL) { dns_ntatable_detach(&ntatable); + } result = dns_view_getntatable(view, &ntatable); - if (result == ISC_R_NOTFOUND) + if (result == ISC_R_NOTFOUND) { continue; + } CHECK(dns_ntatable_totext(ntatable, text)); } CHECK(putnull(text)); @@ -14314,17 +14334,19 @@ named_server_nta(named_server_t *server, isc_lex_t *lex, } /* Get the NTA name. */ - if (nametext == NULL) + if (nametext == NULL) { nametext = next_token(lex, text); - if (nametext == NULL) + } + if (nametext == NULL) { return (ISC_R_UNEXPECTEDEND); + } /* Copy nametext as it'll be overwritten by next_token() */ strlcpy(namebuf, nametext, DNS_NAME_FORMATSIZE); - if (strcmp(namebuf, ".") == 0) + if (strcmp(namebuf, ".") == 0) { ntaname = dns_rootname; - else { + } else { isc_buffer_t b; isc_buffer_init(&b, namebuf, strlen(namebuf)); isc_buffer_add(&b, strlen(namebuf)); @@ -14344,18 +14366,27 @@ named_server_nta(named_server_t *server, isc_lex_t *lex, view != NULL; view = ISC_LIST_NEXT(view, link)) { - if (viewname != NULL && - strcmp(view->name, viewname) != 0) - continue; + static bool first = true; - if (view->nta_lifetime == 0) + if (viewname != NULL && strcmp(view->name, viewname) != 0) { continue; + } - if (!ttlset) + if (view->rdclass != rdclass && rdclass != dns_rdataclass_any) { + continue; + } + + if (view->nta_lifetime == 0) { + continue; + } + + if (!ttlset) { ntattl = view->nta_lifetime; + } - if (ntatable != NULL) + if (ntatable != NULL) { dns_ntatable_detach(&ntatable); + } result = dns_view_getntatable(view, &ntatable); if (result == ISC_R_NOTFOUND) { @@ -14378,6 +14409,11 @@ named_server_nta(named_server_t *server, isc_lex_t *lex, isc_time_set(&t, when, 0); isc_time_formattimestamp(&t, tbuf, sizeof(tbuf)); + if (!first) { + CHECK(putstr(text, "\n")); + } + first = false; + CHECK(putstr(text, "Negative trust anchor added: ")); CHECK(putstr(text, namebuf)); CHECK(putstr(text, "/")); @@ -14392,6 +14428,11 @@ named_server_nta(named_server_t *server, isc_lex_t *lex, } else { CHECK(dns_ntatable_delete(ntatable, ntaname)); + if (!first) { + CHECK(putstr(text, "\n")); + } + first = false; + CHECK(putstr(text, "Negative trust anchor removed: ")); CHECK(putstr(text, namebuf)); CHECK(putstr(text, "/")); @@ -14411,20 +14452,21 @@ named_server_nta(named_server_t *server, isc_lex_t *lex, "for view '%s': %s", view->name, isc_result_totext(result)); } - - CHECK(putnull(text)); - } + CHECK(putnull(text)); + cleanup: if (msg != NULL) { (void) putstr(text, msg); (void) putnull(text); } - if (excl) + if (excl) { isc_task_endexclusive(server->task); - if (ntatable != NULL) + } + if (ntatable != NULL) { dns_ntatable_detach(&ntatable); + } return (result); } diff --git a/bin/rndc/rndc.docbook b/bin/rndc/rndc.docbook index ccf5f8f477..2ab4d6d2db 100644 --- a/bin/rndc/rndc.docbook +++ b/bin/rndc/rndc.docbook @@ -575,7 +575,7 @@ nta - ( -d | -f | -r | -l duration) + ( -class class | -dump | -force | -remove | -lifetime duration) domain view @@ -623,7 +623,7 @@ is equivalent to . - If is used, any other arguments + If the is used, any other arguments are ignored, and a list of existing NTAs is printed (note that this may include NTAs that are expired but have not yet been cleaned up). @@ -640,10 +640,15 @@ lifetime, regardless of whether data could be validated if the NTA were not present. + + The view class can be specified with . + The default is class IN, which is + the only class for which DNSSEC is currently supported. + All of these options can be shortened, i.e., to , , , - and . + , and . diff --git a/bin/tests/system/rndc/clean.sh b/bin/tests/system/rndc/clean.sh index 65393720bd..3472273c27 100644 --- a/bin/tests/system/rndc/clean.sh +++ b/bin/tests/system/rndc/clean.sh @@ -12,7 +12,7 @@ rm -f dig.out.*.test* rm -f ns*/named.lock rm -f ns*/named.memstats -rm -f ns*/named.run +rm -f ns*/named.run ns*/named.run.prev rm -f ns2/named.stats rm -f ns2/nil.db ns2/other.db ns2/static.db ns2/*.jnl rm -f ns2/session.key @@ -25,3 +25,4 @@ rm -f nsupdate.out.*.test* rm -f python.out.*.test* rm -f rndc.out.*.test* rm -f ns*/managed-keys.bind* ns*/*.mkeys* +rm -f ns*/*.nta diff --git a/bin/tests/system/rndc/ns3/named.conf.in b/bin/tests/system/rndc/ns3/named.conf.in index e8dbfc4aeb..dd3529559e 100644 --- a/bin/tests/system/rndc/ns3/named.conf.in +++ b/bin/tests/system/rndc/ns3/named.conf.in @@ -14,7 +14,6 @@ options { pid-file "named.pid"; listen-on { 10.53.0.3; }; listen-on-v6 { none; }; - recursion no; }; key rndc_key { @@ -31,8 +30,17 @@ controls { inet 10.53.0.3 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; }; +view all { + match-clients { any; }; -zone "." { - type hint; - file "../../common/root.hint"; + recursion no; + + zone "." { + type hint; + file "../../common/root.hint"; + }; +}; + +view none { + match-clients { none; }; }; diff --git a/bin/tests/system/rndc/tests.sh b/bin/tests/system/rndc/tests.sh index 488ee841a6..b9dda3827e 100644 --- a/bin/tests/system/rndc/tests.sh +++ b/bin/tests/system/rndc/tests.sh @@ -486,6 +486,22 @@ grep "NTA lifetime cannot exceed one week" rndc.out.4.test$n > /dev/null || ret= if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` +n=`expr $n + 1` +echo_i "testing rndc nta -class option ($n)" +ret=0 +nextpart ns4/named.run > /dev/null +$RNDCCMD4 nta -c in nta1.example > rndc.out.1.test$n 2>&1 +nextpart ns4/named.run | grep "added NTA 'nta1.example'" > /dev/null || ret=1 +$RNDCCMD4 nta -c any nta1.example > rndc.out.2.test$n 2>&1 +nextpart ns4/named.run | grep "added NTA 'nta1.example'" > /dev/null || ret=1 +$RNDCCMD4 nta -c ch nta1.example > rndc.out.3.test$n 2>&1 +nextpart ns4/named.run | grep "added NTA 'nta1.example'" > /dev/null && ret=1 +$RNDCCMD4 nta -c fake nta1.example > rndc.out.4.test$n 2>&1 +nextpart ns4/named.run | grep "added NTA 'nta1.example'" > /dev/null && ret=1 +grep 'unknown class' rndc.out.4.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi +status=`expr $status + $ret` + for i in 512 1024 2048 4096 8192 16384 32768 65536 131072 262144 524288 do n=`expr $n + 1` @@ -656,5 +672,14 @@ grep "address family not supported" rndc.out.1.test$n > /dev/null || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` +n=`expr $n + 1` +echo_i "check rndc nta reports adding to multiple views ($n)" +ret=0 +$RNDCCMD 10.53.0.3 nta test.com > rndc.out.test$n 2>&1 || ret=1 +lines=`cat rndc.out.test$n | wc -l` +[ ${lines:-0} -eq 2 ] || 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/doc/arm/notes.xml b/doc/arm/notes.xml index 96d6c2a900..a9f702a9ed 100644 --- a/doc/arm/notes.xml +++ b/doc/arm/notes.xml @@ -465,6 +465,14 @@ instead of using the resolver category. + + + The rndc nta command could not differentiate + between views of the same name but different class; this + has been corrected with the addition of a -class + option. [GL #105] + + @@ -497,6 +505,15 @@ to be non-resolvable. [GL #390] + + + When a negative trust anchor was added to multiple views + using rndc nta, the text returned via + rndc was incorrectly truncated after the + first line, making it appear that only one NTA had been + added. This has been fixed. [GL #105] + + named now rejects excessively large