diff --git a/CHANGES b/CHANGES index c405df69ae..ef29e7d965 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,5 @@ +1964. [func] Seperate out MX and SRV to CNAME checks. [RT #15723] + 1963. [port] Tru64 4.0E doesn't support send() and recv(). [RT #15586] diff --git a/bin/check/check-tool.c b/bin/check/check-tool.c index 2521bf2801..c792baca24 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.21 2005/09/30 08:25:38 marka Exp $ */ +/* $Id: check-tool.c,v 1.22 2006/01/05 23:45:33 marka Exp $ */ /*! \file */ @@ -71,7 +71,9 @@ unsigned int zone_options = DNS_ZONEOPT_CHECKNS | DNS_ZONEOPT_MANYERRORS | DNS_ZONEOPT_CHECKNAMES | DNS_ZONEOPT_CHECKINTEGRITY | - DNS_ZONEOPT_CHECKWILDCARD; + DNS_ZONEOPT_CHECKWILDCARD | + DNS_ZONEOPT_WARNMXCNAME | + DNS_ZONEOPT_WARNSRVCNAME; /* * This needs to match the list in bin/named/log.c. @@ -128,10 +130,11 @@ checkns(dns_zone_t *zone, dns_name_t *name, dns_name_t *owner, case 0: if (strcasecmp(ai->ai_canonname, namebuf) != 0) { dns_zone_log(zone, ISC_LOG_ERROR, - "%s/NS '%s' (out of zone) " + "%s/NS '%s' (out of zone) " "is a CNAME (illegal)", ownerbuf, namebuf); - answer = ISC_FALSE; + /* XXX950 make fatal for 9.5.0 */ + /* answer = ISC_FALSE; */ } break; case EAI_NONAME: @@ -141,7 +144,8 @@ checkns(dns_zone_t *zone, dns_name_t *name, dns_name_t *owner, dns_zone_log(zone, ISC_LOG_ERROR, "%s/NS '%s' (out of zone) " "has no addresses records (A or AAAA)", ownerbuf, namebuf); - return (ISC_FALSE); + /* XXX950 make fatal for 9.5.0 */ + return (ISC_TRUE); default: dns_zone_log(zone, ISC_LOG_WARNING, @@ -175,7 +179,8 @@ checkns(dns_zone_t *zone, dns_name_t *name, dns_name_t *owner, ownerbuf, namebuf, inet_ntop(AF_INET, rdata.data, addrbuf, sizeof(addrbuf))); - answer = ISC_FALSE; + /* XXX950 make fatal for 9.5.0 */ + /* answer = ISC_FALSE; */ } dns_rdata_reset(&rdata); result = dns_rdataset_next(a); @@ -203,7 +208,8 @@ checkns(dns_zone_t *zone, dns_name_t *name, dns_name_t *owner, ownerbuf, namebuf, inet_ntop(AF_INET6, rdata.data, addrbuf, sizeof(addrbuf))); - answer = ISC_FALSE; + /* XXX950 make fatal for 9.5.0. */ + /* answer = ISC_FALSE; */ } dns_rdata_reset(&rdata); result = dns_rdataset_next(aaaa); @@ -246,7 +252,8 @@ checkns(dns_zone_t *zone, dns_name_t *name, dns_name_t *owner, ownerbuf, namebuf, type, inet_ntop(cur->ai_family, ptr, addrbuf, sizeof(addrbuf))); - answer = ISC_FALSE; + /* XXX950 make fatal for 9.5.0. */ + /* answer = ISC_FALSE; */ } } freeaddrinfo(ai); @@ -263,6 +270,8 @@ checkmx(dns_zone_t *zone, dns_name_t *name, dns_name_t *owner) { char namebuf[DNS_NAME_FORMATSIZE + 1]; char ownerbuf[DNS_NAME_FORMATSIZE]; int result; + int level = ISC_LOG_ERROR; + isc_boolean_t answer = ISC_TRUE; memset(&hints, 0, sizeof(hints)); hints.ai_flags = AI_CANONNAME; @@ -282,13 +291,21 @@ checkmx(dns_zone_t *zone, dns_name_t *name, dns_name_t *owner) { dns_name_format(name, namebuf, sizeof(namebuf) - 1); switch (result) { case 0: - if (strcasecmp(ai->ai_canonname, namebuf) != 0) - dns_zone_log(zone, ISC_LOG_WARNING, - "%s/MX '%s' (out of zone) " - "is a CNAME (illegal)", - ownerbuf, namebuf); + if (strcasecmp(ai->ai_canonname, namebuf) != 0) { + if ((zone_options & DNS_ZONEOPT_WARNMXCNAME) != 0) + level = ISC_LOG_WARNING; + if ((zone_options & DNS_ZONEOPT_IGNOREMXCNAME) == 0) { + dns_zone_log(zone, ISC_LOG_WARNING, + "%s/MX '%s' (out of zone) " + "is a CNAME (illegal)", + ownerbuf, namebuf); + if (level == ISC_LOG_ERROR) + answer = ISC_FALSE; + } + } freeaddrinfo(ai); - break; + return (answer); + case EAI_NONAME: #if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME) case EAI_NODATA: @@ -296,7 +313,8 @@ checkmx(dns_zone_t *zone, dns_name_t *name, dns_name_t *owner) { dns_zone_log(zone, ISC_LOG_ERROR, "%s/MX '%s' (out of zone) " "has no addresses records (A or AAAA)", ownerbuf, namebuf); - return (ISC_FALSE); + /* XXX950 make fatal for 9.5.0. */ + return (ISC_TRUE); default: dns_zone_log(zone, ISC_LOG_WARNING, @@ -315,6 +333,8 @@ checksrv(dns_zone_t *zone, dns_name_t *name, dns_name_t *owner) { char namebuf[DNS_NAME_FORMATSIZE + 1]; char ownerbuf[DNS_NAME_FORMATSIZE]; int result; + int level = ISC_LOG_ERROR; + isc_boolean_t answer = ISC_TRUE; memset(&hints, 0, sizeof(hints)); hints.ai_flags = AI_CANONNAME; @@ -334,13 +354,21 @@ checksrv(dns_zone_t *zone, dns_name_t *name, dns_name_t *owner) { dns_name_format(name, namebuf, sizeof(namebuf) - 1); switch (result) { case 0: - if (strcasecmp(ai->ai_canonname, namebuf) != 0) - dns_zone_log(zone, ISC_LOG_WARNING, - "%s/SRV '%s' (out of zone) " - "is a CNAME (illegal)", - ownerbuf, namebuf); + if (strcasecmp(ai->ai_canonname, namebuf) != 0) { + if ((zone_options & DNS_ZONEOPT_WARNSRVCNAME) != 0) + level = ISC_LOG_WARNING; + if ((zone_options & DNS_ZONEOPT_IGNORESRVCNAME) == 0) { + dns_zone_log(zone, level, + "%s/SRV '%s' (out of zone) " + "is a CNAME (illegal)", + ownerbuf, namebuf); + if (level == ISC_LOG_ERROR) + answer = ISC_FALSE; + } + } freeaddrinfo(ai); - break; + return (answer); + case EAI_NONAME: #if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME) case EAI_NODATA: @@ -348,7 +376,8 @@ checksrv(dns_zone_t *zone, dns_name_t *name, dns_name_t *owner) { dns_zone_log(zone, ISC_LOG_ERROR, "%s/SRV '%s' (out of zone) " "has no addresses records (A or AAAA)", ownerbuf, namebuf); - return (ISC_FALSE); + /* XXX950 make fatal for 9.5.0. */ + return (ISC_TRUE); default: dns_zone_log(zone, ISC_LOG_WARNING, diff --git a/bin/check/named-checkconf.c b/bin/check/named-checkconf.c index 3824b20ffa..4315b7ba36 100644 --- a/bin/check/named-checkconf.c +++ b/bin/check/named-checkconf.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: named-checkconf.c,v 1.39 2005/09/18 07:16:17 marka Exp $ */ +/* $Id: named-checkconf.c,v 1.40 2006/01/05 23:45:33 marka Exp $ */ /*! \file */ @@ -225,6 +225,42 @@ configure_zone(const char *vclass, const char *view, cfg_obj_t *zconfig, zone_options &= ~DNS_ZONEOPT_CHECKINTEGRITY; } + obj = NULL; + if (get_maps(maps, "check-mx-cname", &obj)) { + if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { + zone_options |= DNS_ZONEOPT_WARNMXCNAME; + zone_options &= ~DNS_ZONEOPT_IGNOREMXCNAME; + } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { + zone_options &= ~DNS_ZONEOPT_WARNMXCNAME; + zone_options &= ~DNS_ZONEOPT_IGNOREMXCNAME; + } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { + zone_options |= DNS_ZONEOPT_WARNMXCNAME; + zone_options |= DNS_ZONEOPT_IGNOREMXCNAME; + } else + INSIST(0); + } else { + zone_options |= DNS_ZONEOPT_WARNMXCNAME; + zone_options &= ~DNS_ZONEOPT_IGNOREMXCNAME; + } + + obj = NULL; + if (get_maps(maps, "check-srv-cname", &obj)) { + if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { + zone_options |= DNS_ZONEOPT_WARNSRVCNAME; + zone_options &= ~DNS_ZONEOPT_IGNORESRVCNAME; + } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { + zone_options &= ~DNS_ZONEOPT_WARNSRVCNAME; + zone_options &= ~DNS_ZONEOPT_IGNORESRVCNAME; + } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { + zone_options |= DNS_ZONEOPT_WARNSRVCNAME; + zone_options |= DNS_ZONEOPT_IGNORESRVCNAME; + } else + INSIST(0); + } else { + zone_options |= DNS_ZONEOPT_WARNSRVCNAME; + zone_options &= ~DNS_ZONEOPT_IGNORESRVCNAME; + } + obj = NULL; if (get_maps(maps, "check-sibling", &obj)) { if (cfg_obj_asboolean(obj)) diff --git a/bin/check/named-checkzone.c b/bin/check/named-checkzone.c index f7873ae14b..9970743fd8 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.41 2005/09/18 07:16:17 marka Exp $ */ +/* $Id: named-checkzone.c,v 1.42 2006/01/05 23:45:33 marka Exp $ */ /*! \file */ @@ -77,7 +77,8 @@ usage(void) { "[-f inputformat] [-F outputformat] " "[-t directory] [-w directory] [-k (ignore|warn|fail)] " "[-n (ignore|warn|fail)] [-m (ignore|warn|fail)] " - "[-i (full|local|none)] [-W (ignore|warn)] " + "[-i (full|local|none)] [-M (ignore|warn|fail)] " + "[-S (ignore|warn|fail)] [-W (ignore|warn)] " "zonename filename\n", prog_name); exit(1); } @@ -134,8 +135,10 @@ main(int argc, char **argv) { DNS_ZONEOPT_CHECKWILDCARD); } +#define ARGCMP(X) (strcmp(isc_commandline_argument, X) == 0) + while ((c = isc_commandline_parse(argc, argv, - "c:df:i:jk:m:n:qst:o:vw:DF:W:")) + "c:df:i:jk:m:n:qst:o:vw:DF:M:S:W:")) != EOF) { switch (c) { case 'c': @@ -147,35 +150,31 @@ main(int argc, char **argv) { break; case 'i': - if (!strcmp(isc_commandline_argument, "full")) { + if (ARGCMP("full")) { zone_options |= DNS_ZONEOPT_CHECKINTEGRITY | DNS_ZONEOPT_CHECKSIBLING; docheckmx = ISC_TRUE; docheckns = ISC_TRUE; dochecksrv = ISC_TRUE; - } else if (!strcmp(isc_commandline_argument, - "full-sibling")) { + } else if (ARGCMP("full-sibling")) { zone_options |= DNS_ZONEOPT_CHECKINTEGRITY; zone_options &= ~DNS_ZONEOPT_CHECKSIBLING; docheckmx = ISC_TRUE; docheckns = ISC_TRUE; dochecksrv = ISC_TRUE; - } else if (!strcmp(isc_commandline_argument, - "local")) { + } else if (ARGCMP("local")) { zone_options |= DNS_ZONEOPT_CHECKINTEGRITY; zone_options |= DNS_ZONEOPT_CHECKSIBLING; docheckmx = ISC_FALSE; docheckns = ISC_FALSE; dochecksrv = ISC_FALSE; - } else if (!strcmp(isc_commandline_argument, - "local-sibling")) { + } else if (ARGCMP("local-sibling")) { zone_options |= DNS_ZONEOPT_CHECKINTEGRITY; zone_options &= ~DNS_ZONEOPT_CHECKSIBLING; docheckmx = ISC_FALSE; docheckns = ISC_FALSE; dochecksrv = ISC_FALSE; - } else if (!strcmp(isc_commandline_argument, - "none")) { + } else if (ARGCMP("none")) { zone_options &= ~DNS_ZONEOPT_CHECKINTEGRITY; zone_options &= ~DNS_ZONEOPT_CHECKSIBLING; docheckmx = ISC_FALSE; @@ -201,15 +200,13 @@ main(int argc, char **argv) { break; case 'k': - if (!strcmp(isc_commandline_argument, "warn")) { + if (ARGCMP("warn")) { zone_options |= DNS_ZONEOPT_CHECKNAMES; zone_options &= ~DNS_ZONEOPT_CHECKNAMESFAIL; - } else if (!strcmp(isc_commandline_argument, - "fail")) { + } else if (ARGCMP("fail")) { zone_options |= DNS_ZONEOPT_CHECKNAMES | DNS_ZONEOPT_CHECKNAMESFAIL; - } else if (!strcmp(isc_commandline_argument, - "ignore")) { + } else if (ARGCMP("ignore")) { zone_options &= ~(DNS_ZONEOPT_CHECKNAMES | DNS_ZONEOPT_CHECKNAMESFAIL); } else { @@ -220,13 +217,13 @@ main(int argc, char **argv) { break; case 'n': - if (!strcmp(isc_commandline_argument, "ignore")) { + if (ARGCMP("ignore")) { zone_options &= ~(DNS_ZONEOPT_CHECKNS| DNS_ZONEOPT_FATALNS); - } else if (!strcmp(isc_commandline_argument, "warn")) { + } else if (ARGCMP("warn")) { zone_options |= DNS_ZONEOPT_CHECKNS; zone_options &= ~DNS_ZONEOPT_FATALNS; - } else if (!strcmp(isc_commandline_argument, "fail")) { + } else if (ARGCMP("fail")) { zone_options |= DNS_ZONEOPT_CHECKNS| DNS_ZONEOPT_FATALNS; } else { @@ -237,15 +234,13 @@ main(int argc, char **argv) { break; case 'm': - if (!strcmp(isc_commandline_argument, "warn")) { + if (ARGCMP("warn")) { zone_options |= DNS_ZONEOPT_CHECKMX; zone_options &= ~DNS_ZONEOPT_CHECKMXFAIL; - } else if (!strcmp(isc_commandline_argument, - "fail")) { + } else if (ARGCMP("fail")) { zone_options |= DNS_ZONEOPT_CHECKMX | DNS_ZONEOPT_CHECKMXFAIL; - } else if (!strcmp(isc_commandline_argument, - "ignore")) { + } else if (ARGCMP("ignore")) { zone_options &= ~(DNS_ZONEOPT_CHECKMX | DNS_ZONEOPT_CHECKMXFAIL); } else { @@ -276,10 +271,9 @@ main(int argc, char **argv) { break; case 's': - if (strcmp(isc_commandline_argument, "full") == 0) + if (ARGCMP("full")) outputstyle = &dns_master_style_full; - else if (strcmp(isc_commandline_argument, - "default") == 0) { + else if (ARGCMP("default")) { outputstyle = &dns_master_style_default; } else { fprintf(stderr, @@ -305,10 +299,44 @@ main(int argc, char **argv) { dumpzone++; break; + case 'M': + if (ARGCMP("fail")) { + zone_options &= ~DNS_ZONEOPT_WARNMXCNAME; + zone_options &= ~DNS_ZONEOPT_IGNOREMXCNAME; + } else if (ARGCMP("warn")) { + zone_options |= DNS_ZONEOPT_WARNMXCNAME; + zone_options &= ~DNS_ZONEOPT_IGNOREMXCNAME; + } else if (ARGCMP("ignore")) { + zone_options |= DNS_ZONEOPT_WARNMXCNAME; + zone_options |= DNS_ZONEOPT_IGNOREMXCNAME; + } else { + fprintf(stderr, "invalid argument to -M: %s\n", + isc_commandline_argument); + exit(1); + } + break; + + case 'S': + if (ARGCMP("fail")) { + zone_options &= ~DNS_ZONEOPT_WARNSRVCNAME; + zone_options &= ~DNS_ZONEOPT_IGNORESRVCNAME; + } else if (ARGCMP("warn")) { + zone_options |= DNS_ZONEOPT_WARNSRVCNAME; + zone_options &= ~DNS_ZONEOPT_IGNORESRVCNAME; + } else if (ARGCMP("ignore")) { + zone_options |= DNS_ZONEOPT_WARNSRVCNAME; + zone_options |= DNS_ZONEOPT_IGNORESRVCNAME; + } else { + fprintf(stderr, "invalid argument to -S: %s\n", + isc_commandline_argument); + exit(1); + } + break; + case 'W': - if (!strcmp(isc_commandline_argument, "warn")) + if (ARGCMP("warn")) zone_options |= DNS_ZONEOPT_CHECKWILDCARD; - else if (!strcmp(isc_commandline_argument, "ignore")) + else if (ARGCMP("ignore")) zone_options &= ~DNS_ZONEOPT_CHECKWILDCARD; break; diff --git a/bin/check/named-checkzone.docbook b/bin/check/named-checkzone.docbook index f902a19362..a2a6824c7b 100644 --- a/bin/check/named-checkzone.docbook +++ b/bin/check/named-checkzone.docbook @@ -18,7 +18,7 @@ - PERFORMANCE OF THIS SOFTWARE. --> - + June 13, 2000 @@ -63,9 +63,11 @@ + + @@ -80,6 +82,7 @@ + @@ -264,6 +267,18 @@ + + -M mode + + + Check if a MX record refers to a CNAME. + Possible modes are "fail", + "warn" (default) and + "ignore". + + + + -n mode @@ -309,6 +324,18 @@ + + -S mode + + + Check if a SRV record refers to a CNAME. + Possible modes are "fail", + "warn" (default) and + "ignore". + + + + -t directory diff --git a/bin/named/config.c b/bin/named/config.c index e06cff7f67..728274840c 100644 --- a/bin/named/config.c +++ b/bin/named/config.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: config.c,v 1.66 2006/01/05 02:19:01 marka Exp $ */ +/* $Id: config.c,v 1.67 2006/01/05 23:45:33 marka Exp $ */ /*! \file */ @@ -171,6 +171,8 @@ options {\n\ check-wildcard yes;\n\ check-sibling yes;\n\ check-integrity yes;\n\ + check-mx-cname warn;\n\ + check-srv-cname warn;\n\ zero-no-soa-ttl yes;\n\ };\n\ " diff --git a/bin/named/named.conf.docbook b/bin/named/named.conf.docbook index ff5b71de8d..091a659887 100644 --- a/bin/named/named.conf.docbook +++ b/bin/named/named.conf.docbook @@ -17,7 +17,7 @@ - PERFORMANCE OF THIS SOFTWARE. --> - + Aug 13, 2004 @@ -247,7 +247,9 @@ options { check-names ( master | slave | response ) ( fail | warn | ignore ); check-mx ( fail | warn | ignore ); - integrity-check boolean; + check-integrity boolean; + check-mx-cname ( fail | warn | ignore ); + check-srv-cname ( fail | warn | ignore ); cache-file quoted_string; suppress-initial-notify boolean; // not yet implemented preferred-glue string; @@ -391,7 +393,9 @@ view string optional_class check-names ( master | slave | response ) ( fail | warn | ignore ); check-mx ( fail | warn | ignore ); - integrity-check boolean; + check-integrity boolean; + check-mx-cname ( fail | warn | ignore ); + check-srv-cname ( fail | warn | ignore ); cache-file quoted_string; suppress-initial-notify boolean; // not yet implemented preferred-glue string; @@ -490,7 +494,9 @@ zone string optional_class delegation-only boolean; check-names ( fail | warn | ignore ); check-mx ( fail | warn | ignore ); - integrity-check boolean; + check-integrity boolean; + check-mx-cname ( fail | warn | ignore ); + check-srv-cname ( fail | warn | ignore ); dialup dialuptype; ixfr-from-differences boolean; journal quoted_string; diff --git a/bin/named/zoneconf.c b/bin/named/zoneconf.c index 3262028aed..8fafb61722 100644 --- a/bin/named/zoneconf.c +++ b/bin/named/zoneconf.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: zoneconf.c,v 1.127 2006/01/05 03:32:50 marka Exp $ */ +/* $Id: zoneconf.c,v 1.128 2006/01/05 23:45:33 marka Exp $ */ /*% */ @@ -342,6 +342,7 @@ ns_zone_configure(cfg_obj_t *config, cfg_obj_t *vconfig, cfg_obj_t *zconfig, isc_boolean_t alt; dns_view_t *view; isc_boolean_t check = ISC_FALSE, fail = ISC_FALSE; + isc_boolean_t warn = ISC_FALSE, ignore = ISC_FALSE; isc_boolean_t ixfrdiff; dns_masterformat_t masterformat; @@ -682,6 +683,36 @@ ns_zone_configure(cfg_obj_t *config, cfg_obj_t *vconfig, cfg_obj_t *zconfig, INSIST(obj != NULL); dns_zone_setoption(zone, DNS_ZONEOPT_CHECKINTEGRITY, cfg_obj_asboolean(obj)); + + obj = NULL; + result = ns_config_get(maps, "check-mx-cname", &obj); + INSIST(obj != NULL); + if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { + warn = ISC_TRUE; + ignore = ISC_FALSE; + } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { + warn = ignore = ISC_FALSE; + } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { + warn = ignore = ISC_TRUE; + } else + INSIST(0); + dns_zone_setoption(zone, DNS_ZONEOPT_WARNMXCNAME, warn); + dns_zone_setoption(zone, DNS_ZONEOPT_IGNOREMXCNAME, ignore); + + obj = NULL; + result = ns_config_get(maps, "check-srv-cname", &obj); + INSIST(obj != NULL); + if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { + warn = ISC_TRUE; + ignore = ISC_FALSE; + } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { + warn = ignore = ISC_FALSE; + } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { + warn = ignore = ISC_TRUE; + } else + INSIST(0); + dns_zone_setoption(zone, DNS_ZONEOPT_WARNSRVCNAME, warn); + dns_zone_setoption(zone, DNS_ZONEOPT_IGNORESRVCNAME, ignore); } /* diff --git a/doc/arm/Bv9ARM-book.xml b/doc/arm/Bv9ARM-book.xml index 6fa9da3177..70c021d7d3 100644 --- a/doc/arm/Bv9ARM-book.xml +++ b/doc/arm/Bv9ARM-book.xml @@ -18,7 +18,7 @@ - PERFORMANCE OF THIS SOFTWARE. --> - + BIND 9 Administrator Reference Manual @@ -4402,6 +4402,8 @@ category notify { null; }; check-mx ( warn | fail | ignore ); check-wildcard yes_or_no; check-integrity yes_or_no; + check-mx-cname ( warn | fail | ignore ); + check-srv-cname ( warn | fail | ignore ); check-sibling yes_or_no; allow-notify { address_match_list }; allow-query { address_match_list }; @@ -5580,6 +5582,28 @@ options { + + check-mx-cname + + + If check-integrity is set then + fail, warn or ignore MX records that refer + to CNAMES. The default is to warn. + + + + + + check-srv-cname + + + If check-integrity is set then + fail, warn or ignore SRV records that refer + to CNAMES. The default is to warn. + + + + check-sibling diff --git a/lib/bind9/check.c b/lib/bind9/check.c index b8356de209..2c4725ace5 100644 --- a/lib/bind9/check.c +++ b/lib/bind9/check.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: check.c,v 1.65 2005/11/03 22:59:52 marka Exp $ */ +/* $Id: check.c,v 1.66 2006/01/05 23:45:33 marka Exp $ */ /*! \file */ @@ -931,6 +931,8 @@ check_zoneconf(cfg_obj_t *zconfig, cfg_obj_t *voptions, cfg_obj_t *config, { "check-wildcard", MASTERZONE }, { "check-mx", MASTERZONE }, { "integrity-check", MASTERZONE }, + { "check-mx-cname", MASTERZONE }, + { "check-srv-cname", MASTERZONE }, { "masterfile-format", MASTERZONE | SLAVEZONE | STUBZONE | HINTZONE }, }; diff --git a/lib/dns/include/dns/zone.h b/lib/dns/include/dns/zone.h index 9e397351d1..9cf9bbf2b2 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.139 2006/01/05 02:19:02 marka Exp $ */ +/* $Id: zone.h,v 1.140 2006/01/05 23:45:34 marka Exp $ */ #ifndef DNS_ZONE_H #define DNS_ZONE_H 1 @@ -59,8 +59,12 @@ typedef enum { #define DNS_ZONEOPT_CHECKMX 0x00004000U /*%< check-mx */ #define DNS_ZONEOPT_CHECKMXFAIL 0x00008000U /*%< fatal check-mx failures */ #define DNS_ZONEOPT_CHECKINTEGRITY 0x00010000U /*%< perform integrity checks */ -#define DNS_ZONEOPT_CHECKSIBLING 0x00020000U /*%< perform sibling glue checks */ +#define DNS_ZONEOPT_CHECKSIBLING 0x00020000U /*%< perform sibling glue checks */ #define DNS_ZONEOPT_NOCHECKNS 0x00040000U /*%< disable IN NS address checks */ +#define DNS_ZONEOPT_WARNMXCNAME 0x00080000U /*%< warn on MX CNAME check */ +#define DNS_ZONEOPT_IGNOREMXCNAME 0x00100000U /*%< ignore MX CNAME check */ +#define DNS_ZONEOPT_WARNSRVCNAME 0x00200000U /*%< warn on SRV CNAME check */ +#define DNS_ZONEOPT_IGNORESRVCNAME 0x00400000U /*%< ignore SRV CNAME check */ #ifndef NOMINUM_PUBLIC /* diff --git a/lib/dns/zone.c b/lib/dns/zone.c index f377cf1f15..3059d057f2 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: zone.c,v 1.449 2006/01/05 02:19:02 marka Exp $ */ +/* $Id: zone.c,v 1.450 2006/01/05 23:45:33 marka Exp $ */ /*! \file */ @@ -468,7 +468,7 @@ zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount, unsigned int *soacount, isc_uint32_t *serial, isc_uint32_t *refresh, isc_uint32_t *retry, isc_uint32_t *expire, isc_uint32_t *minimum, - unsigned int *cnames); + unsigned int *errors); static void zone_freedbargs(dns_zone_t *zone); static void forward_callback(isc_task_t *task, isc_event_t *event); @@ -1411,21 +1411,32 @@ zone_check_mx(dns_zone_t *zone, dns_db_t *db, dns_name_t *name, dns_zone_log(zone, level, "%s/MX '%s' has no address records (A or AAAA)", ownerbuf, namebuf); - return (ISC_FALSE); + /* XXX950 make fatal for 9.5.0. */ + return (ISC_TRUE); } if (result == DNS_R_CNAME) { - dns_zone_log(zone, level, "%s/MX '%s' is a CNAME (illegal)", - ownerbuf, namebuf); - return (ISC_FALSE); + if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) || + DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) + level = ISC_LOG_WARNING; + if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) + dns_zone_log(zone, level, + "%s/MX '%s' is a CNAME (illegal)", + ownerbuf, namebuf); + return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE); } if (result == DNS_R_DNAME) { - dns_name_format(foundname, altbuf, sizeof altbuf); - dns_zone_log(zone, level, - "%s/MX '%s' is below a DNAME '%s' (illegal)", - ownerbuf, namebuf, altbuf); - return (ISC_FALSE); + if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) || + DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) + level = ISC_LOG_WARNING; + if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) { + dns_name_format(foundname, altbuf, sizeof altbuf); + dns_zone_log(zone, level, "%s/MX '%s' is below a DNAME" + " '%s' (illegal)", ownerbuf, namebuf, + altbuf); + } + return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE); } if (zone->checkmx != NULL && result == DNS_R_DELEGATION) @@ -1446,6 +1457,12 @@ zone_check_srv(dns_zone_t *zone, dns_db_t *db, dns_name_t *name, dns_name_t *foundname; int level; + /* + * "." means the services does not exist. + */ + if (dns_name_equal(name, dns_rootname)) + return (ISC_TRUE); + /* * Outside of zone. */ @@ -1482,21 +1499,32 @@ zone_check_srv(dns_zone_t *zone, dns_db_t *db, dns_name_t *name, dns_zone_log(zone, level, "%s/SRV '%s' has no address records (A or AAAA)", ownerbuf, namebuf); - return (ISC_FALSE); + /* XXX950 make fatal for 9.5.0. */ + return (ISC_TRUE); } if (result == DNS_R_CNAME) { - dns_zone_log(zone, level, "%s/SRV '%s' is a CNAME (illegal)", - ownerbuf, namebuf); - return (ISC_FALSE); + if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) || + DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) + level = ISC_LOG_WARNING; + if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) + dns_zone_log(zone, level, + "%s/SRV '%s' is a CNAME (illegal)", + ownerbuf, namebuf); + return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE); } if (result == DNS_R_DNAME) { - dns_name_format(foundname, altbuf, sizeof altbuf); - dns_zone_log(zone, level, - "%s/SRV '%s' is below a DNAME '%s' (illegal)", - ownerbuf, namebuf, altbuf); - return (ISC_FALSE); + if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) || + DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) + level = ISC_LOG_WARNING; + if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) { + dns_name_format(foundname, altbuf, sizeof altbuf); + dns_zone_log(zone, level, "%s/SRV '%s' is below a " + "DNAME '%s' (illegal)", ownerbuf, namebuf, + altbuf); + } + return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE); } if (zone->checksrv != NULL && result == DNS_R_DELEGATION) @@ -1599,18 +1627,21 @@ zone_check_glue(dns_zone_t *zone, dns_db_t *db, dns_name_t *name, if (result == DNS_R_DELEGATION && zone->checkns != NULL) (void)(zone->checkns)(zone, name, owner, &a, &aaaa); - answer = ISC_FALSE; + /* XXX950 make fatal for 9.5.0. */ + /* answer = ISC_FALSE; */ } } else if (result == DNS_R_CNAME) { dns_zone_log(zone, level, "%s/NS '%s' is a CNAME (illegal)", ownerbuf, namebuf); - answer = ISC_FALSE; + /* XXX950 make fatal for 9.5.0. */ + /* answer = ISC_FALSE; */ } else if (result == DNS_R_DNAME) { dns_name_format(foundname, altbuf, sizeof altbuf); dns_zone_log(zone, level, "%s/NS '%s' is below a DNAME '%s' (illegal)", ownerbuf, namebuf, altbuf); - answer = ISC_FALSE; + /* XXX950 make fatal for 9.5.0. */ + /* answer = ISC_FALSE; */ } if (dns_rdataset_isassociated(&a)) @@ -1743,7 +1774,7 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, { unsigned int soacount = 0; unsigned int nscount = 0; - unsigned int cnames = 0; + unsigned int errors = 0; isc_uint32_t serial, refresh, retry, expire, minimum; isc_time_t now; isc_boolean_t needdump = ISC_FALSE; @@ -1826,7 +1857,7 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, INSIST(db != NULL); result = zone_get_from_db(zone, db, &nscount, &soacount, &serial, &refresh, &retry, &expire, &minimum, - &cnames); + &errors); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "could not find NS and/or SOA records"); @@ -1853,7 +1884,7 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, } if (result != ISC_R_SUCCESS) goto cleanup; - if (zone->type == dns_zone_master && cnames != 0) { + if (zone->type == dns_zone_master && errors != 0) { result = DNS_R_BADZONE; goto cleanup; } @@ -2042,13 +2073,15 @@ zone_check_ns(dns_zone_t *zone, dns_db_t *db, dns_name_t *name) { dns_zone_log(zone, level, "NS '%s' has no address records (A or AAAA)", namebuf); - return (ISC_FALSE); + /* XXX950 Make fatal ISC_FALSE for 9.5.0. */ + return (ISC_TRUE); } if (result == DNS_R_CNAME) { dns_zone_log(zone, level, "NS '%s' is a CNAME (illegal)", namebuf); - return (ISC_FALSE); + /* XXX950 Make fatal ISC_FALSE for 9.5.0. */ + return (ISC_TRUE); } if (result == DNS_R_DNAME) { @@ -2056,7 +2089,8 @@ zone_check_ns(dns_zone_t *zone, dns_db_t *db, dns_name_t *name) { dns_zone_log(zone, level, "NS '%s' is below a DNAME '%s' (illegal)", namebuf, altbuf); - return (ISC_FALSE); + /* XXX950 Make fatal ISC_FALSE for 9.5.0. */ + return (ISC_TRUE); } return (ISC_TRUE); @@ -2065,11 +2099,11 @@ zone_check_ns(dns_zone_t *zone, dns_db_t *db, dns_name_t *name) { static isc_result_t zone_count_ns_rr(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, unsigned int *nscount, - unsigned int *cnames) + unsigned int *errors) { isc_result_t result; unsigned int count = 0; - unsigned int ccount = 0; + unsigned int ecount = 0; dns_rdataset_t rdataset; dns_rdata_t rdata; dns_rdata_ns_t ns; @@ -2084,7 +2118,7 @@ zone_count_ns_rr(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node, result = dns_rdataset_first(&rdataset); while (result == ISC_R_SUCCESS) { - if (cnames != NULL && zone->rdclass == dns_rdataclass_in && + if (errors != NULL && zone->rdclass == dns_rdataclass_in && (zone->type == dns_zone_master || zone->type == dns_zone_slave)) { dns_rdata_init(&rdata); @@ -2093,7 +2127,7 @@ zone_count_ns_rr(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node, RUNTIME_CHECK(result == ISC_R_SUCCESS); if (dns_name_issubdomain(&ns.name, &zone->origin) && !zone_check_ns(zone, db, &ns.name)) - ccount++; + ecount++; } count++; result = dns_rdataset_next(&rdataset); @@ -2103,8 +2137,8 @@ zone_count_ns_rr(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node, success: if (nscount != NULL) *nscount = count; - if (cnames != NULL) - *cnames = ccount; + if (errors != NULL) + *errors = ecount; result = ISC_R_SUCCESS; @@ -2197,7 +2231,7 @@ zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount, unsigned int *soacount, isc_uint32_t *serial, isc_uint32_t *refresh, isc_uint32_t *retry, isc_uint32_t *expire, isc_uint32_t *minimum, - unsigned int *cnames) + unsigned int *errors) { dns_dbversion_t *version; isc_result_t result; @@ -2217,9 +2251,9 @@ zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount, goto closeversion; } - if (nscount != NULL || cnames != NULL) { + if (nscount != NULL || errors != NULL) { result = zone_count_ns_rr(zone, db, node, version, - nscount, cnames); + nscount, errors); if (result != ISC_R_SUCCESS) answer = result; } diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index 7946095bf7..928a248e0e 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: namedconf.c,v 1.62 2006/01/05 02:19:02 marka Exp $ */ +/* $Id: namedconf.c,v 1.63 2006/01/05 23:45:34 marka Exp $ */ /*! \file */ @@ -840,6 +840,8 @@ zone_clauses[] = { { "check-wildcard", &cfg_type_boolean, 0 }, { "check-integrity", &cfg_type_boolean, 0 }, { "check-mx", &cfg_type_checkmode, 0 }, + { "check-mx-cname", &cfg_type_checkmode, 0 }, + { "check-srv-cname", &cfg_type_checkmode, 0 }, { "check-sibling", &cfg_type_boolean, 0 }, { "zero-no-soa-ttl", &cfg_type_boolean, 0 }, { NULL, NULL, 0 }