diff --git a/bin/named/named.conf.docbook b/bin/named/named.conf.docbook index 8587f7283c..0a6c7bde3e 100644 --- a/bin/named/named.conf.docbook +++ b/bin/named/named.conf.docbook @@ -13,7 +13,7 @@ - 2018-05-29 + 2018-06-21 ISC @@ -224,9 +224,9 @@ options { coresize ( default | unlimited | sizeval ); datasize ( default | unlimited | sizeval ); deny-answer-addresses { address_match_element; ... } [ - except-from { quoted_string; ... } ]; - deny-answer-aliases { quoted_string; ... } [ except-from { - quoted_string; ... } ]; + except-from { string; ... } ]; + deny-answer-aliases { string; ... } [ except-from { string; ... + } ]; dialup ( notify | notify-passive | passive | refresh | boolean ); directory quoted_string; disable-algorithms string { string; @@ -257,14 +257,12 @@ options { dnssec-secure-to-insecure boolean; dnssec-update-mode ( maintain | no-resign ); dnssec-validation ( yes | no | auto ); - dnstap { ( all | auth | client | forwarder | - resolver ) [ ( query | response ) ]; ... }; - dnstap-identity ( quoted_string | none | - hostname ); - dnstap-output ( file | unix ) quoted_string [ - size ( unlimited | size ) ] [ versions ( - unlimited | integer ) ] [ suffix ( increment - | timestamp ) ]; + dnstap { ( all | auth | client | forwarder | resolver ) [ ( query | + response ) ]; ... }; + dnstap-identity ( quoted_string | none | hostname ); + dnstap-output ( file | unix ) quoted_string [ size ( unlimited | + size ) ] [ versions ( unlimited | integer ) ] [ suffix ( + increment | timestamp ) ]; dnstap-version ( quoted_string | none ); dscp integer; dual-stack-servers [ port integer ] { ( quoted_string [ port @@ -362,7 +360,7 @@ options { preferred-glue string; prefetch integer [ integer ]; provide-ixfr boolean; - qname-minimization ( strict | relaxed | disabled ); + qname-minimization ( strict | relaxed | disabled | off ); query-source ( ( [ address ] ( ipv4_address | * ) [ port ( integer | * ) ] ) | ( [ [ address ] ( ipv4_address | * ) ] port ( integer | * ) ) ) [ dscp integer ]; @@ -413,7 +411,7 @@ options { nsip-enable boolean ] [ nsdname-enable boolean ] [ dnsrps-enable boolean ] [ dnsrps-options { unspecified-text } ]; - root-delegation-only [ exclude { quoted_string; ... } ]; + root-delegation-only [ exclude { string; ... } ]; root-key-sentinel boolean; rrset-order { [ class string ] [ type string ] [ name quoted_string ] string string; ... }; @@ -463,6 +461,7 @@ options { use-v4-udp-ports { portrange; ... }; use-v6-udp-ports { portrange; ... }; v6-bias integer; + validate-except { string; ... }; version ( quoted_string | none ); zero-no-soa-ttl boolean; zero-no-soa-ttl-cache boolean; @@ -574,9 +573,9 @@ view string [ class ] { cleaning-interval integer; clients-per-query integer; deny-answer-addresses { address_match_element; ... } [ - except-from { quoted_string; ... } ]; - deny-answer-aliases { quoted_string; ... } [ except-from { - quoted_string; ... } ]; + except-from { string; ... } ]; + deny-answer-aliases { string; ... } [ except-from { string; ... + } ]; dialup ( notify | notify-passive | passive | refresh | boolean ); disable-algorithms string { string; ... }; @@ -610,8 +609,8 @@ view string [ class ] { dnssec-secure-to-insecure boolean; dnssec-update-mode ( maintain | no-resign ); dnssec-validation ( yes | no | auto ); - dnstap { ( all | auth | client | forwarder | - resolver ) [ ( query | response ) ]; ... }; + dnstap { ( all | auth | client | forwarder | resolver ) [ ( query | + response ) ]; ... }; dual-stack-servers [ port integer ] { ( quoted_string [ port integer ] [ dscp integer ] | ipv4_address [ port integer ] [ dscp integer ] | ipv6_address [ port @@ -689,7 +688,7 @@ view string [ class ] { preferred-glue string; prefetch integer [ integer ]; provide-ixfr boolean; - qname-minimization ( strict | relaxed | disabled ); + qname-minimization ( strict | relaxed | disabled | off ); query-source ( ( [ address ] ( ipv4_address | * ) [ port ( integer | * ) ] ) | ( [ [ address ] ( ipv4_address | * ) ] port ( integer | * ) ) ) [ dscp integer ]; @@ -735,7 +734,7 @@ view string [ class ] { nsip-enable boolean ] [ nsdname-enable boolean ] [ dnsrps-enable boolean ] [ dnsrps-options { unspecified-text } ]; - root-delegation-only [ exclude { quoted_string; ... } ]; + root-delegation-only [ exclude { string; ... } ]; root-key-sentinel boolean; rrset-order { [ class string ] [ type string ] [ name quoted_string ] string string; ... }; @@ -797,6 +796,7 @@ view string [ class ] { update-check-ksk boolean; use-alt-transfer-source boolean; v6-bias integer; + validate-except { string; ... }; zero-no-soa-ttl boolean; zero-no-soa-ttl-cache boolean; zone string [ class ] { @@ -878,7 +878,7 @@ view string [ class ] { serial-update-method ( date | increment | unixtime ); server-addresses { ( ipv4_address | ipv6_address ) [ port integer ]; ... }; - server-names { quoted_string; ... }; + server-names { string; ... }; sig-signing-nodes integer; sig-signing-signatures integer; sig-signing-type integer; @@ -982,7 +982,7 @@ zone string [ class ] { serial-update-method ( date | increment | unixtime ); server-addresses { ( ipv4_address | ipv6_address ) [ port integer ]; ... }; - server-names { quoted_string; ... }; + server-names { string; ... }; sig-signing-nodes integer; sig-signing-signatures integer; sig-signing-type integer; diff --git a/bin/named/server.c b/bin/named/server.c index 4660ad557d..2145578736 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -3692,6 +3692,7 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, isc_dscp_t dscp4 = -1, dscp6 = -1; dns_dyndbctx_t *dctx = NULL; unsigned int resolver_param; + dns_ntatable_t *ntatable = NULL; const char *qminmode = NULL; REQUIRE(DNS_VIEW_VALID(view)); @@ -5348,8 +5349,35 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, CHECK(dns_name_fromstring(name, cfg_obj_asstring(obj), 0, NULL)); view->redirectzone = name; - } else + } else { view->redirectzone = NULL; + } + + /* + * Exceptions to DNSSEC validation. + */ + obj = NULL; + result = named_config_get(maps, "validate-except", &obj); + if (result == ISC_R_SUCCESS) { + result = dns_view_getntatable(view, &ntatable); + } + if (result == ISC_R_SUCCESS) { + for (element = cfg_list_first(obj); + element != NULL; + element = cfg_list_next(element)) + { + dns_fixedname_t fntaname; + dns_name_t *ntaname; + + ntaname = dns_fixedname_initname(&fntaname); + obj = cfg_listelt_value(element); + CHECK(dns_name_fromstring(ntaname, + cfg_obj_asstring(obj), + 0, NULL)); + CHECK(dns_ntatable_add(ntatable, ntaname, + true, 0, 0xffffffffU)); + } + } #ifdef HAVE_DNSTAP /* @@ -5362,35 +5390,51 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, result = ISC_R_SUCCESS; cleanup: - if (clients != NULL) + if (ntatable != NULL) { + dns_ntatable_detach(&ntatable); + } + if (clients != NULL) { dns_acl_detach(&clients); - if (mapped != NULL) + } + if (mapped != NULL) { dns_acl_detach(&mapped); - if (excluded != NULL) + } + if (excluded != NULL) { dns_acl_detach(&excluded); - if (ring != NULL) + } + if (ring != NULL) { dns_tsigkeyring_detach(&ring); - if (zone != NULL) + } + if (zone != NULL) { dns_zone_detach(&zone); - if (dispatch4 != NULL) + } + if (dispatch4 != NULL) { dns_dispatch_detach(&dispatch4); - if (dispatch6 != NULL) + } + if (dispatch6 != NULL) { dns_dispatch_detach(&dispatch6); - if (resstats != NULL) + } + if (resstats != NULL) { isc_stats_detach(&resstats); - if (resquerystats != NULL) + } + if (resquerystats != NULL) { dns_stats_detach(&resquerystats); - if (order != NULL) + } + if (order != NULL) { dns_order_detach(&order); - if (cmctx != NULL) + } + if (cmctx != NULL) { isc_mem_detach(&cmctx); - if (hmctx != NULL) + } + if (hmctx != NULL) { isc_mem_detach(&hmctx); - - if (cache != NULL) + } + if (cache != NULL) { dns_cache_detach(&cache); - if (dctx != NULL) + } + if (dctx != NULL) { dns_dyndb_destroyctx(&dctx); + } return (result); } diff --git a/bin/tests/system/checkconf/good.conf b/bin/tests/system/checkconf/good.conf index 6d58e43550..8fb844fb2f 100644 --- a/bin/tests/system/checkconf/good.conf +++ b/bin/tests/system/checkconf/good.conf @@ -65,6 +65,9 @@ options { max-cache-size 20000000000000; nta-lifetime 604800; nta-recheck 604800; + validate-except { + "corp"; + }; transfer-source 0.0.0.0 dscp 63; zone-statistics none; }; diff --git a/doc/arm/Bv9ARM-book.xml b/doc/arm/Bv9ARM-book.xml index a0e195efd1..0ee094c4a6 100644 --- a/doc/arm/Bv9ARM-book.xml +++ b/doc/arm/Bv9ARM-book.xml @@ -6646,6 +6646,24 @@ options { + + validate-except + + + Specifies a list of domain names at and beneath which DNSSEC + validation should not be performed, + regardless of the presence of a trust anchor at or above + those names. This may be used, for example, when configuring + a top-level domain intended only for local use, so that the + lack of a secure delegation for that domain in the root zone + will not cause validation failures. (This is similar + to setting a negative trust anchor, except that it is a + permanent configuration, whereas negative trust anchors + expire and are removed after a set period of time.) + + + + dnssec-accept-expired diff --git a/doc/arm/options.grammar.xml b/doc/arm/options.grammar.xml index ef3f33ce9b..41c115c4a0 100644 --- a/doc/arm/options.grammar.xml +++ b/doc/arm/options.grammar.xml @@ -63,9 +63,9 @@ coresize ( default | unlimited | sizeval ); datasize ( default | unlimited | sizeval ); deny-answer-addresses { address_match_element; ... } [ - except-from { quoted_string; ... } ]; - deny-answer-aliases { quoted_string; ... } [ except-from { - quoted_string; ... } ]; + except-from { string; ... } ]; + deny-answer-aliases { string; ... } [ except-from { string; ... + } ]; dialup ( notify | notify-passive | passive | refresh | boolean ); directory quoted_string; disable-algorithms string { string; @@ -96,14 +96,12 @@ dnssec-secure-to-insecure boolean; dnssec-update-mode ( maintain | no-resign ); dnssec-validation ( yes | no | auto ); - dnstap { ( all | auth | client | forwarder | - resolver ) [ ( query | response ) ]; ... }; - dnstap-identity ( quoted_string | none | - hostname ); - dnstap-output ( file | unix ) quoted_string [ - size ( unlimited | size ) ] [ versions ( - unlimited | integer ) ] [ suffix ( increment - | timestamp ) ]; + dnstap { ( all | auth | client | forwarder | resolver ) [ ( query | + response ) ]; ... }; + dnstap-identity ( quoted_string | none | hostname ); + dnstap-output ( file | unix ) quoted_string [ size ( unlimited | + size ) ] [ versions ( unlimited | integer ) ] [ suffix ( + increment | timestamp ) ]; dnstap-version ( quoted_string | none ); dscp integer; dual-stack-servers [ port integer ] { ( quoted_string [ port @@ -202,7 +200,7 @@ preferred-glue string; prefetch integer [ integer ]; provide-ixfr boolean; - qname-minimization ( strict | relaxed | disabled ); + qname-minimization ( strict | relaxed | disabled | off ); query-source ( ( [ address ] ( ipv4_address | * ) [ port ( integer | * ) ] ) | ( [ [ address ] ( ipv4_address | * ) ] port ( integer | * ) ) ) [ dscp integer ]; @@ -253,7 +251,7 @@ nsip-enable boolean ] [ nsdname-enable boolean ] [ dnsrps-enable boolean ] [ dnsrps-options { unspecified-text } ]; - root-delegation-only [ exclude { quoted_string; ... } ]; + root-delegation-only [ exclude { string; ... } ]; root-key-sentinel boolean; rrset-order { [ class string ] [ type string ] [ name quoted_string ] string string; ... }; @@ -303,6 +301,7 @@ use-v4-udp-ports { portrange; ... }; use-v6-udp-ports { portrange; ... }; v6-bias integer; + validate-except { string; ... }; version ( quoted_string | none ); zero-no-soa-ttl boolean; zero-no-soa-ttl-cache boolean; diff --git a/doc/arm/static-stub.zoneopt.xml b/doc/arm/static-stub.zoneopt.xml index 84e9bb0f41..4aadf68936 100644 --- a/doc/arm/static-stub.zoneopt.xml +++ b/doc/arm/static-stub.zoneopt.xml @@ -19,7 +19,7 @@ forwarders [ port integer ] [ dscp integer ] { ( ipv4_address | ipv6_address ) [ port integer ] [ dscp integer ]; ... }; max-records integer; server-addresses { ( ipv4_address | ipv6_address ) [ port integer ]; ... }; - server-names { quoted_string; ... }; + server-names { string; ... }; zone-statistics ( full | terse | none | boolean ); }; diff --git a/doc/misc/options b/doc/misc/options index 41686fb475..c0ad48b30a 100644 --- a/doc/misc/options +++ b/doc/misc/options @@ -113,9 +113,9 @@ options { datasize ( default | unlimited | ); deallocate-on-exit ; // obsolete deny-answer-addresses { ; ... } [ - except-from { ; ... } ]; - deny-answer-aliases { ; ... } [ except-from { - ; ... } ]; + except-from { ; ... } ]; + deny-answer-aliases { ; ... } [ except-from { ; ... + } ]; dialup ( notify | notify-passive | passive | refresh | ); directory ; disable-algorithms { ; @@ -146,15 +146,13 @@ options { dnssec-secure-to-insecure ; dnssec-update-mode ( maintain | no-resign ); dnssec-validation ( yes | no | auto ); - dnstap { ( all | auth | client | forwarder | - resolver ) [ ( query | response ) ]; ... }; // not configured - dnstap-identity ( | none | - hostname ); // not configured - dnstap-output ( file | unix ) [ - size ( unlimited | ) ] [ versions ( - unlimited | ) ] [ suffix ( increment - | timestamp ) ]; // not configured - dnstap-version ( | none ); // not configured + dnstap { ( all | auth | client | forwarder | resolver ) [ ( query | + response ) ]; ... }; + dnstap-identity ( | none | hostname ); + dnstap-output ( file | unix ) [ size ( unlimited | + ) ] [ versions ( unlimited | ) ] [ suffix ( + increment | timestamp ) ]; + dnstap-version ( | none ); dscp ; dual-stack-servers [ port ] { ( [ port ] [ dscp ] | [ port @@ -178,14 +176,14 @@ options { forward ( first | only ); forwarders [ port ] [ dscp ] { ( | ) [ port ] [ dscp ]; ... }; - fstrm-set-buffer-hint ; // not configured - fstrm-set-flush-timeout ; // not configured - fstrm-set-input-queue-size ; // not configured - fstrm-set-output-notify-threshold ; // not configured - fstrm-set-output-queue-model ( mpsc | spsc ); // not configured - fstrm-set-output-queue-size ; // not configured - fstrm-set-reopen-interval ; // not configured - geoip-directory ( | none ); // not configured + fstrm-set-buffer-hint ; + fstrm-set-flush-timeout ; + fstrm-set-input-queue-size ; + fstrm-set-output-notify-threshold ; + fstrm-set-output-queue-model ( mpsc | spsc ); + fstrm-set-output-queue-size ; + fstrm-set-reopen-interval ; + geoip-directory ( | none ); geoip-use-ecs ; // obsolete glue-cache ; has-old-clients ; // obsolete @@ -321,7 +319,7 @@ options { dnsrps-enable ] [ dnsrps-options { } ]; rfc2308-type1 ; // not yet implemented - root-delegation-only [ exclude { ; ... } ]; + root-delegation-only [ exclude { ; ... } ]; root-key-sentinel ; rrset-order { [ class ] [ type ] [ name ] ; ... }; @@ -380,6 +378,7 @@ options { use-v4-udp-ports { ; ... }; use-v6-udp-ports { ; ... }; v6-bias ; + validate-except { ; ... }; version ( | none ); zero-no-soa-ttl ; zero-no-soa-ttl-cache ; @@ -478,9 +477,9 @@ view [ ] { cleaning-interval ; clients-per-query ; deny-answer-addresses { ; ... } [ - except-from { ; ... } ]; - deny-answer-aliases { ; ... } [ except-from { - ; ... } ]; + except-from { ; ... } ]; + deny-answer-aliases { ; ... } [ except-from { ; ... + } ]; dialup ( notify | notify-passive | passive | refresh | ); disable-algorithms { ; ... }; // may occur multiple times @@ -514,8 +513,8 @@ view [ ] { dnssec-secure-to-insecure ; dnssec-update-mode ( maintain | no-resign ); dnssec-validation ( yes | no | auto ); - dnstap { ( all | auth | client | forwarder | - resolver ) [ ( query | response ) ]; ... }; // not configured + dnstap { ( all | auth | client | forwarder | resolver ) [ ( query | + response ) ]; ... }; dual-stack-servers [ port ] { ( [ port ] [ dscp ] | [ port ] [ dscp ] | [ port @@ -651,7 +650,7 @@ view [ ] { dnsrps-enable ] [ dnsrps-options { } ]; rfc2308-type1 ; // not yet implemented - root-delegation-only [ exclude { ; ... } ]; + root-delegation-only [ exclude { ; ... } ]; root-key-sentinel ; rrset-order { [ class ] [ type ] [ name ] ; ... }; @@ -718,6 +717,7 @@ view [ ] { use-alt-transfer-source ; use-queryport-pool ; // obsolete v6-bias ; + validate-except { ; ... }; zero-no-soa-ttl ; zero-no-soa-ttl-cache ; zone [ ] { @@ -805,7 +805,7 @@ view [ ] { serial-update-method ( date | increment | unixtime ); server-addresses { ( | ) [ port ]; ... }; - server-names { ; ... }; + server-names { ; ... }; sig-signing-nodes ; sig-signing-signatures ; sig-signing-type ; @@ -910,7 +910,7 @@ zone [ ] { serial-update-method ( date | increment | unixtime ); server-addresses { ( | ) [ port ]; ... }; - server-names { ; ... }; + server-names { ; ... }; sig-signing-nodes ; sig-signing-signatures ; sig-signing-type ; diff --git a/doc/misc/static-stub.zoneopt b/doc/misc/static-stub.zoneopt index 74abe0b137..809daf38e7 100644 --- a/doc/misc/static-stub.zoneopt +++ b/doc/misc/static-stub.zoneopt @@ -6,6 +6,6 @@ zone [ ] { forwarders [ port ] [ dscp ] { ( | ) [ port ] [ dscp ]; ... }; max-records ; server-addresses { ( | ) [ port ]; ... }; - server-names { ; ... }; + server-names { ; ... }; zone-statistics ( full | terse | none | ); }; diff --git a/lib/dns/include/dns/nta.h b/lib/dns/include/dns/nta.h index 8221aade87..21af6499c3 100644 --- a/lib/dns/include/dns/nta.h +++ b/lib/dns/include/dns/nta.h @@ -122,9 +122,12 @@ dns_ntatable_add(dns_ntatable_t *ntatable, const dns_name_t *name, uint32_t lifetime); /*%< * Add a negative trust anchor to 'ntatable' for name 'name', - * which will expire at time 'now' + 'lifetime'. If 'force' is false, - * then the name will be checked periodically to see if it's bogus; - * if not, then the NTA will be allowed to expire early. + * which will expire at time 'now' + 'lifetime'. If 'force' is true, + * then the NTA will persist for the entire specified lifetime. + * If it is false, then the name will be queried periodically and + * validation will be attempted to see whether it's still bogus; + * if validation is successful, the NTA will be allowed to expire + * early and validation below the NTA will resume. * * Notes: * diff --git a/lib/dns/nta.c b/lib/dns/nta.c index 6cede2a6a7..f90a80a909 100644 --- a/lib/dns/nta.c +++ b/lib/dns/nta.c @@ -547,20 +547,28 @@ dns_ntatable_totext(dns_ntatable_t *ntatable, isc_buffer_t **buf) { dns_name_t *name; isc_time_t t; - name = dns_fixedname_initname(&fn); - dns_rbt_fullnamefromnode(node, name); - dns_name_format(name, nbuf, sizeof(nbuf)); - isc_time_set(&t, n->expiry, 0); - isc_time_formattimestamp(&t, tbuf, sizeof(tbuf)); + /* + * Skip "validate-except" entries. + */ + if (n->expiry != 0xffffffffU) { + name = dns_fixedname_initname(&fn); + dns_rbt_fullnamefromnode(node, name); + dns_name_format(name, nbuf, sizeof(nbuf)); + isc_time_set(&t, n->expiry, 0); + isc_time_formattimestamp(&t, tbuf, + sizeof(tbuf)); - snprintf(obuf, sizeof(obuf), "%s%s: %s %s", - first ? "" : "\n", nbuf, - n->expiry <= now ? "expired" : "expiry", - tbuf); - first = false; - result = putstr(buf, obuf); - if (result != ISC_R_SUCCESS) - goto cleanup; + snprintf(obuf, sizeof(obuf), "%s%s: %s %s", + first ? "" : "\n", nbuf, + n->expiry <= now + ? "expired" + : "expiry", + tbuf); + first = false; + result = putstr(buf, obuf); + if (result != ISC_R_SUCCESS) + goto cleanup; + } } result = dns_rbtnodechain_next(&chain, NULL, NULL); if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) { @@ -576,56 +584,6 @@ dns_ntatable_totext(dns_ntatable_t *ntatable, isc_buffer_t **buf) { return (result); } -#if 0 -isc_result_t -dns_ntatable_dump(dns_ntatable_t *ntatable, FILE *fp) { - isc_result_t result; - dns_rbtnode_t *node; - dns_rbtnodechain_t chain; - isc_stdtime_t now; - - REQUIRE(VALID_NTATABLE(ntatable)); - - isc_stdtime_get(&now); - - RWLOCK(&ntatable->rwlock, isc_rwlocktype_read); - dns_rbtnodechain_init(&chain, ntatable->view->mctx); - result = dns_rbtnodechain_first(&chain, ntatable->table, NULL, NULL); - if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) - goto cleanup; - for (;;) { - dns_rbtnodechain_current(&chain, NULL, NULL, &node); - if (node->data != NULL) { - dns_nta_t *n = (dns_nta_t *) node->data; - char nbuf[DNS_NAME_FORMATSIZE], tbuf[80]; - dns_fixedname_t fn; - dns_name_t *name; - isc_time_t t; - - name = dns_fixedname_initname(&fn); - dns_rbt_fullnamefromnode(node, name); - dns_name_format(name, nbuf, sizeof(nbuf)); - isc_time_set(&t, n->expiry, 0); - isc_time_formattimestamp(&t, tbuf, sizeof(tbuf)); - fprintf(fp, "%s: %s %s\n", nbuf, - n->expiry <= now ? "expired" : "expiry", - tbuf); - } - result = dns_rbtnodechain_next(&chain, NULL, NULL); - if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) { - if (result == ISC_R_NOMORE) - result = ISC_R_SUCCESS; - break; - } - } - - cleanup: - dns_rbtnodechain_invalidate(&chain); - RWUNLOCK(&ntatable->rwlock, isc_rwlocktype_read); - return (result); -} -#endif - isc_result_t dns_ntatable_dump(dns_ntatable_t *ntatable, FILE *fp) { isc_result_t result; @@ -674,35 +632,41 @@ dns_ntatable_save(dns_ntatable_t *ntatable, FILE *fp) { for (;;) { dns_rbtnodechain_current(&chain, NULL, NULL, &node); if (node->data != NULL) { + isc_buffer_t b; + char nbuf[DNS_NAME_FORMATSIZE + 1], tbuf[80]; + dns_fixedname_t fn; + dns_name_t *name; dns_nta_t *n = (dns_nta_t *) node->data; - if (n->expiry > now) { - isc_buffer_t b; - char nbuf[DNS_NAME_FORMATSIZE + 1], tbuf[80]; - dns_fixedname_t fn; - dns_name_t *name; - name = dns_fixedname_initname(&fn); - dns_rbt_fullnamefromnode(node, name); - - isc_buffer_init(&b, nbuf, sizeof(nbuf)); - result = dns_name_totext(name, false, &b); - if (result != ISC_R_SUCCESS) - goto skip; - - /* Zero terminate. */ - isc_buffer_putuint8(&b, 0); - - isc_buffer_init(&b, tbuf, sizeof(tbuf)); - dns_time32_totext(n->expiry, &b); - - /* Zero terminate. */ - isc_buffer_putuint8(&b, 0); - - fprintf(fp, "%s %s %s\n", nbuf, - n->forced ? "forced" : "regular", - tbuf); - written = true; + /* + * Skip this node if the expiry is already in the + * past, or if this is a "validate-except" entry. + */ + if (n->expiry <= now || n->expiry == 0xffffffffU) { + goto skip; } + + name = dns_fixedname_initname(&fn); + dns_rbt_fullnamefromnode(node, name); + + isc_buffer_init(&b, nbuf, sizeof(nbuf)); + result = dns_name_totext(name, false, &b); + if (result != ISC_R_SUCCESS) + goto skip; + + /* Zero terminate. */ + isc_buffer_putuint8(&b, 0); + + isc_buffer_init(&b, tbuf, sizeof(tbuf)); + dns_time32_totext(n->expiry, &b); + + /* Zero terminate. */ + isc_buffer_putuint8(&b, 0); + + fprintf(fp, "%s %s %s\n", nbuf, + n->forced ? "forced" : "regular", + tbuf); + written = true; } skip: result = dns_rbtnodechain_next(&chain, NULL, NULL); diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index 0c026f8991..3f6336d898 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -1155,7 +1155,7 @@ options_clauses[] = { static cfg_type_t cfg_type_namelist = { "namelist", cfg_parse_bracketed_list, cfg_print_bracketed_list, - cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_qstring + cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_astring }; static keyword_type_t exclude_kw = { "exclude", &cfg_type_namelist }; @@ -1976,6 +1976,7 @@ view_clauses[] = { { "trust-anchor-telemetry", &cfg_type_boolean, CFG_CLAUSEFLAG_EXPERIMENTAL }, { "use-queryport-pool", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE }, + { "validate-except", &cfg_type_namelist, 0 }, { "v6-bias", &cfg_type_uint32, 0 }, { "zero-no-soa-ttl-cache", &cfg_type_boolean, 0 }, { NULL, NULL, 0 }