diff --git a/CHANGES b/CHANGES index e84c9a1f4c..727bb4d04b 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,7 @@ 1795. [placeholder] rt13396 -1794. [placeholder] rt13382 +1794. [func] Named and named-checkzone can now both check for + non-terminal wildcard records. 1793. [placeholder] rt13378 diff --git a/bin/check/check-tool.c b/bin/check/check-tool.c index 14e855a6eb..f06602fb33 100644 --- a/bin/check/check-tool.c +++ b/bin/check/check-tool.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: check-tool.c,v 1.13 2004/11/30 01:08:48 marka Exp $ */ +/* $Id: check-tool.c,v 1.14 2005/01/09 23:39:56 marka Exp $ */ #include @@ -51,7 +51,8 @@ int debug = 0; isc_boolean_t nomerge = ISC_TRUE; unsigned int zone_options = DNS_ZONEOPT_CHECKNS | DNS_ZONEOPT_MANYERRORS | - DNS_ZONEOPT_CHECKNAMES; + DNS_ZONEOPT_CHECKNAMES | + DNS_ZONEOPT_CHECKWILDCARD; /* * This needs to match the list in bin/named/log.c. diff --git a/bin/check/named-checkzone.c b/bin/check/named-checkzone.c index e4f93d2aa3..83886a60b1 100644 --- a/bin/check/named-checkzone.c +++ b/bin/check/named-checkzone.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: named-checkzone.c,v 1.31 2004/10/25 01:27:53 marka Exp $ */ +/* $Id: named-checkzone.c,v 1.32 2005/01/09 23:39:56 marka Exp $ */ #include @@ -67,7 +67,7 @@ usage(void) { fprintf(stderr, "usage: named-checkzone [-djqvD] [-c class] [-o output] " "[-t directory] [-w directory] [-k (ignore|warn|fail)] " - "[-n (ignore|warn|fail)] zonename filename\n"); + "[-n (ignore|warn|fail)] [-W (ignore|warn)] zonename filename\n"); exit(1); } @@ -88,7 +88,7 @@ main(int argc, char **argv) { char *classname = classname_in; const char *workdir = NULL; - while ((c = isc_commandline_parse(argc, argv, "c:dijk:n:qst:o:vw:D")) != EOF) { + while ((c = isc_commandline_parse(argc, argv, "c:dijk:n:qst:o:vw:DW:")) != EOF) { switch (c) { case 'c': classname = isc_commandline_argument; @@ -165,6 +165,13 @@ main(int argc, char **argv) { dumpzone++; break; + case 'W': + if (!strcmp(isc_commandline_argument, "warn")) + zone_options |= DNS_ZONEOPT_CHECKWILDCARD; + else if (!strcmp(isc_commandline_argument, "ignore")) + zone_options &= ~DNS_ZONEOPT_CHECKWILDCARD; + break; + default: usage(); } diff --git a/bin/check/named-checkzone.docbook b/bin/check/named-checkzone.docbook index 85bd233615..213267d65e 100644 --- a/bin/check/named-checkzone.docbook +++ b/bin/check/named-checkzone.docbook @@ -16,7 +16,7 @@ - PERFORMANCE OF THIS SOFTWARE. --> - + @@ -48,6 +48,7 @@ + zonename filename @@ -178,6 +179,19 @@ + + -W mode + + + Specify whether to check for non-terminal wildcards. + Non-terminal wildcards are almost always the result of a + failure to understand the wildcard matching algorithm (RFC 1034). + Possible modes are "warn" (default) and + "ignore". + + + + zonename diff --git a/bin/named/config.c b/bin/named/config.c index 1965758be0..6f34fc1acc 100644 --- a/bin/named/config.c +++ b/bin/named/config.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: config.c,v 1.52 2004/12/21 10:45:15 jinmei Exp $ */ +/* $Id: config.c,v 1.53 2005/01/09 23:39:57 marka Exp $ */ #include @@ -158,6 +158,7 @@ options {\n\ zone-statistics false;\n\ max-journal-size unlimited;\n\ ixfr-from-differences false;\n\ + check-wildcard yes;\n\ };\n\ " diff --git a/bin/named/update.c b/bin/named/update.c index 9f9c395cbf..6bc8c337bd 100644 --- a/bin/named/update.c +++ b/bin/named/update.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: update.c,v 1.118 2004/10/21 01:29:29 marka Exp $ */ +/* $Id: update.c,v 1.119 2005/01/09 23:39:58 marka Exp $ */ #include @@ -2149,6 +2149,7 @@ update_action(isc_task_t *task, isc_event_t *event) { dns_ssutable_t *ssutable = NULL; dns_fixedname_t tmpnamefixed; dns_name_t *tmpname = NULL; + unsigned int options; INSIST(event->ev_type == DNS_EVENT_UPDATE); @@ -2382,6 +2383,7 @@ update_action(isc_task_t *task, isc_event_t *event) { * Process the Update Section. */ + options = dns_zone_getoptions(zone); for (result = dns_message_firstname(request, DNS_SECTION_UPDATE); result == ISC_R_SUCCESS; result = dns_message_nextname(request, DNS_SECTION_UPDATE)) @@ -2468,6 +2470,15 @@ update_action(isc_task_t *task, isc_event_t *event) { } soa_serial_changed = ISC_TRUE; } + if ((options & DNS_ZONEOPT_CHECKWILDCARD) != 0 && + dns_name_internalwildcard(name)) { + char namestr[DNS_NAME_FORMATSIZE]; + dns_name_format(name, namestr, + sizeof(namestr)); + update_log(client, zone, LOGLEVEL_PROTOCOL, + "warning: ownername '%s' contains " + "a non-terminal wildcard", namestr); + } if (isc_log_wouldlog(ns_g_lctx, LOGLEVEL_PROTOCOL)) { char namestr[DNS_NAME_FORMATSIZE]; diff --git a/bin/named/zoneconf.c b/bin/named/zoneconf.c index 86ff65c09f..7d56979101 100644 --- a/bin/named/zoneconf.c +++ b/bin/named/zoneconf.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: zoneconf.c,v 1.114 2004/10/14 00:49:33 marka Exp $ */ +/* $Id: zoneconf.c,v 1.115 2005/01/09 23:39:58 marka Exp $ */ #include @@ -602,7 +602,13 @@ ns_zone_configure(cfg_obj_t *config, cfg_obj_t *vconfig, cfg_obj_t *zconfig, } RETERR(dns_zone_setkeydirectory(zone, filename)); } - + obj = NULL; + result = ns_config_get(maps, "check-wildcard", &obj); + if (result == ISC_R_SUCCESS) + check = cfg_obj_asboolean(obj); + else + check = ISC_FALSE; + dns_zone_setoption(zone, DNS_ZONEOPT_CHECKWILDCARD, check); } else if (ztype == dns_zone_slave) { RETERR(configure_zone_acl(zconfig, vconfig, config, "allow-update-forwarding", ac, zone, diff --git a/doc/arm/Bv9ARM-book.xml b/doc/arm/Bv9ARM-book.xml index 04882f40bf..3658577441 100644 --- a/doc/arm/Bv9ARM-book.xml +++ b/doc/arm/Bv9ARM-book.xml @@ -2,7 +2,7 @@ - + BIND 9 Administrator Reference Manual @@ -2733,6 +2733,7 @@ statement in the named.conf file: forwarders { ip_addr port ip_port ; ip_addr port ip_port ; ... }; dual-stack-servers port ip_port { ( domain_name port ip_port | ip_addr port ip_port ) ; ... }; check-names ( master | slave | response )( warn | fail | ignore ); + check-wildcard yes_or_no; allow-notify { address_match_list }; allow-query { address_match_list }; allow-query-cache { address_match_list }; @@ -3384,6 +3385,16 @@ IN-ADDR.ARPA, IP6.ARPA, IP6.INT). +check-wildcard + +This option is used to check for non-terminal wildcards. +The use of non-terminal wildcards is almost always as a result of a failure +to understand the wildcard matching algorithm (RFC 1034). This option +affects master zones. The default (yes) is to check +for non-terminal wildcards and issue a warning. + + + @@ -4686,6 +4697,7 @@ Statement Grammar allow-update-forwarding { address_match_list } ; also-notify { ip_addr port ip_port ; ip_addr port ip_port ; ... }; check-names (warn|fail|ignore) ; + check-wildcard yes_or_no; dialup dialup_option ; delegation-only yes_or_no ; file string ; @@ -4908,6 +4920,11 @@ zones the default is warn. +check-wildcard +See the description of +check-wildcard in . + + database Specify the type of database to be used for storing the zone data. The string following the database keyword diff --git a/doc/misc/options b/doc/misc/options index 9f76722438..e16959c5e2 100644 --- a/doc/misc/options +++ b/doc/misc/options @@ -126,6 +126,7 @@ options { use-alt-transfer-source ; zone-statistics ; key-directory ; + check-wildcard ; }; controls { @@ -218,6 +219,7 @@ view { use-alt-transfer-source ; zone-statistics ; key-directory ; + check-wildcard ; }; server ( | ) { bogus ; @@ -312,6 +314,7 @@ view { use-alt-transfer-source ; zone-statistics ; key-directory ; + check-wildcard ; }; lwres { @@ -378,6 +381,7 @@ zone { use-alt-transfer-source ; zone-statistics ; key-directory ; + check-wildcard ; }; server ( | ) { diff --git a/lib/bind9/check.c b/lib/bind9/check.c index 8b4772060e..aad0cd5ebf 100644 --- a/lib/bind9/check.c +++ b/lib/bind9/check.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: check.c,v 1.51 2004/11/22 05:03:11 marka Exp $ */ +/* $Id: check.c,v 1.52 2005/01/09 23:40:00 marka Exp $ */ #include @@ -741,6 +741,7 @@ check_zoneconf(cfg_obj_t *zconfig, cfg_obj_t *config, isc_symtab_t *symtab, { "update-policy", MASTERZONE }, { "database", MASTERZONE | SLAVEZONE | STUBZONE }, { "key-directory", MASTERZONE }, + { "check-wildcard", MASTERZONE }, }; static optionstable dialups[] = { diff --git a/lib/dns/include/dns/master.h b/lib/dns/include/dns/master.h index af652a6caa..8b7b7866b4 100644 --- a/lib/dns/include/dns/master.h +++ b/lib/dns/include/dns/master.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: master.h,v 1.38 2004/03/05 05:09:43 marka Exp $ */ +/* $Id: master.h,v 1.39 2005/01/09 23:40:03 marka Exp $ */ #ifndef DNS_MASTER_H #define DNS_MASTER_H 1 @@ -45,6 +45,7 @@ * matches as fatal */ #define DNS_MASTER_CHECKNAMES 0x00000100 #define DNS_MASTER_CHECKNAMESFAIL 0x00000200 +#define DNS_MASTER_CHECKWILDCARD 0x00000400 /* Check for internal wilcards. */ ISC_LANG_BEGINDECLS diff --git a/lib/dns/include/dns/name.h b/lib/dns/include/dns/name.h index ea10296ed6..662ce5b059 100644 --- a/lib/dns/include/dns/name.h +++ b/lib/dns/include/dns/name.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: name.h,v 1.111 2004/09/08 00:26:14 marka Exp $ */ +/* $Id: name.h,v 1.112 2005/01/09 23:40:03 marka Exp $ */ #ifndef DNS_NAME_H #define DNS_NAME_H 1 @@ -1167,6 +1167,15 @@ dns_name_ismailbox(const dns_name_t *name); * 'name' to be valid. */ +isc_boolean_t +dns_name_internalwildcard(const dns_name_t *name); +/* + * Return if 'name' contains a internal wildcard name. + * + * Requires: + * 'name' to be valid. + */ + ISC_LANG_ENDDECLS /*** diff --git a/lib/dns/include/dns/zone.h b/lib/dns/include/dns/zone.h index 28337a68f8..c05a927dd6 100644 --- a/lib/dns/include/dns/zone.h +++ b/lib/dns/include/dns/zone.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: zone.h,v 1.128 2004/12/21 10:45:19 jinmei Exp $ */ +/* $Id: zone.h,v 1.129 2005/01/09 23:40:03 marka Exp $ */ #ifndef DNS_ZONE_H #define DNS_ZONE_H 1 @@ -52,6 +52,7 @@ typedef enum { #define DNS_ZONEOPT_USEALTXFRSRC 0x00000400U /* use alternate transfer sources */ #define DNS_ZONEOPT_CHECKNAMES 0x00000800U /* check-names */ #define DNS_ZONEOPT_CHECKNAMESFAIL 0x00001000U /* fatal check-name failures */ +#define DNS_ZONEOPT_CHECKWILDCARD 0x00002000U /* check for internal wildcards */ #ifndef NOMINUM_PUBLIC /* diff --git a/lib/dns/master.c b/lib/dns/master.c index 615a95a494..82e21ed2f8 100644 --- a/lib/dns/master.c +++ b/lib/dns/master.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: master.c,v 1.149 2004/05/05 01:32:58 marka Exp $ */ +/* $Id: master.c,v 1.150 2005/01/09 23:40:01 marka Exp $ */ #include @@ -862,6 +862,23 @@ check_ns(dns_loadctx_t *lctx, isc_token_t *token, const char *source, return (result); } +static void +check_wildcard(dns_incctx_t *ictx, const char *source, unsigned long line, + dns_rdatacallbacks_t *callbacks) +{ + dns_name_t *name; + + name = (ictx->glue != NULL) ? ictx->glue : ictx->current; + if (dns_name_internalwildcard(name)) { + char namebuf[DNS_NAME_FORMATSIZE]; + + dns_name_format(name, namebuf, sizeof(namebuf)); + (*callbacks->warn)(callbacks, "%s:%lu: warning: ownername " + "'%s' contains an non-terminal wildcard", + source, line, namebuf); + } +} + static isc_result_t load(dns_loadctx_t *lctx) { dns_rdataclass_t rdclass; @@ -1346,6 +1363,14 @@ load(dns_loadctx_t *lctx) { isc_buffer_init(&target, target_mem, target_size); } + /* + * Check for internal wildcards. + */ + if ((lctx->options & DNS_MASTER_CHECKWILDCARD) + != 0) + check_wildcard(ictx, source, line, + callbacks); + } if ((lctx->options & DNS_MASTER_ZONE) != 0 && (lctx->options & DNS_MASTER_SLAVE) == 0 && @@ -1571,7 +1596,7 @@ load(dns_loadctx_t *lctx) { isc_boolean_t ok; dns_name_t *name; - name = (ictx->glue != NULL) ? ictx-> glue : + name = (ictx->glue != NULL) ? ictx->glue : ictx->current; ok = dns_rdata_checkowner(name, lctx->zclass, type, ISC_TRUE); diff --git a/lib/dns/name.c b/lib/dns/name.c index 27110a93ed..f5805a33c0 100644 --- a/lib/dns/name.c +++ b/lib/dns/name.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: name.c,v 1.146 2004/09/01 05:13:05 marka Exp $ */ +/* $Id: name.c,v 1.147 2005/01/09 23:40:01 marka Exp $ */ #include @@ -385,6 +385,41 @@ dns_name_iswildcard(const dns_name_t *name) { return (ISC_FALSE); } +isc_boolean_t +dns_name_internalwildcard(const dns_name_t *name) { + unsigned char *ndata; + unsigned int count; + unsigned int label; + + /* + * Does 'name' contain a internal wildcard? + */ + + REQUIRE(VALID_NAME(name)); + REQUIRE(name->labels > 0); + + /* + * Skip first label. + */ + ndata = name->ndata; + count = *ndata++; + INSIST(count <= 63); + ndata += count; + label = 1; + /* + * Check all but the last of the remaining labels. + */ + while (label + 1 < name->labels) { + count = *ndata++; + INSIST(count <= 63); + if (count == 1 && *ndata == '*') + return (ISC_TRUE); + ndata += count; + label++; + } + return (ISC_FALSE); +} + static inline unsigned int name_hash(dns_name_t *name, isc_boolean_t case_sensitive) { unsigned int length; diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 063c1a64cd..347358e973 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: zone.c,v 1.426 2004/12/21 10:45:18 jinmei Exp $ */ +/* $Id: zone.c,v 1.427 2005/01/09 23:40:02 marka Exp $ */ #include @@ -1148,6 +1148,8 @@ zone_gotreadhandle(isc_task_t *task, isc_event_t *event) { options |= DNS_MASTER_CHECKNAMES; if (DNS_ZONE_OPTION(load->zone, DNS_ZONEOPT_CHECKNAMESFAIL)) options |= DNS_MASTER_CHECKNAMESFAIL; + if (DNS_ZONE_OPTION(load->zone, DNS_ZONEOPT_CHECKWILDCARD)) + options |= DNS_MASTER_CHECKWILDCARD; result = dns_master_loadfileinc(load->zone->masterfile, dns_db_origin(load->db), dns_db_origin(load->db), @@ -1218,6 +1220,8 @@ zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) { options |= DNS_MASTER_CHECKNAMES; if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL)) options |= DNS_MASTER_CHECKNAMESFAIL; + if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKWILDCARD)) + options |= DNS_MASTER_CHECKWILDCARD; if (zone->zmgr != NULL && zone->db != NULL && zone->task != NULL) { load = isc_mem_get(zone->mctx, sizeof(*load)); diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index 90176929dd..866b6bcd8a 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: namedconf.c,v 1.42 2004/12/21 10:45:20 jinmei Exp $ */ +/* $Id: namedconf.c,v 1.43 2005/01/09 23:40:04 marka Exp $ */ #include @@ -788,6 +788,7 @@ zone_clauses[] = { { "use-alt-transfer-source", &cfg_type_boolean, 0 }, { "zone-statistics", &cfg_type_boolean, 0 }, { "key-directory", &cfg_type_qstring, 0 }, + { "check-wildcard", &cfg_type_boolean, 0 }, { NULL, NULL, 0 } };