diff --git a/CHANGES b/CHANGES index 87d625bb15..44b4be8554 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,11 @@ +1510. [func] New view option "root-delegation-only". Apply + delegation-only check to all TLDs and root. + Note there are some TLDs that are NOT delegation + only (e.g. DE and MUSEUM) these can be excluded + from the checks buy using exclude. + + root-delegation-only exclude { "DE"; "MUSEUM"; }; + 1509. [bug] Hint zones should accept delegation-only. Forward zone should not accept delegation-only. diff --git a/bin/named/server.c b/bin/named/server.c index f22cdbbd16..d63fd4ed76 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: server.c,v 1.402 2003/09/19 05:53:26 marka Exp $ */ +/* $Id: server.c,v 1.403 2003/09/19 12:39:47 marka Exp $ */ #include @@ -1002,6 +1002,35 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig, } else view->preferred_glue = 0; + obj = NULL; + result = ns_config_get(maps, "root-delegation-only", &obj); + if (result == ISC_R_SUCCESS) { + dns_view_setrootdelonly(view, ISC_TRUE); + if (!cfg_obj_isvoid(obj)) { + dns_fixedname_t fixed; + dns_name_t *name; + isc_buffer_t b; + char *str; + cfg_obj_t *exclude; + + dns_fixedname_init(&fixed); + name = dns_fixedname_name(&fixed); + for (element = cfg_list_first(obj); + element != NULL; + element = cfg_list_next(element)) { + exclude = cfg_listelt_value(element); + str = cfg_obj_asstring(exclude); + isc_buffer_init(&b, str, strlen(str)); + isc_buffer_add(&b, strlen(str)); + CHECK(dns_name_fromtext(name, &b, dns_rootname, + ISC_FALSE, NULL)); + CHECK(dns_view_excludedelegationonly(view, + name)); + } + } + } else + dns_view_setrootdelonly(view, ISC_FALSE); + result = ISC_R_SUCCESS; cleanup: diff --git a/doc/arm/Bv9ARM-book.xml b/doc/arm/Bv9ARM-book.xml index 956608add4..32b879de96 100644 --- a/doc/arm/Bv9ARM-book.xml +++ b/doc/arm/Bv9ARM-book.xml @@ -2,7 +2,7 @@ - + BIND 9 Administrator Reference Manual @@ -2811,6 +2811,7 @@ statement in the named.conf file: match-mapped-addresses yes_or_no; preferred-glue ( A | AAAA | NONE ); edns-udp-size number; + root-delegation-only exclude { namelist } ; }; @@ -2935,6 +2936,20 @@ The default is not to preference any type (NONE). +root-delegation-only + +Turn on enforcment of delegation-only in TLDs and root zones with an optional +exclude list. + + +Note some TLDs are NOT delegation only (e.g. "DE" and "MUSEUM"). + + +options { + root-delegation-only exclude { "de"; "museum"; }; +}; + + diff --git a/lib/bind9/check.c b/lib/bind9/check.c index e57a105877..e82c371442 100644 --- a/lib/bind9/check.c +++ b/lib/bind9/check.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: check.c,v 1.39 2003/09/19 05:53:27 marka Exp $ */ +/* $Id: check.c,v 1.40 2003/09/19 12:39:48 marka Exp $ */ #include @@ -279,6 +279,39 @@ check_options(cfg_obj_t *options, isc_log_t *logctx) { "preferred-glue unexpected value '%s'", str); } + obj = NULL; + (void)cfg_map_get(options, "root-delegation-only", &obj); + if (obj != NULL) { + if (!cfg_obj_isvoid(obj)) { + cfg_listelt_t *element; + cfg_obj_t *exclude; + char *str; + dns_fixedname_t fixed; + dns_name_t *name; + isc_buffer_t b; + isc_result_t tresult; + + dns_fixedname_init(&fixed); + name = dns_fixedname_name(&fixed); + for (element = cfg_list_first(obj); + element != NULL; + element = cfg_list_next(element)) { + exclude = cfg_listelt_value(element); + str = cfg_obj_asstring(exclude); + isc_buffer_init(&b, str, strlen(str)); + isc_buffer_add(&b, strlen(str)); + tresult = dns_name_fromtext(name, &b, + dns_rootname, + ISC_FALSE, NULL); + if (tresult != ISC_R_SUCCESS) { + cfg_obj_log(obj, logctx, ISC_LOG_ERROR, + "bad domain name '%s'", + str); + result = tresult; + } + } + } + } return (result); } diff --git a/lib/dns/include/dns/view.h b/lib/dns/include/dns/view.h index d2a4fa4d5e..7330731845 100644 --- a/lib/dns/include/dns/view.h +++ b/lib/dns/include/dns/view.h @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: view.h,v 1.83 2003/09/17 05:24:43 marka Exp $ */ +/* $Id: view.h,v 1.84 2003/09/19 12:39:48 marka Exp $ */ #ifndef DNS_VIEW_H #define DNS_VIEW_H 1 @@ -120,6 +120,8 @@ struct dns_view { dns_rdatatype_t preferred_glue; isc_boolean_t flush; dns_namelist_t * delonly; + isc_boolean_t rootdelonly; + dns_namelist_t * rootexlude;; /* * Configurable data for server use only, @@ -720,6 +722,22 @@ isc_result_t dns_view_adddelegationonly(dns_view_t *view, dns_name_t *name); /* * Add the given name to the delegation only table. + * + * + * Requires: + * 'view' is valid. + * 'name' is valid. + * + * Returns: + * ISC_R_SUCCESS + * ISC_R_NOMEMORY + */ + +isc_result_t +dns_view_excludedelegationonly(dns_view_t *view, dns_name_t *name); +/* + * Add the given name to be excluded from the root-delegation-only. + * * * Requires: * 'view' is valid. @@ -733,7 +751,8 @@ dns_view_adddelegationonly(dns_view_t *view, dns_name_t *name); isc_boolean_t dns_view_isdelegationonly(dns_view_t *view, dns_name_t *name); /* - * Check if 'name' is in the delegation only table. + * Check if 'name' is in the delegation only table or if + * rootdelonly is set that name is not being excluded. * * Requires: * 'view' is valid. @@ -744,7 +763,22 @@ dns_view_isdelegationonly(dns_view_t *view, dns_name_t *name); * ISC_FALSE othewise. */ +void +dns_view_setrootdelonly(dns_view_t *view, isc_boolean_t value); +/* + * Set the root delegation only flag. + * + * Requires: + * 'view' is valid. + */ -ISC_LANG_ENDDECLS +isc_boolean_t +dns_view_getrootdelonly(dns_view_t *view); +/* + * Get the root delegation only flag. + * + * Requires: + * 'view' is valid. + */ #endif /* DNS_VIEW_H */ diff --git a/lib/dns/view.c b/lib/dns/view.c index f3f236e5ee..d2f37944f7 100644 --- a/lib/dns/view.c +++ b/lib/dns/view.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: view.c,v 1.118 2003/09/17 15:01:26 marka Exp $ */ +/* $Id: view.c,v 1.119 2003/09/19 12:39:48 marka Exp $ */ #include @@ -1224,6 +1224,41 @@ dns_view_adddelegationonly(dns_view_t *view, dns_name_t *name) { return (result); } +isc_result_t +dns_view_excludedelegationonly(dns_view_t *view, dns_name_t *name) { + isc_result_t result; + dns_name_t *new; + isc_uint32_t hash; + + REQUIRE(DNS_VIEW_VALID(view)); + + if (view->rootexlude == NULL) { + view->rootexlude = isc_mem_get(view->mctx, + sizeof(dns_namelist_t) * + DNS_VIEW_DELONLYHASH); + if (view->rootexlude == NULL) + return (ISC_R_NOMEMORY); + for (hash = 0; hash < DNS_VIEW_DELONLYHASH; hash++) + ISC_LIST_INIT(view->delonly[hash]); + } + hash = dns_name_hash(name, ISC_FALSE) % DNS_VIEW_DELONLYHASH; + new = ISC_LIST_HEAD(view->rootexlude[hash]); + while (new != NULL && !dns_name_equal(new, name)) + new = ISC_LIST_NEXT(new, link); + if (new != NULL) + return (ISC_R_SUCCESS); + new = isc_mem_get(view->mctx, sizeof(*new)); + if (new == NULL) + return (ISC_R_NOMEMORY); + dns_name_init(new, NULL); + result = dns_name_dup(name, view->mctx, new); + if (result == ISC_R_SUCCESS) + ISC_LIST_APPEND(view->rootexlude[hash], new, link); + else + isc_mem_put(view->mctx, new, sizeof(*new)); + return (result); +} + isc_boolean_t dns_view_isdelegationonly(dns_view_t *view, dns_name_t *name) { dns_name_t *new; @@ -1231,10 +1266,23 @@ dns_view_isdelegationonly(dns_view_t *view, dns_name_t *name) { REQUIRE(DNS_VIEW_VALID(view)); - if (view->delonly == NULL) + if (!view->rootdelonly && view->delonly == NULL) return (ISC_FALSE); hash = dns_name_hash(name, ISC_FALSE) % DNS_VIEW_DELONLYHASH; + if (view->rootdelonly && dns_name_countlabels(name) <= 2) { + if (view->rootexlude == NULL) + return (ISC_TRUE); + new = ISC_LIST_HEAD(view->rootexlude[hash]); + while (new != NULL && !dns_name_equal(new, name)) + new = ISC_LIST_NEXT(new, link); + if (new == NULL) + return (ISC_TRUE); + } + + if (view->delonly == NULL) + return (ISC_FALSE); + new = ISC_LIST_HEAD(view->delonly[hash]); while (new != NULL && !dns_name_equal(new, name)) new = ISC_LIST_NEXT(new, link); @@ -1242,3 +1290,15 @@ dns_view_isdelegationonly(dns_view_t *view, dns_name_t *name) { return (ISC_FALSE); return (ISC_TRUE); } + +void +dns_view_setrootdelonly(dns_view_t *view, isc_boolean_t value) { + REQUIRE(DNS_VIEW_VALID(view)); + view->rootdelonly = value; +} + +isc_boolean_t +dns_view_getrootdelonly(dns_view_t *view) { + REQUIRE(DNS_VIEW_VALID(view)); + return (view->rootdelonly); +} diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index dfc791b8a8..8450a23b53 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: namedconf.c,v 1.22 2003/09/17 05:24:43 marka Exp $ */ +/* $Id: namedconf.c,v 1.23 2003/09/19 12:39:49 marka Exp $ */ #include @@ -607,6 +607,17 @@ options_clauses[] = { { NULL, NULL, 0 } }; + +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 }; + +static keyword_type_t exclude_kw = { "exclude", &cfg_type_namelist }; + +static cfg_type_t cfg_type_optional_exclude = { + "optional_exclude", parse_optional_keyvalue, print_keyvalue, + doc_optional_keyvalue, &cfg_rep_list, &exclude_kw }; + /* * Clauses that can be found within the 'view' statement, * with defaults in the 'options' statement. @@ -649,6 +660,7 @@ view_clauses[] = { { "preferred-glue", &cfg_type_astring, 0 }, { "dual-stack-servers", &cfg_type_nameportiplist, 0 }, { "edns-udp-size", &cfg_type_uint32, 0 }, + { "root-delegation-only", &cfg_type_optional_exclude, 0 }, { NULL, NULL, 0 } };