diff --git a/CHANGES b/CHANGES
index 06d63ee859..255fd9c81b 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,13 @@
+5080. [func] Improvements to "rndc nta" user interface:
+ - catch and report invalid command line options
+ - when removing an NTA from all views, do not
+ abort with an error if the NTA was not found
+ in one of the views
+ - include the view name in "rndc nta -dump"
+ output, for consistency with the add and remove
+ actions
+ Thanks to Tony Finch. [GL !816]
+
5079. [func] Disable IDN processing in dig and nslookup
when not on a tty. [GL #653]
diff --git a/bin/named/server.c b/bin/named/server.c
index c1839f98fe..e9773fba55 100644
--- a/bin/named/server.c
+++ b/bin/named/server.c
@@ -10877,7 +10877,7 @@ named_server_dumpsecroots(named_server_t *server, isc_lex_t *lex,
continue;
}
CHECK(putstr(text, "\n Negative trust anchors:\n\n"));
- CHECK(dns_ntatable_totext(ntatable, text));
+ CHECK(dns_ntatable_totext(ntatable, NULL, text));
}
if (ptr != NULL)
ptr = next_token(lex, text);
@@ -14314,6 +14314,7 @@ named_server_nta(named_server_t *server, isc_lex_t *lex,
isc_result_t result = ISC_R_SUCCESS;
char *ptr, *nametext = NULL, *viewname;
char namebuf[DNS_NAME_FORMATSIZE];
+ char viewbuf[DNS_NAME_FORMATSIZE];
isc_stdtime_t now, when;
isc_time_t t;
char tbuf[64];
@@ -14323,8 +14324,9 @@ named_server_nta(named_server_t *server, isc_lex_t *lex,
const dns_name_t *ntaname;
dns_name_t *fname;
dns_ttl_t ntattl;
- bool ttlset = false, excl = false;
+ bool ttlset = false, excl = false, viewfound = false;
dns_rdataclass_t rdclass = dns_rdataclass_in;
+ bool first = true;
UNUSED(force);
@@ -14337,18 +14339,24 @@ named_server_nta(named_server_t *server, isc_lex_t *lex,
}
for (;;) {
+ bool opts = true;
+
/* Check for options */
ptr = next_token(lex, text);
if (ptr == NULL) {
return (ISC_R_UNEXPECTEDEND);
}
- if (argcheck(ptr, "dump")) {
+ if (!opts) {
+ nametext = ptr;
+ } else if (strcmp(ptr, "--") == 0) {
+ opts = false;
+ } else if (argcheck(ptr, "dump")) {
dump = true;
} else if (argcheck(ptr, "remove")) {
ntattl = 0;
ttlset = true;
- } else if (argcheck(ptr, "force")) {
+ } else if (opts && argcheck(ptr, "force")) {
force = true;
continue;
} else if (argcheck(ptr, "lifetime")) {
@@ -14388,6 +14396,9 @@ named_server_nta(named_server_t *server, isc_lex_t *lex,
tr.length = strlen(ptr);
CHECK(dns_rdataclass_fromtext(&rdclass, &tr));
continue;
+ } else if (ptr[0] == '-') {
+ msg = "Unknown option";
+ CHECK(DNS_R_SYNTAX);
} else {
nametext = ptr;
}
@@ -14410,7 +14421,8 @@ named_server_nta(named_server_t *server, isc_lex_t *lex,
if (result == ISC_R_NOTFOUND) {
continue;
}
- CHECK(dns_ntatable_totext(ntatable, text));
+
+ CHECK(dns_ntatable_totext(ntatable, view->name, text));
}
CHECK(putnull(text));
@@ -14448,6 +14460,14 @@ named_server_nta(named_server_t *server, isc_lex_t *lex,
/* Look for the view name. */
viewname = next_token(lex, text);
+ if (viewname != NULL) {
+ strlcpy(viewbuf, viewname, DNS_NAME_FORMATSIZE);
+ viewname = viewbuf;
+ }
+
+ if (next_token(lex, text) != NULL) {
+ CHECK(DNS_R_SYNTAX);
+ }
isc_stdtime_get(&now);
@@ -14458,11 +14478,10 @@ named_server_nta(named_server_t *server, isc_lex_t *lex,
view != NULL;
view = ISC_LIST_NEXT(view, link))
{
- static bool first = true;
-
if (viewname != NULL && strcmp(view->name, viewname) != 0) {
continue;
}
+ viewfound = true;
if (view->rdclass != rdclass && rdclass != dns_rdataclass_any) {
continue;
@@ -14518,22 +14537,37 @@ named_server_nta(named_server_t *server, isc_lex_t *lex,
"added NTA '%s' (%d sec) in view '%s'",
namebuf, ntattl, view->name);
} else {
- CHECK(dns_ntatable_delete(ntatable, ntaname));
+ bool removed;
+
+ result = dns_ntatable_delete(ntatable, ntaname);
+ if (result == ISC_R_SUCCESS) {
+ removed = true;
+ } else if (result == ISC_R_NOTFOUND) {
+ removed = false;
+ } else {
+ goto cleanup;
+ }
if (!first) {
CHECK(putstr(text, "\n"));
}
first = false;
- CHECK(putstr(text, "Negative trust anchor removed: "));
+ CHECK(putstr(text, "Negative trust anchor "));
+ CHECK(putstr(text, removed ? "removed: "
+ : "not found: "));
CHECK(putstr(text, namebuf));
CHECK(putstr(text, "/"));
CHECK(putstr(text, view->name));
- isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
- NAMED_LOGMODULE_SERVER, ISC_LOG_INFO,
- "removed NTA '%s' in view %s",
- namebuf, view->name);
+ if (removed) {
+ isc_log_write(named_g_lctx,
+ NAMED_LOGCATEGORY_GENERAL,
+ NAMED_LOGMODULE_SERVER,
+ ISC_LOG_INFO,
+ "removed NTA '%s' in view %s",
+ namebuf, view->name);
+ }
}
result = dns_view_saventa(view);
@@ -14546,6 +14580,11 @@ named_server_nta(named_server_t *server, isc_lex_t *lex,
}
}
+ if (!viewfound) {
+ msg = "No such view";
+ CHECK(ISC_R_NOTFOUND);
+ }
+
CHECK(putnull(text));
cleanup:
@@ -14553,6 +14592,7 @@ named_server_nta(named_server_t *server, isc_lex_t *lex,
(void) putstr(text, msg);
(void) putnull(text);
}
+
if (excl) {
isc_task_endexclusive(server->task);
}
diff --git a/bin/rndc/rndc.docbook b/bin/rndc/rndc.docbook
index 047e5c0199..999d408943 100644
--- a/bin/rndc/rndc.docbook
+++ b/bin/rndc/rndc.docbook
@@ -650,6 +650,12 @@
, , ,
, and .
+
+ Unrecognized options are treated as errors. To reference
+ a domain or view name that begins with a hyphen,
+ use a double-hyphen on the command line to indicate the
+ end of options.
+
diff --git a/bin/tests/system/dnssec/tests.sh b/bin/tests/system/dnssec/tests.sh
index f3490027a3..6e2369f696 100644
--- a/bin/tests/system/dnssec/tests.sh
+++ b/bin/tests/system/dnssec/tests.sh
@@ -1873,8 +1873,8 @@ $PERL -e 'my $delay = '$start' + 13 - time(); select(undef, undef, undef, $delay
$RNDCCMD 10.53.0.4 nta -d > rndc.out.ns4.test$n._11
lines=`grep " expiry " rndc.out.ns4.test$n._11 | wc -l`
[ "$lines" -le 2 ] || ret=1
-grep "bogus.example: expiry" rndc.out.ns4.test$n._11 > /dev/null || ret=1
-grep "badds.example: expiry" rndc.out.ns4.test$n._11 > /dev/null && ret=1
+grep "bogus.example/_default: expiry" rndc.out.ns4.test$n._11 > /dev/null || ret=1
+grep "badds.example/_default: expiry" rndc.out.ns4.test$n._11 > /dev/null && ret=1
$DIG $DIGOPTS b.bogus.example. a @10.53.0.4 > dig.out.ns4.test$n.11 || ret=1
grep "status: SERVFAIL" dig.out.ns4.test$n.11 > /dev/null && ret=1
$DIG $DIGOPTS a.badds.example. a @10.53.0.4 > dig.out.ns4.test$n.12 || ret=1
@@ -1910,14 +1910,14 @@ ret=0
echo_i "testing NTA removals ($n)"
$RNDCCMD 10.53.0.4 nta badds.example 2>&1 | sed 's/^/ns4 /' | cat_i
$RNDCCMD 10.53.0.4 nta -d > rndc.out.ns4.test$n.1
-grep "badds.example: expiry" rndc.out.ns4.test$n.1 > /dev/null || ret=1
+grep "badds.example/_default: expiry" rndc.out.ns4.test$n.1 > /dev/null || ret=1
$DIG $DIGOPTS a.badds.example. a @10.53.0.4 > dig.out.ns4.test$n.1 || ret=1
grep "status: SERVFAIL" dig.out.ns4.test$n.1 > /dev/null && ret=1
grep "^a.badds.example." dig.out.ns4.test$n.1 > /dev/null || ret=1
$RNDCCMD 10.53.0.4 nta -remove badds.example > rndc.out.ns4.test$n.2
grep "Negative trust anchor removed: badds.example/_default" rndc.out.ns4.test$n.2 > /dev/null || ret=1
$RNDCCMD 10.53.0.4 nta -d > rndc.out.ns4.test$n.3
-grep "badds.example: expiry" rndc.out.ns4.test$n.3 > /dev/null && ret=1
+grep "badds.example/_default: expiry" rndc.out.ns4.test$n.3 > /dev/null && ret=1
$DIG $DIGOPTS a.badds.example. a @10.53.0.4 > dig.out.ns4.test$n.2 || ret=1
grep "status: SERVFAIL" dig.out.ns4.test$n.2 > /dev/null || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
@@ -1928,7 +1928,7 @@ echo_i "remove non-existent NTA three times"
$RNDCCMD 10.53.0.4 nta -r foo > rndc.out.ns4.test$n.4 2>&1
$RNDCCMD 10.53.0.4 nta -remove foo > rndc.out.ns4.test$n.5 2>&1
$RNDCCMD 10.53.0.4 nta -r foo > rndc.out.ns4.test$n.6 2>&1
-grep "'nta' failed: not found" rndc.out.ns4.test$n.6 > /dev/null || ret=1
+grep "not found" rndc.out.ns4.test$n.6 > /dev/null || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=`expr $status + $ret`
ret=0
@@ -2009,7 +2009,7 @@ sleep 4
$RNDCCMD 10.53.0.4 nta -d > rndc.out.ns4.test$n.3
lines=`wc -l < rndc.out.ns4.test$n.3`
[ "$lines" -eq 1 ] || ret=1
-grep "bogus.example: expiry" rndc.out.ns4.test$n.3 > /dev/null || ret=1
+grep "bogus.example/_default: expiry" rndc.out.ns4.test$n.3 > /dev/null || ret=1
$DIG $DIGOPTS b.bogus.example. a @10.53.0.4 > dig.out.ns4.test$n.4 || ret=1
grep "status: SERVFAIL" dig.out.ns4.test$n.4 > /dev/null && ret=1
grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.4 > /dev/null && ret=1
diff --git a/doc/arm/notes.xml b/doc/arm/notes.xml
index 28344833ce..6424f21f6f 100644
--- a/doc/arm/notes.xml
+++ b/doc/arm/notes.xml
@@ -547,6 +547,13 @@
added. This has been fixed. [GL #105]
+
+
+ The view name is now included in the output of
+ rndc nta -dump, for consistency with
+ other options. [GL !816]
+
+
named now rejects excessively large
diff --git a/lib/dns/include/dns/nta.h b/lib/dns/include/dns/nta.h
index 21af6499c3..cce47b0a44 100644
--- a/lib/dns/include/dns/nta.h
+++ b/lib/dns/include/dns/nta.h
@@ -182,9 +182,10 @@ dns_ntatable_covered(dns_ntatable_t *ntatable, isc_stdtime_t now,
*/
isc_result_t
-dns_ntatable_totext(dns_ntatable_t *ntatable, isc_buffer_t **buf);
+dns_ntatable_totext(dns_ntatable_t *ntatable, const char *view,
+ isc_buffer_t **buf);
/*%<
- * Dump the NTA table to buffer at 'buf'
+ * Dump the NTA table to buffer at 'buf', with view names
*
* Requires:
* \li "ntatable" is a valid table.
diff --git a/lib/dns/nta.c b/lib/dns/nta.c
index 194688f865..73674b3002 100644
--- a/lib/dns/nta.c
+++ b/lib/dns/nta.c
@@ -509,7 +509,9 @@ putstr(isc_buffer_t **b, const char *str) {
}
isc_result_t
-dns_ntatable_totext(dns_ntatable_t *ntatable, isc_buffer_t **buf) {
+dns_ntatable_totext(dns_ntatable_t *ntatable, const char *view,
+ isc_buffer_t **buf)
+{
isc_result_t result;
dns_rbtnode_t *node;
dns_rbtnodechain_t chain;
@@ -552,8 +554,10 @@ dns_ntatable_totext(dns_ntatable_t *ntatable, isc_buffer_t **buf) {
isc_time_formattimestamp(&t, tbuf,
sizeof(tbuf));
- snprintf(obuf, sizeof(obuf), "%s%s: %s %s",
+ snprintf(obuf, sizeof(obuf), "%s%s%s%s: %s %s",
first ? "" : "\n", nbuf,
+ view != NULL ? "/" : "",
+ view != NULL ? view : "",
n->expiry <= now
? "expired"
: "expiry",
@@ -588,7 +592,7 @@ dns_ntatable_dump(dns_ntatable_t *ntatable, FILE *fp) {
if (result != ISC_R_SUCCESS)
return (result);
- result = dns_ntatable_totext(ntatable, &text);
+ result = dns_ntatable_totext(ntatable, NULL, &text);
if (isc_buffer_usedlength(text) != 0) {
(void) putstr(&text, "\n");