From 0b1da8124c817270f5dfe46cd0211b993c931a91 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Fri, 19 Sep 2003 12:39:49 +0000 Subject: [PATCH] 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"; }; --- CHANGES | 8 +++++ bin/named/server.c | 31 +++++++++++++++++- doc/arm/Bv9ARM-book.xml | 17 +++++++++- lib/bind9/check.c | 35 ++++++++++++++++++++- lib/dns/include/dns/view.h | 40 ++++++++++++++++++++++-- lib/dns/view.c | 64 ++++++++++++++++++++++++++++++++++++-- lib/isccfg/namedconf.c | 14 ++++++++- 7 files changed, 200 insertions(+), 9 deletions(-) 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 } };