From 0e507dbb816575e6220fe309e8ada68897ffcdbe Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Wed, 23 Feb 2011 03:08:11 +0000 Subject: [PATCH] 2039. [func] Redirect on NXDOMAIN support. [RT #23146] --- CHANGES | 2 + bin/named/bind.keys.h | 4 +- bin/named/config.c | 4 +- bin/named/named.conf.docbook | 4 +- bin/named/query.c | 111 ++++++- bin/named/server.c | 45 ++- bin/named/zoneconf.c | 34 ++- bin/tests/system/conf.sh.in | 4 +- bin/tests/system/redirect/clean.sh | 27 ++ bin/tests/system/redirect/conf/bad1.conf | 11 + bin/tests/system/redirect/conf/bad2.conf | 11 + bin/tests/system/redirect/conf/bad3.conf | 10 + bin/tests/system/redirect/conf/good1.conf | 9 + bin/tests/system/redirect/conf/good2.conf | 9 + bin/tests/system/redirect/conf/good3.conf | 10 + bin/tests/system/redirect/conf/good4.conf | 10 + bin/tests/system/redirect/ns1/example.db | 55 ++++ bin/tests/system/redirect/ns1/named.conf | 65 +++++ bin/tests/system/redirect/ns1/redirect.db | 12 + bin/tests/system/redirect/ns1/root.db | 24 ++ bin/tests/system/redirect/ns1/sign.sh | 44 +++ bin/tests/system/redirect/ns2/named.conf | 49 ++++ bin/tests/system/redirect/ns2/redirect.db | 12 + bin/tests/system/redirect/setup.sh | 23 ++ bin/tests/system/redirect/tests.sh | 336 ++++++++++++++++++++++ doc/arm/Bv9ARM-book.xml | 29 +- lib/bind9/check.c | 65 +++-- lib/dns/include/dns/view.h | 3 +- lib/dns/include/dns/zone.h | 5 +- lib/dns/view.c | 10 +- lib/dns/zone.c | 110 +++++-- lib/isccfg/namedconf.c | 4 +- 32 files changed, 1071 insertions(+), 80 deletions(-) create mode 100644 bin/tests/system/redirect/clean.sh create mode 100644 bin/tests/system/redirect/conf/bad1.conf create mode 100644 bin/tests/system/redirect/conf/bad2.conf create mode 100644 bin/tests/system/redirect/conf/bad3.conf create mode 100644 bin/tests/system/redirect/conf/good1.conf create mode 100644 bin/tests/system/redirect/conf/good2.conf create mode 100644 bin/tests/system/redirect/conf/good3.conf create mode 100644 bin/tests/system/redirect/conf/good4.conf create mode 100644 bin/tests/system/redirect/ns1/example.db create mode 100644 bin/tests/system/redirect/ns1/named.conf create mode 100644 bin/tests/system/redirect/ns1/redirect.db create mode 100644 bin/tests/system/redirect/ns1/root.db create mode 100644 bin/tests/system/redirect/ns1/sign.sh create mode 100644 bin/tests/system/redirect/ns2/named.conf create mode 100644 bin/tests/system/redirect/ns2/redirect.db create mode 100644 bin/tests/system/redirect/setup.sh create mode 100644 bin/tests/system/redirect/tests.sh diff --git a/CHANGES b/CHANGES index 017223a371..e238e99858 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,5 @@ +2039. [func] Redirect on NXDOMAIN support. [RT #23146] + 2038. [bug] Install . [RT #23342] 2037. [doc] Update COPYRIGHT to contain all the individual diff --git a/bin/named/bind.keys.h b/bin/named/bind.keys.h index 61e3f700c6..0177214159 100644 --- a/bin/named/bind.keys.h +++ b/bin/named/bind.keys.h @@ -1,6 +1,6 @@ /* - * Generated by bindkeys.pl 1.7 2011/01/04 23:47:13 tbox Exp - * From bind.keys 1.7 2011/01/03 23:45:07 each Exp + * Generated by bindkeys.pl 1.7 2011-01-04 23:47:13 tbox Exp + * From bind.keys 1.7 2011-01-03 23:45:07 each Exp */ #define TRUSTED_KEYS "\ # The bind.keys file is used to override the built-in DNSSEC trust anchors\n\ diff --git a/bin/named/config.c b/bin/named/config.c index 4fc64e60ef..7122e27a32 100644 --- a/bin/named/config.c +++ b/bin/named/config.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: config.c,v 1.115 2011/02/03 12:18:10 tbox Exp $ */ +/* $Id: config.c,v 1.116 2011/02/23 03:08:08 marka Exp $ */ /*! \file */ @@ -377,6 +377,8 @@ ns_config_getzonetype(const cfg_obj_t *zonetypeobj) { ztype = dns_zone_stub; else if (strcasecmp(str, "static-stub") == 0) ztype = dns_zone_staticstub; + else if (strcasecmp(str, "redirect") == 0) + ztype = dns_zone_redirect; else INSIST(0); return (ztype); diff --git a/bin/named/named.conf.docbook b/bin/named/named.conf.docbook index aa1e54b687..87971075de 100644 --- a/bin/named/named.conf.docbook +++ b/bin/named/named.conf.docbook @@ -17,7 +17,7 @@ - PERFORMANCE OF THIS SOFTWARE. --> - + Aug 13, 2004 @@ -563,7 +563,7 @@ view string optional_class ZONE zone string optional_class { - type ( master | slave | stub | hint | + type ( master | slave | stub | hint | redirect | forward | delegation-only ); file quoted_string; diff --git a/bin/named/query.c b/bin/named/query.c index b00689186d..bab7cfd857 100644 --- a/bin/named/query.c +++ b/bin/named/query.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: query.c,v 1.355 2011/02/18 15:18:30 smann Exp $ */ +/* $Id: query.c,v 1.356 2011/02/23 03:08:08 marka Exp $ */ /*! \file */ @@ -4928,6 +4928,106 @@ dns64_aaaaok(ns_client_t *client, dns_rdataset_t *rdataset, return (ISC_FALSE); } +/* + * Look for the name and type in the redirection zone. If found update + * the arguments as appropriate. Return ISC_TRUE if a update was + * performed. + * + * Only perform the update if the client is in the allow query acl and + * returning the update would not cause a DNSSEC validation failure. + */ +static isc_boolean_t +redirect(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset, + dns_dbnode_t **nodep, dns_db_t **dbp, dns_rdatatype_t qtype) +{ + dns_db_t *db = NULL; + dns_dbnode_t *node = NULL; + dns_fixedname_t fixed; + dns_name_t *found; + dns_rdataset_t trdataset; + isc_result_t result; + dns_rdatatype_t type; + + CTRACE("redirect"); + + if (client->view->redirect == NULL) + return (ISC_FALSE); + + dns_fixedname_init(&fixed); + found = dns_fixedname_name(&fixed); + dns_rdataset_init(&trdataset); + + if (WANTDNSSEC(client) && dns_db_iszone(*dbp) && dns_db_issecure(*dbp)) + return (ISC_FALSE); + + if (WANTDNSSEC(client) && dns_rdataset_isassociated(rdataset)) { + if (rdataset->trust == dns_trust_secure) + return (ISC_FALSE); + if (rdataset->trust == dns_trust_ultimate && + (rdataset->type == dns_rdatatype_nsec || + rdataset->type == dns_rdatatype_nsec3)) + return (ISC_FALSE); + if (rdataset->type == 0) { + for (result = dns_rdataset_first(rdataset); + result == ISC_R_SUCCESS; + result = dns_rdataset_next(rdataset)) { + dns_ncache_current(rdataset, found, &trdataset); + type = trdataset.type; + dns_rdataset_disassociate(&trdataset); + if (type == dns_rdatatype_nsec || + type == dns_rdatatype_nsec3 || + type == dns_rdatatype_rrsig) + return (ISC_FALSE); + } + } + } + + result = ns_client_checkaclsilent(client, NULL, + dns_zone_getqueryacl(client->view->redirect), + ISC_TRUE); + if (result != ISC_R_SUCCESS) + return (ISC_FALSE); + + result = dns_zone_getdb(client->view->redirect, &db); + if (result != ISC_R_SUCCESS) + return (ISC_FALSE); + + /* + * Lookup the requested data in the redirect zone. + */ + result = dns_db_find(db, client->query.qname, NULL, qtype, 0, + client->now, &node, found, &trdataset, NULL); + if (result != ISC_R_SUCCESS) { + if (dns_rdataset_isassociated(&trdataset)) + dns_rdataset_disassociate(&trdataset); + if (node != NULL) + dns_db_detachnode(db, &node); + dns_db_detach(&db); + return (ISC_FALSE); + } + CTRACE("redirect: found data: done"); + + dns_name_copy(found, name, NULL); + if (dns_rdataset_isassociated(rdataset)) + dns_rdataset_disassociate(rdataset); + if (dns_rdataset_isassociated(&trdataset)) { + dns_rdataset_clone(&trdataset, rdataset); + dns_rdataset_disassociate(&trdataset); + } + if (*nodep != NULL) + dns_db_detachnode(*dbp, nodep); + dns_db_detach(dbp); + dns_db_attachnode(db, node, nodep); + dns_db_attach(db, dbp); + dns_db_detachnode(db, &node); + dns_db_detach(&db); + + client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY | + NS_QUERYATTR_NOADDITIONAL); + + return (ISC_TRUE); +} + /* * Do the bulk of query processing for the current query of 'client'. * If 'event' is non-NULL, we are returning from recursion and 'qtype' @@ -5844,6 +5944,11 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) case DNS_R_NXDOMAIN: INSIST(is_zone); + if (!empty_wild && + redirect(client, fname, rdataset, &node, &db, type)) { + result = ISC_R_SUCCESS; + break; + } if (dns_rdataset_isassociated(rdataset)) { /* * If we've got a NSEC record, we need to save the @@ -5904,6 +6009,10 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) goto cleanup; case DNS_R_NCACHENXDOMAIN: + if (redirect(client, fname, rdataset, &node, &db, type)) { + result = ISC_R_SUCCESS; + break; + } case DNS_R_NCACHENXRRSET: ncache_nxrrset: INSIST(!is_zone); diff --git a/bin/named/server.c b/bin/named/server.c index 0c3c4e23e5..d5e2445964 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: server.c,v 1.603 2011/02/16 19:48:12 each Exp $ */ +/* $Id: server.c,v 1.604 2011/02/23 03:08:09 marka Exp $ */ /*! \file */ @@ -3341,6 +3341,37 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig, goto cleanup; } + /* + * Redirect zones only require minimal configuration. + */ + if (strcasecmp(ztypestr, "redirect") == 0) { + if (view->redirect != NULL) { + cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR, + "redirect zone already exists"); + result = ISC_R_EXISTS; + goto cleanup; + } + result = dns_viewlist_find(&ns_g_server->viewlist, view->name, + view->rdclass, &pview); + if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS) + goto cleanup; + if (pview != NULL && pview->redirect != NULL) { + dns_zone_attach(pview->redirect, &zone); + dns_zone_setview(zone, view); + } else { + CHECK(dns_zone_create(&zone, mctx)); + CHECK(dns_zone_setorigin(zone, origin)); + dns_zone_setview(zone, view); + CHECK(dns_zonemgr_managezone(ns_g_server->zonemgr, + zone)); + dns_zone_setstats(zone, ns_g_server->zonestats); + } + CHECK(ns_zone_configure(config, vconfig, zconfig, aclconf, + zone)); + dns_zone_attach(zone, &view->redirect); + goto cleanup; + } + /* * Check for duplicates in the new zone table. */ @@ -3366,9 +3397,8 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig, * options (e.g., an existing master zone cannot * be reused if the options specify a slave zone) */ - result = dns_viewlist_find(&ns_g_server->viewlist, - view->name, view->rdclass, - &pview); + result = dns_viewlist_find(&ns_g_server->viewlist, view->name, + view->rdclass, &pview); if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS) goto cleanup; if (pview != NULL) @@ -3924,6 +3954,9 @@ removed(dns_zone_t *zone, void *uap) { case dns_zone_stub: type = "stub"; break; + case dns_zone_redirect: + type = "redirect"; + break; default: type = "other"; break; @@ -5017,6 +5050,8 @@ load_zones(ns_server_t *server, isc_boolean_t stop) { CHECK(dns_view_load(view, stop)); if (view->managed_keys != NULL) CHECK(dns_zone_load(view->managed_keys)); + if (view->redirect != NULL) + CHECK(dns_zone_load(view->redirect)); } /* @@ -5050,6 +5085,8 @@ load_new_zones(ns_server_t *server, isc_boolean_t stop) { /* Load managed-keys data */ if (view->managed_keys != NULL) CHECK(dns_zone_loadnew(view->managed_keys)); + if (view->redirect != NULL) + CHECK(dns_zone_loadnew(view->redirect)); } /* diff --git a/bin/named/zoneconf.c b/bin/named/zoneconf.c index 7254eece04..f32e654505 100644 --- a/bin/named/zoneconf.c +++ b/bin/named/zoneconf.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: zoneconf.c,v 1.170 2011/01/06 23:47:00 tbox Exp $ */ +/* $Id: zoneconf.c,v 1.171 2011/02/23 03:08:09 marka Exp $ */ /*% */ @@ -973,7 +973,8 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig, * to primary masters (type "master") and slaves * acting as masters (type "slave"), but not to stubs. */ - if (ztype != dns_zone_stub && ztype != dns_zone_staticstub) { + if (ztype != dns_zone_stub && ztype != dns_zone_staticstub && + ztype != dns_zone_redirect) { obj = NULL; result = ns_config_get(maps, "notify", &obj); INSIST(result == ISC_R_SUCCESS); @@ -1046,7 +1047,7 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig, dns_zone_setidleout(zone, cfg_obj_asuint32(obj) * 60); obj = NULL; - result = ns_config_get(maps, "max-journal-size", &obj); + result = ns_config_get(maps, "max-journal-size", &obj); INSIST(result == ISC_R_SUCCESS); dns_zone_setjournalsize(zone, -1); if (cfg_obj_isstring(obj)) { @@ -1119,6 +1120,32 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig, INSIST(result == ISC_R_SUCCESS); dns_zone_setoption(zone, DNS_ZONEOPT_NSEC3TESTZONE, cfg_obj_asboolean(obj)); + } else if (ztype == dns_zone_redirect) { + dns_zone_setnotifytype(zone, dns_notifytype_no); + + obj = NULL; + result = ns_config_get(maps, "max-journal-size", &obj); + INSIST(result == ISC_R_SUCCESS); + dns_zone_setjournalsize(zone, -1); + if (cfg_obj_isstring(obj)) { + const char *str = cfg_obj_asstring(obj); + INSIST(strcasecmp(str, "unlimited") == 0); + journal_size = ISC_UINT32_MAX / 2; + } else { + isc_resourcevalue_t value; + value = cfg_obj_asuint64(obj); + if (value > ISC_UINT32_MAX / 2) { + cfg_obj_log(obj, ns_g_lctx, + ISC_LOG_ERROR, + "'max-journal-size " + "%" ISC_PRINT_QUADFORMAT "d' " + "is too large", + value); + RETERR(ISC_R_RANGE); + } + journal_size = (isc_uint32_t)value; + } + dns_zone_setjournalsize(zone, journal_size); } /* @@ -1320,6 +1347,7 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig, switch (ztype) { case dns_zone_slave: case dns_zone_stub: + case dns_zone_redirect: count = 0; obj = NULL; result = cfg_map_get(zoptions, "masters", &obj); diff --git a/bin/tests/system/conf.sh.in b/bin/tests/system/conf.sh.in index 0102932c53..04718f468d 100644 --- a/bin/tests/system/conf.sh.in +++ b/bin/tests/system/conf.sh.in @@ -15,7 +15,7 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: conf.sh.in,v 1.60 2011/02/22 04:14:29 marka Exp $ +# $Id: conf.sh.in,v 1.61 2011/02/23 03:08:09 marka Exp $ # # Common configuration data for system tests, to be sourced into @@ -55,7 +55,7 @@ JOURNALPRINT=$TOP/bin/tools/named-journalprint SUBDIRS="acl allow_query addzone autosign cacheclean checkconf checknames database dlv @DLZ_SYSTEM_TEST@ dlzexternal dns64 dnssec forward glue gost ixfr limits lwresd masterfile masterformat metadata - notify nsupdate pending pkcs11 resolver rpz rrsetorder + notify nsupdate pending pkcs11 redirect resolver rpz rrsetorder sortlist smartsign staticstub stub tkey tsig tsiggss unknown upforwd views xfer xferquota zonechecks" diff --git a/bin/tests/system/redirect/clean.sh b/bin/tests/system/redirect/clean.sh new file mode 100644 index 0000000000..8d2ae47876 --- /dev/null +++ b/bin/tests/system/redirect/clean.sh @@ -0,0 +1,27 @@ +#!/bin/sh +# +# Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC") +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. + +# $Id: clean.sh,v 1.2 2011/02/23 03:08:09 marka Exp $ + + +rm -f ns1/K* +rm -f ns1/signed.db* +rm -f ns1/nsec3.db* +rm -f ns1/dsset-signed. +rm -f ns1/dsset-nsec3. +rm -f */named.memstats +rm -f */named.run +rm -f dig.out.* random.data diff --git a/bin/tests/system/redirect/conf/bad1.conf b/bin/tests/system/redirect/conf/bad1.conf new file mode 100644 index 0000000000..c92fce80e8 --- /dev/null +++ b/bin/tests/system/redirect/conf/bad1.conf @@ -0,0 +1,11 @@ +zone "." { + type hint; + file "hint.db"; +}; + +zone "." { + type redirect; + file "redirect.db"; + allow-query { 10.0.1.0; }; + forwarders { 1.2.3.4; }; +}; diff --git a/bin/tests/system/redirect/conf/bad2.conf b/bin/tests/system/redirect/conf/bad2.conf new file mode 100644 index 0000000000..9973ef83f5 --- /dev/null +++ b/bin/tests/system/redirect/conf/bad2.conf @@ -0,0 +1,11 @@ +zone "." { + type hint; + file "hint.db"; +}; + +zone "." { + type redirect; + file "redirect.db"; + allow-query { 10.0.1.0; }; + also-notify { 1.2.3.4; }; +}; diff --git a/bin/tests/system/redirect/conf/bad3.conf b/bin/tests/system/redirect/conf/bad3.conf new file mode 100644 index 0000000000..b5b56d191b --- /dev/null +++ b/bin/tests/system/redirect/conf/bad3.conf @@ -0,0 +1,10 @@ +zone "." { + type hint; + file "hint.db"; +}; + +zone "x" { + type redirect; + file "redirect.db"; + allow-query { 10.0.1.0; }; +}; diff --git a/bin/tests/system/redirect/conf/good1.conf b/bin/tests/system/redirect/conf/good1.conf new file mode 100644 index 0000000000..834c2861f8 --- /dev/null +++ b/bin/tests/system/redirect/conf/good1.conf @@ -0,0 +1,9 @@ +zone "." { + type hint; + file "hint.db"; +}; + +zone "." { + type redirect; + file "redirect.db"; +}; diff --git a/bin/tests/system/redirect/conf/good2.conf b/bin/tests/system/redirect/conf/good2.conf new file mode 100644 index 0000000000..d953365530 --- /dev/null +++ b/bin/tests/system/redirect/conf/good2.conf @@ -0,0 +1,9 @@ +zone "." { + type master; + file "master.db"; +}; + +zone "." { + type redirect; + file "redirect.db"; +}; diff --git a/bin/tests/system/redirect/conf/good3.conf b/bin/tests/system/redirect/conf/good3.conf new file mode 100644 index 0000000000..897a03467d --- /dev/null +++ b/bin/tests/system/redirect/conf/good3.conf @@ -0,0 +1,10 @@ +zone "." { + type slave; + file "slave.db"; + masters { 1.2.3.4; }; +}; + +zone "." { + type redirect; + file "redirect.db"; +}; diff --git a/bin/tests/system/redirect/conf/good4.conf b/bin/tests/system/redirect/conf/good4.conf new file mode 100644 index 0000000000..f1095b3d38 --- /dev/null +++ b/bin/tests/system/redirect/conf/good4.conf @@ -0,0 +1,10 @@ +zone "." { + type hint; + file "hint.db"; +}; + +zone "." { + type redirect; + file "redirect.db"; + allow-query { 10.0.1.0; }; +}; diff --git a/bin/tests/system/redirect/ns1/example.db b/bin/tests/system/redirect/ns1/example.db new file mode 100644 index 0000000000..cb49045d8f --- /dev/null +++ b/bin/tests/system/redirect/ns1/example.db @@ -0,0 +1,55 @@ +; Copyright (C) 2010, 2011 Internet Systems Consortium, Inc. ("ISC") +; +; Permission to use, copy, modify, and/or distribute this software for any +; purpose with or without fee is hereby granted, provided that the above +; copyright notice and this permission notice appear in all copies. +; +; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +; PERFORMANCE OF THIS SOFTWARE. + +; $Id: example.db,v 1.2 2011/02/23 03:08:10 marka Exp $ + +$TTL 3600 +@ SOA ns1 marka.isc.org. 0 0 0 0 1200 +@ NS ns1 +ns1 A 10.53.0.1 +excluded-good-a AAAA 2001:eeee::1 + A 1.2.3.4 +excluded-bad-a AAAA 2001:eeee::2 + A 10.0.0.1 +excluded-only AAAA 2001:eeee::3 +partially-excluded-good-a AAAA 2001:eeee::1 + AAAA 2001::1 + A 1.2.3.4 +partially-excluded-bad-a AAAA 2001:eeee::2 + AAAA 2001::2 + A 10.0.0.1 +partially-excluded-only AAAA 2001:eeee::3 + AAAA 2001::3 +a-only A 1.2.3.5 +a-and-aaaa AAAA 2001::1 + A 1.2.3.6 +aaaa-only AAAA 2001::2 +a-not-mapped A 10.0.0.2 +mx-only MX 10 ns.example. +cname-excluded-good-a CNAME excluded-good-a +cname-excluded-bad-a CNAME excluded-bad-a +cname-excluded-only CNAME excluded-only +cname-partial-excluded-good-a CNAME partial-excluded-good-a +cname-partial-excluded-bad-a CNAME partial-excluded-bad-a +cname-partial-excluded-only CNAME partial-excluded-only +cname-a-only CNAME a-only +cname-a-and-aaaa CNAME a-and-aaaa +cname-aaaa-only CNAME aaaa-only +cname-a-not-mapped CNAME a-not-mapped +cname-mx-only CNAME mx-only +cname-non-existent CNAME non-existent +ttl-less-than-600 500 A 5.6.7.8 +ttl-more-than-600 700 A 5.6.7.8 +ttl-less-than-minimum 1100 A 5.6.7.8 +ttl-more-than-minimum 1300 A 5.6.7.8 diff --git a/bin/tests/system/redirect/ns1/named.conf b/bin/tests/system/redirect/ns1/named.conf new file mode 100644 index 0000000000..40dd6d33c5 --- /dev/null +++ b/bin/tests/system/redirect/ns1/named.conf @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* $Id: named.conf,v 1.2 2011/02/23 03:08:10 marka Exp $ */ + +// NS1 + +controls { /* empty */ }; + +acl rfc1918 { 10/8; 192.168/16; 172.16/12; }; + +options { + query-source address 10.53.0.1; + notify-source 10.53.0.1; + transfer-source 10.53.0.1; + port 5300; + pid-file "named.pid"; + listen-on { 10.53.0.1; }; + listen-on-v6 { none; }; + allow-recursion { 10.53.0.1; }; + notify yes; + dnssec-enable yes; + dnssec-validation yes; +}; + +zone "." { + type master; + file "root.db"; +}; + +zone "example" { + type master; + file "example.db"; +}; + +zone "signed" { + type master; + file "signed.db.signed"; +}; + +zone "nsec3" { + type master; + file "nsec3.db.signed"; +}; + +zone "." { + type redirect; + file "redirect.db"; + allow-query { !10.53.0.2; !10.53.0.4; any; }; +}; + +// include "trusted.conf"; diff --git a/bin/tests/system/redirect/ns1/redirect.db b/bin/tests/system/redirect/ns1/redirect.db new file mode 100644 index 0000000000..5b04315b8e --- /dev/null +++ b/bin/tests/system/redirect/ns1/redirect.db @@ -0,0 +1,12 @@ +; Copyright +; + +$TTL 300 +@ IN SOA ns.example.net hostmaster.example.net 0 0 0 0 0 +@ IN NS ns.example.net +; +; NS records do not need address records in this zone as it is not in the +; normal namespace. +; +*. IN A 100.100.100.2 +*. IN AAAA 2001:ffff:ffff::100.100.100.2 diff --git a/bin/tests/system/redirect/ns1/root.db b/bin/tests/system/redirect/ns1/root.db new file mode 100644 index 0000000000..600763d6a4 --- /dev/null +++ b/bin/tests/system/redirect/ns1/root.db @@ -0,0 +1,24 @@ +; Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC") +; +; Permission to use, copy, modify, and/or distribute this software for any +; purpose with or without fee is hereby granted, provided that the above +; copyright notice and this permission notice appear in all copies. +; +; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +; PERFORMANCE OF THIS SOFTWARE. + +; $Id: root.db,v 1.2 2011/02/23 03:08:10 marka Exp $ + +$TTL 3600 +@ SOA a.root-servers.nil. marka.isc.org. 0 0 0 0 0 +@ NS a.root-servers.nil. +a.root-servers.nil. A 10.53.0.1 +example NS ns1.example. +ns1.example. A 10.53.0.1 +signed NS ns1.example. +ns1.signed. A 10.53.0.1 diff --git a/bin/tests/system/redirect/ns1/sign.sh b/bin/tests/system/redirect/ns1/sign.sh new file mode 100644 index 0000000000..4c19b07f9e --- /dev/null +++ b/bin/tests/system/redirect/ns1/sign.sh @@ -0,0 +1,44 @@ +#!/bin/sh -e +# +# Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC") +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. + +# $Id: sign.sh,v 1.2 2011/02/23 03:08:10 marka Exp $ + +SYSTEMTESTTOP=../.. +. $SYSTEMTESTTOP/conf.sh + +RANDFILE=../random.data + +zone=signed +infile=example.db +zonefile=signed.db + +key1=`$KEYGEN -q -r $RANDFILE $zone` +key2=`$KEYGEN -q -r $RANDFILE -fk $zone` + +cat $infile $key1.key $key2.key > $zonefile + +$SIGNER -P -g -r $RANDFILE -o $zone $zonefile > /dev/null + +zone=nsec3 +infile=example.db +zonefile=nsec3.db + +key1=`$KEYGEN -q -r $RANDFILE -3 $zone` +key2=`$KEYGEN -q -r $RANDFILE -3 -fk $zone` + +cat $infile $key1.key $key2.key > $zonefile + +$SIGNER -P -3 - -g -r $RANDFILE -o $zone $zonefile > /dev/null diff --git a/bin/tests/system/redirect/ns2/named.conf b/bin/tests/system/redirect/ns2/named.conf new file mode 100644 index 0000000000..a2c9a4c21e --- /dev/null +++ b/bin/tests/system/redirect/ns2/named.conf @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2010, 2011 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* $Id: named.conf,v 1.2 2011/02/23 03:08:10 marka Exp $ */ + +// NS2 + +controls { /* empty */ }; + +acl rfc1918 { 10/8; 192.168/16; 172.16/12; }; + +options { + query-source address 10.53.0.2; + notify-source 10.53.0.2; + transfer-source 10.53.0.2; + port 5300; + pid-file "named.pid"; + listen-on { 10.53.0.2; }; + listen-on-v6 { none; }; + recursion yes; + notify yes; + dnssec-enable yes; + dnssec-validation yes; + +}; + +zone "." { + type hint; + file "../../common/root.hint"; +}; + +zone "." { + type redirect; + file "redirect.db"; + allow-query { !10.53.0.4; any; }; +}; diff --git a/bin/tests/system/redirect/ns2/redirect.db b/bin/tests/system/redirect/ns2/redirect.db new file mode 100644 index 0000000000..12997dc9c0 --- /dev/null +++ b/bin/tests/system/redirect/ns2/redirect.db @@ -0,0 +1,12 @@ +; Copyright +; + +$TTL 300 +@ IN SOA ns.example.net hostmaster.example.net 0 0 0 0 0 +@ IN NS ns.example.net +; +; NS records do not need address records in this zone as it is not in the +; normal namespace. +; +*. IN A 100.100.100.1 +*. IN AAAA 2001:ffff:ffff::100.100.100.1 diff --git a/bin/tests/system/redirect/setup.sh b/bin/tests/system/redirect/setup.sh new file mode 100644 index 0000000000..7ec058c3c1 --- /dev/null +++ b/bin/tests/system/redirect/setup.sh @@ -0,0 +1,23 @@ +#!/bin/sh -e +# +# Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC") +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. + +# $Id: setup.sh,v 1.2 2011/02/23 03:08:09 marka Exp $ + +sh clean.sh + +../../../tools/genrandom 400 random.data + +cd ns1 && sh sign.sh diff --git a/bin/tests/system/redirect/tests.sh b/bin/tests/system/redirect/tests.sh new file mode 100644 index 0000000000..d426e370b0 --- /dev/null +++ b/bin/tests/system/redirect/tests.sh @@ -0,0 +1,336 @@ +#!/bin/sh +# +# Copyright (C) 2010, 2011 Internet Systems Consortium, Inc. ("ISC") +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. + +# $Id: tests.sh,v 1.2 2011/02/23 03:08:09 marka Exp $ + +SYSTEMTESTTOP=.. +. $SYSTEMTESTTOP/conf.sh + +status=0 +n=1 + +rm -f dig.out.* + +DIGOPTS="+tcp +noadd +nosea +nostat +nocmd -p 5300" + +for conf in conf/good*.conf +do + echo "I:checking that $conf is accepted ($n)" + ret=0 + $CHECKCONF "$conf" || ret=1 + n=`expr $n + 1` + if [ $ret != 0 ]; then echo "I:failed"; fi + status=`expr $status + $ret` +done + +for conf in conf/bad*.conf +do + echo "I:checking that $conf is rejected ($n)" + ret=0 + $CHECKCONF "$conf" >/dev/null && ret=1 + n=`expr $n + 1` + if [ $ret != 0 ]; then echo "I:failed"; fi + status=`expr $status + $ret` +done + +echo "I:checking A redirect works for nonexist ($n)" +ret=0 +$DIG $DIGOPTS nonexist. @10.53.0.2 -b 10.53.0.2 a > dig.out.ns2.test$n || ret=1 +grep "status: NOERROR" dig.out.ns2.test$n > /dev/null || ret=1 +grep "100.100.100.1" dig.out.ns2.test$n > /dev/null || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:checking AAAA redirect works for nonexist ($n)" +ret=0 +$DIG $DIGOPTS nonexist. @10.53.0.2 -b 10.53.0.2 aaaa > dig.out.ns2.test$n || ret=1 +grep "status: NOERROR" dig.out.ns2.test$n > /dev/null || ret=1 +grep "2001:ffff:ffff::6464:6401" dig.out.ns2.test$n > /dev/null || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:checking ANY redirect works for nonexist ($n)" +ret=0 +$DIG $DIGOPTS nonexist. @10.53.0.2 -b 10.53.0.2 any > dig.out.ns2.test$n || ret=1 +grep "status: NOERROR" dig.out.ns2.test$n > /dev/null || ret=1 +grep "100.100.100.1" dig.out.ns2.test$n > /dev/null || ret=1 +grep "2001:ffff:ffff::6464:6401" dig.out.ns2.test$n > /dev/null || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:checking A redirect doesn't work for acl miss ($n)" +ret=0 +$DIG $DIGOPTS nonexist. @10.53.0.2 -b 10.53.0.4 a > dig.out.ns2.test$n || ret=1 +grep "status: NXDOMAIN" dig.out.ns2.test$n > /dev/null || ret=1 +grep "100.100.100.1" dig.out.ns2.test$n > /dev/null && ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:checking AAAA redirect doesn't work for acl miss ($n)" +ret=0 +$DIG $DIGOPTS nonexist. @10.53.0.2 -b 10.53.0.4 aaaa > dig.out.ns2.test$n || ret=1 +grep "status: NXDOMAIN" dig.out.ns2.test$n > /dev/null || ret=1 +grep "2001:ffff:ffff::6464:6401" dig.out.ns2.test$n > /dev/null && ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:checking ANY redirect doesn't work for acl miss ($n)" +ret=0 +$DIG $DIGOPTS nonexist. @10.53.0.2 -b 10.53.0.4 any > dig.out.ns2.test$n || ret=1 +grep "status: NXDOMAIN" dig.out.ns2.test$n > /dev/null || ret=1 +grep "100.100.100.1" dig.out.ns2.test$n > /dev/null && ret=1 +grep "2001:ffff:ffff::6464:6401" dig.out.ns2.test$n > /dev/null && ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:checking A redirect works for signed nonexist, DO=0 ($n)" +ret=0 +$DIG $DIGOPTS nonexist.signed. @10.53.0.2 -b 10.53.0.2 a > dig.out.ns2.test$n || ret=1 +grep "status: NOERROR" dig.out.ns2.test$n > /dev/null || ret=1 +grep "100.100.100.1" dig.out.ns2.test$n > /dev/null || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:checking AAAA redirect works for signed nonexist, DO=0 ($n)" +ret=0 +$DIG $DIGOPTS nonexist.signed. @10.53.0.2 -b 10.53.0.2 aaaa > dig.out.ns2.test$n || ret=1 +grep "status: NOERROR" dig.out.ns2.test$n > /dev/null || ret=1 +grep "2001:ffff:ffff::6464:6401" dig.out.ns2.test$n > /dev/null || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:checking ANY redirect works for signed nonexist, DO=0 ($n)" +ret=0 +$DIG $DIGOPTS nonexist.signed. @10.53.0.2 -b 10.53.0.2 any > dig.out.ns2.test$n || ret=1 +grep "status: NOERROR" dig.out.ns2.test$n > /dev/null || ret=1 +grep "100.100.100.1" dig.out.ns2.test$n > /dev/null || ret=1 +grep "2001:ffff:ffff::6464:6401" dig.out.ns2.test$n > /dev/null || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:checking A redirect fails for signed nonexist, DO=1 ($n)" +ret=0 +$DIG $DIGOPTS nonexist.signed. +dnssec @10.53.0.2 -b 10.53.0.2 a > dig.out.ns2.test$n || ret=1 +grep "status: NXDOMAIN" dig.out.ns2.test$n > /dev/null || ret=1 +grep "100.100.100.1" dig.out.ns2.test$n > /dev/null && ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:checking AAAA redirect fails for signed nonexist, DO=1 ($n)" +ret=0 +$DIG $DIGOPTS nonexist.signed. +dnssec @10.53.0.2 -b 10.53.0.2 aaaa > dig.out.ns2.test$n || ret=1 +grep "status: NXDOMAIN" dig.out.ns2.test$n > /dev/null || ret=1 +grep "2001:ffff:ffff::6464:6401" dig.out.ns2.test$n > /dev/null && ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:checking ANY redirect fails for signed nonexist, DO=1 ($n)" +ret=0 +$DIG $DIGOPTS nonexist.signed. +dnssec @10.53.0.2 -b 10.53.0.2 any > dig.out.ns2.test$n || ret=1 +grep "status: NXDOMAIN" dig.out.ns2.test$n > /dev/null || ret=1 +grep "100.100.100.1" dig.out.ns2.test$n > /dev/null && ret=1 +grep "2001:ffff:ffff::6464:6401" dig.out.ns2.test$n > /dev/null && ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:checking A redirect fails for nsec3 signed nonexist, DO=1 ($n)" +ret=0 +$DIG $DIGOPTS nonexist.nsec3. +dnssec @10.53.0.2 -b 10.53.0.2 a > dig.out.ns2.test$n || ret=1 +grep "status: NXDOMAIN" dig.out.ns2.test$n > /dev/null || ret=1 +grep "100.100.100.1" dig.out.ns2.test$n > /dev/null && ret=1 +grep "IN.NSEC3" dig.out.ns2.test$n > /dev/null || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:checking AAAA redirect fails for nsec3 signed nonexist, DO=1 ($n)" +ret=0 +$DIG $DIGOPTS nonexist.nsec3. +dnssec @10.53.0.2 -b 10.53.0.2 aaaa > dig.out.ns2.test$n || ret=1 +grep "status: NXDOMAIN" dig.out.ns2.test$n > /dev/null || ret=1 +grep "2001:ffff:ffff::6464:6401" dig.out.ns2.test$n > /dev/null && ret=1 +grep "IN.NSEC3" dig.out.ns2.test$n > /dev/null || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:checking ANY redirect fails for nsec3 signed nonexist, DO=1 ($n)" +ret=0 +$DIG $DIGOPTS nonexist.nsec3. +dnssec @10.53.0.2 -b 10.53.0.2 any > dig.out.ns2.test$n || ret=1 +grep "status: NXDOMAIN" dig.out.ns2.test$n > /dev/null || ret=1 +grep "100.100.100.1" dig.out.ns2.test$n > /dev/null && ret=1 +grep "2001:ffff:ffff::6464:6401" dig.out.ns2.test$n > /dev/null && ret=1 +grep "IN.NSEC3" dig.out.ns2.test$n > /dev/null || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:checking A redirect works for nonexist authoritative ($n)" +ret=0 +$DIG $DIGOPTS nonexist. @10.53.0.1 -b 10.53.0.1 a > dig.out.ns1.test$n || ret=1 +grep "status: NOERROR" dig.out.ns1.test$n > /dev/null || ret=1 +grep "100.100.100.2" dig.out.ns1.test$n > /dev/null || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:checking AAAA redirect works for nonexist authoritative ($n)" +ret=0 +$DIG $DIGOPTS nonexist. @10.53.0.1 -b 10.53.0.1 aaaa > dig.out.ns1.test$n || ret=1 +grep "status: NOERROR" dig.out.ns1.test$n > /dev/null || ret=1 +grep "2001:ffff:ffff::6464:6402" dig.out.ns1.test$n > /dev/null || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:checking ANY redirect works for nonexist authoritative ($n)" +ret=0 +$DIG $DIGOPTS nonexist. @10.53.0.1 -b 10.53.0.1 any > dig.out.ns1.test$n || ret=1 +grep "status: NOERROR" dig.out.ns1.test$n > /dev/null || ret=1 +grep "100.100.100.2" dig.out.ns1.test$n > /dev/null || ret=1 +grep "2001:ffff:ffff::6464:6402" dig.out.ns1.test$n > /dev/null || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:checking A redirect doesn't work for acl miss authoritative ($n)" +ret=0 +$DIG $DIGOPTS nonexist. @10.53.0.1 -b 10.53.0.4 a > dig.out.ns1.test$n || ret=1 +grep "status: NXDOMAIN" dig.out.ns1.test$n > /dev/null || ret=1 +grep "100.100.100.2" dig.out.ns1.test$n > /dev/null && ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:checking AAAA redirect doesn't work for acl miss authoritative ($n)" +ret=0 +$DIG $DIGOPTS nonexist. @10.53.0.1 -b 10.53.0.4 aaaa > dig.out.ns1.test$n || ret=1 +grep "status: NXDOMAIN" dig.out.ns1.test$n > /dev/null || ret=1 +grep "2001:ffff:ffff::6464:6402" dig.out.ns1.test$n > /dev/null && ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:checking ANY redirect doesn't work for acl miss authoritative ($n)" +ret=0 +$DIG $DIGOPTS nonexist. @10.53.0.1 -b 10.53.0.4 any > dig.out.ns1.test$n || ret=1 +grep "status: NXDOMAIN" dig.out.ns1.test$n > /dev/null || ret=1 +grep "100.100.100.2" dig.out.ns1.test$n > /dev/null && ret=1 +grep "2001:ffff:ffff::6464:6402" dig.out.ns1.test$n > /dev/null && ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:checking A redirect works for signed nonexist, DO=0 authoritative ($n)" +ret=0 +$DIG $DIGOPTS nonexist.signed. @10.53.0.1 -b 10.53.0.1 a > dig.out.ns1.test$n || ret=1 +grep "status: NOERROR" dig.out.ns1.test$n > /dev/null || ret=1 +grep "100.100.100.2" dig.out.ns1.test$n > /dev/null || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:checking AAAA redirect works for signed nonexist, DO=0 authoritative ($n)" +ret=0 +$DIG $DIGOPTS nonexist.signed. @10.53.0.1 -b 10.53.0.1 aaaa > dig.out.ns1.test$n || ret=1 +grep "status: NOERROR" dig.out.ns1.test$n > /dev/null || ret=1 +grep "2001:ffff:ffff::6464:6402" dig.out.ns1.test$n > /dev/null || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:checking ANY redirect works for signed nonexist, DO=0 authoritative ($n)" +ret=0 +$DIG $DIGOPTS nonexist.signed. @10.53.0.1 -b 10.53.0.1 any > dig.out.ns1.test$n || ret=1 +grep "status: NOERROR" dig.out.ns1.test$n > /dev/null || ret=1 +grep "100.100.100.2" dig.out.ns1.test$n > /dev/null || ret=1 +grep "2001:ffff:ffff::6464:6402" dig.out.ns1.test$n > /dev/null || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:checking A redirect fails for signed nonexist, DO=1 authoritative ($n)" +ret=0 +$DIG $DIGOPTS nonexist.signed. +dnssec @10.53.0.1 -b 10.53.0.1 a > dig.out.ns1.test$n || ret=1 +grep "status: NXDOMAIN" dig.out.ns1.test$n > /dev/null || ret=1 +grep "100.100.100.2" dig.out.ns1.test$n > /dev/null && ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:checking AAAA redirect fails for signed nonexist, DO=1 authoritative ($n)" +ret=0 +$DIG $DIGOPTS nonexist.signed. +dnssec @10.53.0.1 -b 10.53.0.1 aaaa > dig.out.ns1.test$n || ret=1 +grep "status: NXDOMAIN" dig.out.ns1.test$n > /dev/null || ret=1 +grep "2001:ffff:ffff::6464:6402" dig.out.ns1.test$n > /dev/null && ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:checking ANY redirect fails for signed nonexist, DO=1 authoritative ($n)" +ret=0 +$DIG $DIGOPTS nonexist.signed. +dnssec @10.53.0.1 -b 10.53.0.1 any > dig.out.ns1.test$n || ret=1 +grep "status: NXDOMAIN" dig.out.ns1.test$n > /dev/null || ret=1 +grep "100.100.100.2" dig.out.ns1.test$n > /dev/null && ret=1 +grep "2001:ffff:ffff::6464:6402" dig.out.ns1.test$n > /dev/null && ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:checking A redirect fails for nsec3 signed nonexist, DO=1 authoritative ($n)" +ret=0 +$DIG $DIGOPTS nonexist.nsec3. +dnssec @10.53.0.1 -b 10.53.0.1 a > dig.out.ns1.test$n || ret=1 +grep "status: NXDOMAIN" dig.out.ns1.test$n > /dev/null || ret=1 +grep "100.100.100.2" dig.out.ns1.test$n > /dev/null && ret=1 +grep "IN.NSEC3" dig.out.ns1.test$n > /dev/null || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:checking AAAA redirect fails for nsec3 signed nonexist, DO=1 authoritative ($n)" +ret=0 +$DIG $DIGOPTS nonexist.nsec3. +dnssec @10.53.0.1 -b 10.53.0.1 aaaa > dig.out.ns1.test$n || ret=1 +grep "status: NXDOMAIN" dig.out.ns1.test$n > /dev/null || ret=1 +grep "2001:ffff:ffff::6464:6402" dig.out.ns1.test$n > /dev/null && ret=1 +grep "IN.NSEC3" dig.out.ns1.test$n > /dev/null || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:checking ANY redirect fails for nsec3 signed nonexist, DO=1 authoritative ($n)" +ret=0 +$DIG $DIGOPTS nonexist.nsec3. +dnssec @10.53.0.1 -b 10.53.0.1 any > dig.out.ns1.test$n || ret=1 +grep "status: NXDOMAIN" dig.out.ns1.test$n > /dev/null || ret=1 +grep "100.100.100.2" dig.out.ns1.test$n > /dev/null && ret=1 +grep "2001:ffff:ffff::6464:6402" dig.out.ns1.test$n > /dev/null && ret=1 +grep "IN.NSEC3" dig.out.ns1.test$n > /dev/null || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:exit status: $status" +exit $status diff --git a/doc/arm/Bv9ARM-book.xml b/doc/arm/Bv9ARM-book.xml index 98babd1dc1..5792a45e94 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 @@ -10097,6 +10097,13 @@ zone zone_name class delegation-only yes_or_no ; }; +zone "." class { + type redirect; + file string ; + masterfile-format (text|raw) ; + allow-query { address_match_list }; +}; + zone zone_name class { type delegation-only; }; @@ -10337,6 +10344,26 @@ zone zone_name class + + + + redirect + + + + + Provides a source of answers when the normal resolution + returns NXDOMAIN. Only one redirect zone is supported + per view. allow-query can be used + to restrict which clients see these answers. + + + If the client has requested DNSSEC records (DO=1) and + the NXDOMAIN response is signed then no substitution + will occur. + + + diff --git a/lib/bind9/check.c b/lib/bind9/check.c index 7e7de7ef10..05b8ba2dd0 100644 --- a/lib/bind9/check.c +++ b/lib/bind9/check.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: check.c,v 1.125 2011/01/07 23:47:07 tbox Exp $ */ +/* $Id: check.c,v 1.126 2011/02/23 03:08:10 marka Exp $ */ /*! \file */ @@ -1223,7 +1223,9 @@ check_update_policy(const cfg_obj_t *policy, isc_log_t *logctx) { #define FORWARDZONE 16 #define DELEGATIONZONE 32 #define STATICSTUBZONE 64 -#define CHECKACL 128 +#define REDIRECTZONE 128 +#define STREDIRECTZONE 0 /* Set to REDIRECTZONE to allow xfr-in. */ +#define CHECKACL 256 typedef struct { const char *name; @@ -1252,30 +1254,30 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions, const cfg_listelt_t *element; static optionstable options[] = { - { "allow-query", MASTERZONE | SLAVEZONE | STUBZONE | CHECKACL | - STATICSTUBZONE }, + { "allow-query", MASTERZONE | SLAVEZONE | STUBZONE | REDIRECTZONE | + CHECKACL | STATICSTUBZONE }, { "allow-notify", SLAVEZONE | CHECKACL }, { "allow-transfer", MASTERZONE | SLAVEZONE | CHECKACL }, { "notify", MASTERZONE | SLAVEZONE }, { "also-notify", MASTERZONE | SLAVEZONE }, - { "dialup", MASTERZONE | SLAVEZONE | STUBZONE }, + { "dialup", MASTERZONE | SLAVEZONE | STUBZONE | STREDIRECTZONE }, { "delegation-only", HINTZONE | STUBZONE | DELEGATIONZONE }, { "forward", MASTERZONE | SLAVEZONE | STUBZONE | FORWARDZONE }, { "forwarders", MASTERZONE | SLAVEZONE | STUBZONE | FORWARDZONE }, - { "maintain-ixfr-base", MASTERZONE | SLAVEZONE }, - { "max-ixfr-log-size", MASTERZONE | SLAVEZONE }, + { "maintain-ixfr-base", MASTERZONE | SLAVEZONE | STREDIRECTZONE }, + { "max-ixfr-log-size", MASTERZONE | SLAVEZONE | STREDIRECTZONE }, { "notify-source", MASTERZONE | SLAVEZONE }, { "notify-source-v6", MASTERZONE | SLAVEZONE }, - { "transfer-source", SLAVEZONE | STUBZONE }, - { "transfer-source-v6", SLAVEZONE | STUBZONE }, - { "max-transfer-time-in", SLAVEZONE | STUBZONE }, + { "transfer-source", SLAVEZONE | STUBZONE | STREDIRECTZONE }, + { "transfer-source-v6", SLAVEZONE | STUBZONE | STREDIRECTZONE }, + { "max-transfer-time-in", SLAVEZONE | STUBZONE | STREDIRECTZONE }, { "max-transfer-time-out", MASTERZONE | SLAVEZONE }, - { "max-transfer-idle-in", SLAVEZONE | STUBZONE }, + { "max-transfer-idle-in", SLAVEZONE | STUBZONE | STREDIRECTZONE }, { "max-transfer-idle-out", MASTERZONE | SLAVEZONE }, - { "max-retry-time", SLAVEZONE | STUBZONE }, - { "min-retry-time", SLAVEZONE | STUBZONE }, - { "max-refresh-time", SLAVEZONE | STUBZONE }, - { "min-refresh-time", SLAVEZONE | STUBZONE }, + { "max-retry-time", SLAVEZONE | STUBZONE | STREDIRECTZONE }, + { "min-retry-time", SLAVEZONE | STUBZONE | STREDIRECTZONE }, + { "max-refresh-time", SLAVEZONE | STUBZONE | STREDIRECTZONE }, + { "min-refresh-time", SLAVEZONE | STUBZONE | STREDIRECTZONE }, { "dnssec-secure-to-insecure", MASTERZONE }, { "sig-validity-interval", MASTERZONE }, { "sig-re-signing-interval", MASTERZONE }, @@ -1283,17 +1285,17 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions, { "sig-signing-type", MASTERZONE }, { "sig-signing-signatures", MASTERZONE }, { "zone-statistics", MASTERZONE | SLAVEZONE | STUBZONE | - STATICSTUBZONE}, + STATICSTUBZONE| REDIRECTZONE }, { "allow-update", MASTERZONE | CHECKACL }, { "allow-update-forwarding", SLAVEZONE | CHECKACL }, - { "file", MASTERZONE | SLAVEZONE | STUBZONE | HINTZONE }, - { "journal", MASTERZONE | SLAVEZONE }, + { "file", MASTERZONE | SLAVEZONE | STUBZONE | HINTZONE | REDIRECTZONE }, + { "journal", MASTERZONE | SLAVEZONE | STREDIRECTZONE }, { "ixfr-base", MASTERZONE | SLAVEZONE }, { "ixfr-tmp-file", MASTERZONE | SLAVEZONE }, - { "masters", SLAVEZONE | STUBZONE }, + { "masters", SLAVEZONE | STUBZONE | REDIRECTZONE }, { "pubkey", MASTERZONE | SLAVEZONE | STUBZONE }, { "update-policy", MASTERZONE }, - { "database", MASTERZONE | SLAVEZONE | STUBZONE }, + { "database", MASTERZONE | SLAVEZONE | STUBZONE | REDIRECTZONE }, { "key-directory", MASTERZONE }, { "check-wildcard", MASTERZONE }, { "check-mx", MASTERZONE }, @@ -1301,20 +1303,21 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions, { "integrity-check", MASTERZONE }, { "check-mx-cname", MASTERZONE }, { "check-srv-cname", MASTERZONE }, - { "masterfile-format", MASTERZONE | SLAVEZONE | STUBZONE | HINTZONE }, + { "masterfile-format", MASTERZONE | SLAVEZONE | STUBZONE | HINTZONE | + REDIRECTZONE }, { "update-check-ksk", MASTERZONE }, { "dnssec-dnskey-kskonly", MASTERZONE }, { "auto-dnssec", MASTERZONE }, - { "try-tcp-refresh", SLAVEZONE }, + { "try-tcp-refresh", SLAVEZONE | STREDIRECTZONE }, { "server-addresses", STATICSTUBZONE }, { "server-names", STATICSTUBZONE }, }; static optionstable dialups[] = { - { "notify", MASTERZONE | SLAVEZONE }, - { "notify-passive", SLAVEZONE }, - { "refresh", SLAVEZONE | STUBZONE }, - { "passive", SLAVEZONE | STUBZONE }, + { "notify", MASTERZONE | SLAVEZONE | STREDIRECTZONE }, + { "notify-passive", SLAVEZONE | STREDIRECTZONE }, + { "refresh", SLAVEZONE | STUBZONE | STREDIRECTZONE }, + { "passive", SLAVEZONE | STUBZONE | STREDIRECTZONE }, }; znamestr = cfg_obj_asstring(cfg_tuple_get(zconfig, "name")); @@ -1344,6 +1347,8 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions, ztype = HINTZONE; else if (strcasecmp(typestr, "delegation-only") == 0) ztype = DELEGATIONZONE; + else if (strcasecmp(typestr, "redirect") == 0) + ztype = REDIRECTZONE; else { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "zone '%s': invalid type %s", @@ -1351,6 +1356,11 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions, return (ISC_R_FAILURE); } + if (ztype == REDIRECTZONE && strcmp(znamestr, ".") != 0) { + cfg_obj_log(zconfig, logctx, ISC_LOG_ERROR, + "redirect zones must be called \".\""); + return (ISC_R_FAILURE); + } obj = cfg_tuple_get(zconfig, "class"); if (cfg_obj_isstring(obj)) { isc_textregion_t r; @@ -1392,7 +1402,8 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions, zname = dns_fixedname_name(&fixedname); dns_name_format(zname, namebuf, sizeof(namebuf)); - tresult = nameexist(zconfig, namebuf, ztype == HINTZONE ? 1 : 2, + tresult = nameexist(zconfig, namebuf, ztype == HINTZONE ? 1 : + ztype == REDIRECTZONE ? 2 : 3, symtab, "zone '%s': already exists " "previous definition: %s:%u", logctx, mctx); if (tresult != ISC_R_SUCCESS) diff --git a/lib/dns/include/dns/view.h b/lib/dns/include/dns/view.h index 153c52e5c2..f0cdc462f4 100644 --- a/lib/dns/include/dns/view.h +++ b/lib/dns/include/dns/view.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: view.h,v 1.132 2011/01/13 01:59:28 marka Exp $ */ +/* $Id: view.h,v 1.133 2011/02/23 03:08:11 marka Exp $ */ #ifndef DNS_VIEW_H #define DNS_VIEW_H 1 @@ -182,6 +182,7 @@ struct dns_view { dns_viewlist_t * viewlist; dns_zone_t * managed_keys; + dns_zone_t * redirect; #ifdef BIND9 /* File in which to store configuration for newly added zones */ diff --git a/lib/dns/include/dns/zone.h b/lib/dns/include/dns/zone.h index de16129325..6c5927421e 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.182 2010/12/18 01:56:22 each Exp $ */ +/* $Id: zone.h,v 1.183 2011/02/23 03:08:11 marka Exp $ */ #ifndef DNS_ZONE_H #define DNS_ZONE_H 1 @@ -43,7 +43,8 @@ typedef enum { dns_zone_stub, dns_zone_staticstub, dns_zone_key, - dns_zone_dlz + dns_zone_dlz, + dns_zone_redirect, } dns_zonetype_t; #define DNS_ZONEOPT_SERVERS 0x00000001U /*%< perform server checks */ diff --git a/lib/dns/view.c b/lib/dns/view.c index 44f868c20c..b649f5daf1 100644 --- a/lib/dns/view.c +++ b/lib/dns/view.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: view.c,v 1.178 2011/01/13 09:53:04 marka Exp $ */ +/* $Id: view.c,v 1.179 2011/02/23 03:08:11 marka Exp $ */ /*! \file */ @@ -195,6 +195,7 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, ISC_LIST_INIT(view->rpz_zones); dns_fixedname_init(&view->dlv_fixed); view->managed_keys = NULL; + view->redirect = NULL; #ifdef BIND9 view->new_zone_file = NULL; view->new_zone_config = NULL; @@ -430,6 +431,8 @@ destroy(dns_view_t *view) { } if (view->managed_keys != NULL) dns_zone_detach(&view->managed_keys); + if (view->redirect != NULL) + dns_zone_detach(&view->redirect); dns_view_setnewzones(view, ISC_FALSE, NULL, NULL); #endif dns_fwdtable_destroy(&view->fwdtable); @@ -499,6 +502,11 @@ view_flushanddetach(dns_view_t **viewp, isc_boolean_t flush) { dns_zone_flush(view->managed_keys); dns_zone_detach(&view->managed_keys); } + if (view->redirect != NULL) { + if (view->flush) + dns_zone_flush(view->redirect); + dns_zone_detach(&view->redirect); + } #endif done = all_done(view); UNLOCK(&view->lock); diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 3fea87f932..982ec7ecac 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: zone.c,v 1.590 2011/02/22 04:14:30 marka Exp $ */ +/* $Id: zone.c,v 1.591 2011/02/23 03:08:11 marka Exp $ */ /*! \file */ @@ -1058,6 +1058,7 @@ dns_zone_getserial(dns_zone_t *zone) { */ void dns_zone_settype(dns_zone_t *zone, dns_zonetype_t type) { + char namebuf[1024]; REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(type != dns_zone_none); @@ -1068,6 +1069,12 @@ dns_zone_settype(dns_zone_t *zone, dns_zonetype_t type) { LOCK_ZONE(zone); REQUIRE(zone->type == dns_zone_none || zone->type == type); zone->type = type; + + if (zone->strnamerd != NULL) + isc_mem_free(zone->mctx, zone->strnamerd); + + zone_namerd_tostr(zone, namebuf, sizeof namebuf); + zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf); UNLOCK_ZONE(zone); } @@ -1367,6 +1374,8 @@ zone_isdynamic(dns_zone_t *zone) { return (ISC_TF(zone->type == dns_zone_slave || zone->type == dns_zone_stub || zone->type == dns_zone_key || + (zone->type == dns_zone_redirect && + zone->masters != NULL) || (!zone->update_disabled && zone->ssutable != NULL) || (!zone->update_disabled && zone->update_acl != NULL && !dns_acl_isnone(zone->update_acl)))); @@ -1476,7 +1485,8 @@ zone_load(dns_zone_t *zone, unsigned int flags) { goto cleanup; } - if ((zone->type == dns_zone_slave || zone->type == dns_zone_stub) && + if ((zone->type == dns_zone_slave || zone->type == dns_zone_stub || + (zone->type == dns_zone_redirect && zone->masters != NULL)) && rbt) { if (zone->masterfile == NULL || !isc_file_exists(zone->masterfile)) { @@ -1514,7 +1524,9 @@ zone_load(dns_zone_t *zone, unsigned int flags) { result = zone_startload(db, zone, loadtime); } else { result = DNS_R_NOMASTERFILE; - if (zone->type == dns_zone_master) { + if (zone->type == dns_zone_master || + (zone->type == dns_zone_redirect && + zone->masters == NULL)) { dns_zone_log(zone, ISC_LOG_ERROR, "loading zone: " "no master file configured"); @@ -1580,7 +1592,8 @@ get_master_options(dns_zone_t *zone) { unsigned int options; options = DNS_MASTER_ZONE; - if (zone->type == dns_zone_slave) + if (zone->type == dns_zone_slave || + (zone->type == dns_zone_redirect && zone->masters == NULL)) options |= DNS_MASTER_SLAVE; if (zone->type == dns_zone_key) options |= DNS_MASTER_KEY; @@ -3331,7 +3344,9 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, */ if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) { if (zone->type == dns_zone_slave || - zone->type == dns_zone_stub) { + zone->type == dns_zone_stub || + (zone->type == dns_zone_redirect && + zone->masters == NULL)) { if (result == ISC_R_FILENOTFOUND) dns_zone_log(zone, ISC_LOG_DEBUG(1), "no master file"); @@ -3436,6 +3451,7 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, case dns_zone_master: case dns_zone_slave: case dns_zone_stub: + case dns_zone_redirect: if (soacount != 1) { dns_zone_log(zone, ISC_LOG_ERROR, "has %d SOA records", soacount); @@ -3452,7 +3468,8 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, result = DNS_R_BADZONE; goto cleanup; } - if (zone->type != dns_zone_stub) { + if (zone->type != dns_zone_stub && + zone->type != dns_zone_redirect) { result = check_nsec3param(zone, db); if (result != ISC_R_SUCCESS) goto cleanup; @@ -3527,7 +3544,9 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS); if (zone->type == dns_zone_slave || - zone->type == dns_zone_stub) { + zone->type == dns_zone_stub || + (zone->type == dns_zone_redirect && + zone->masters != NULL)) { isc_time_t t; isc_uint32_t delay; @@ -3629,7 +3648,8 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, cleanup: if (zone->type == dns_zone_slave || zone->type == dns_zone_stub || - zone->type == dns_zone_key) { + zone->type == dns_zone_key || + (zone->type == dns_zone_redirect && zone->masters != NULL)) { if (zone->journal != NULL) zone_saveunique(zone, zone->journal, "jn-XXXXXXXX"); if (zone->masterfile != NULL) @@ -3640,7 +3660,8 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, if (zone->task != NULL) zone_settimer(zone, &now); result = ISC_R_SUCCESS; - } else if (zone->type == dns_zone_master) + } else if (zone->type == dns_zone_master || + zone->type == dns_zone_redirect) dns_zone_log(zone, ISC_LOG_ERROR, "not loaded due to errors."); return (result); } @@ -7803,6 +7824,9 @@ zone_maintenance(dns_zone_t *zone) { * Expire check. */ switch (zone->type) { + case dns_zone_redirect: + if (zone->masters == NULL) + break; case dns_zone_slave: case dns_zone_stub: LOCK_ZONE(zone); @@ -7821,6 +7845,9 @@ zone_maintenance(dns_zone_t *zone) { * Up to date check. */ switch (zone->type) { + case dns_zone_redirect: + if (zone->masters == NULL) + break; case dns_zone_slave: case dns_zone_stub: if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH) && @@ -7838,6 +7865,7 @@ zone_maintenance(dns_zone_t *zone) { case dns_zone_master: case dns_zone_slave: case dns_zone_key: + case dns_zone_redirect: LOCK_ZONE(zone); if (zone->masterfile != NULL && isc_time_compare(&now, &zone->dumptime) >= 0 && @@ -9329,7 +9357,8 @@ refresh_callback(isc_task_t *task, isc_event_t *event) { "master %s exceeded (source %s)", master, source); /* Try with slave with TCP. */ - if (zone->type == dns_zone_slave && + if ((zone->type == dns_zone_slave || + zone->type == dns_zone_redirect) && DNS_ZONE_OPTION(zone, DNS_ZONEOPT_TRYTCPREFRESH)) { if (!dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr, @@ -9398,7 +9427,8 @@ refresh_callback(isc_task_t *task, isc_event_t *event) { * Perhaps AXFR/IXFR is allowed even if SOA queries aren't. */ if (msg->rcode == dns_rcode_refused && - zone->type == dns_zone_slave) + (zone->type == dns_zone_slave || + zone->type == dns_zone_redirect)) goto tcp_transfer; goto next_master; } @@ -9407,7 +9437,8 @@ refresh_callback(isc_task_t *task, isc_event_t *event) { * If truncated punt to zone transfer which will query again. */ if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) { - if (zone->type == dns_zone_slave) { + if (zone->type == dns_zone_slave || + zone->type == dns_zone_redirect) { dns_zone_log(zone, ISC_LOG_INFO, "refresh: truncated UDP answer, " "initiating TCP zone xfer " @@ -9531,7 +9562,8 @@ refresh_callback(isc_task_t *task, isc_event_t *event) { dns_zone_log(zone, ISC_LOG_INFO, "refresh: skipping %s as master %s " "(source %s) is unreachable (cached)", - zone->type == dns_zone_slave ? + (zone->type == dns_zone_slave || + zone->type == dns_zone_redirect) ? "zone transfer" : "NS query", master, source); goto next_master; @@ -9541,7 +9573,8 @@ refresh_callback(isc_task_t *task, isc_event_t *event) { LOCK_ZONE(zone); dns_request_destroy(&zone->request); UNLOCK_ZONE(zone); - if (zone->type == dns_zone_slave) { + if (zone->type == dns_zone_slave || + zone->type == dns_zone_redirect) { queue_xfrin(zone); } else { INSIST(zone->type == dns_zone_stub); @@ -10332,6 +10365,11 @@ zone_settimer(dns_zone_t *zone, isc_time_t *now) { isc_time_settoepoch(&next); switch (zone->type) { + case dns_zone_redirect: + if (zone->masters != NULL) + goto treat_as_slave; + /* FALLTHROUGH */ + case dns_zone_master: if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY)) next = zone->notifytime; @@ -10342,6 +10380,8 @@ zone_settimer(dns_zone_t *zone, isc_time_t *now) { isc_time_compare(&zone->dumptime, &next) < 0) next = zone->dumptime; } + if (zone->type == dns_zone_redirect) + break; if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING) && !isc_time_isepoch(&zone->refreshkeytime)) { if (isc_time_isepoch(&next) || @@ -10371,9 +10411,10 @@ zone_settimer(dns_zone_t *zone, isc_time_t *now) { break; case dns_zone_slave: + treat_as_slave: if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY)) next = zone->notifytime; - /*FALLTHROUGH*/ + /* FALLTHROUGH */ case dns_zone_stub: if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH) && @@ -11035,15 +11076,17 @@ zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length) { * Leave space for terminating '\0'. */ isc_buffer_init(&buffer, buf, length - 1); - if (dns_name_dynamic(&zone->origin)) - result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer); - if (result != ISC_R_SUCCESS && - isc_buffer_availablelength(&buffer) >= (sizeof("") - 1)) - isc_buffer_putstr(&buffer, ""); + if (zone->type != dns_zone_redirect && zone->type != dns_zone_key) { + if (dns_name_dynamic(&zone->origin)) + result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer); + if (result != ISC_R_SUCCESS && + isc_buffer_availablelength(&buffer) >= (sizeof("") - 1)) + isc_buffer_putstr(&buffer, ""); - if (isc_buffer_availablelength(&buffer) > 0) - isc_buffer_putstr(&buffer, "/"); - (void)dns_rdataclass_totext(zone->rdclass, &buffer); + if (isc_buffer_availablelength(&buffer) > 0) + isc_buffer_putstr(&buffer, "/"); + (void)dns_rdataclass_totext(zone->rdclass, &buffer); + } if (zone->view != NULL && strcmp(zone->view->name, "_bind") != 0 && strcmp(zone->view->name, "_default") != 0 && @@ -11152,8 +11195,9 @@ dns_zone_logc(dns_zone_t *zone, isc_logcategory_t *category, vsnprintf(message, sizeof(message), fmt, ap); va_end(ap); isc_log_write(dns_lctx, category, DNS_LOGMODULE_ZONE, - level, "%s %s: %s", (zone->type == dns_zone_key) ? - "managed-keys-zone" : "zone", zone->strnamerd, message); + level, "%s%s: %s", (zone->type == dns_zone_key) ? + "managed-keys-zone" : (zone->type == dns_zone_redirect) ? + "redirect-zone" : "zone ", zone->strnamerd, message); } void @@ -11168,8 +11212,9 @@ dns_zone_log(dns_zone_t *zone, int level, const char *fmt, ...) { vsnprintf(message, sizeof(message), fmt, ap); va_end(ap); isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE, - level, "%s %s: %s", (zone->type == dns_zone_key) ? - "managed-keys-zone" : "zone", zone->strnamerd, message); + level, "%s%s: %s", (zone->type == dns_zone_key) ? + "managed-keys-zone" : (zone->type == dns_zone_redirect) ? + "redirect-zone" : "zone ", zone->strnamerd, message); } static void @@ -11447,8 +11492,10 @@ zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) { &oldserial, NULL, NULL, NULL, NULL, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); - if (zone->type == dns_zone_slave && - !isc_serial_gt(serial, oldserial)) { + if ((zone->type == dns_zone_slave || + (zone->type == dns_zone_redirect && + zone->masters != NULL)) + && !isc_serial_gt(serial, oldserial)) { isc_uint32_t serialmin, serialmax; serialmin = (oldserial + 1) & 0xffffffffU; serialmax = (oldserial + 0x7fffffffU) & 0xffffffffU; @@ -13056,7 +13103,8 @@ void dns_zone_forcereload(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); - if (zone->type == dns_zone_master) + if (zone->type == dns_zone_master || + (zone->type == dns_zone_redirect && zone->masters == NULL)) return; LOCK_ZONE(zone); @@ -13148,7 +13196,7 @@ dns_zone_dialup(dns_zone_t *zone) { if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY)) dns_zone_notify(zone); - if (zone->type != dns_zone_master && + if (zone->type != dns_zone_master && zone->masters != NULL && DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH)) dns_zone_refresh(zone); } diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index d1a8df4cc1..4b666b25db 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: namedconf.c,v 1.132 2011/02/03 05:41:55 marka Exp $ */ +/* $Id: namedconf.c,v 1.133 2011/02/23 03:08:11 marka Exp $ */ /*! \file */ @@ -594,7 +594,7 @@ static cfg_type_t cfg_type_forwardtype = { static const char *zonetype_enums[] = { "master", "slave", "stub", "static-stub", "hint", "forward", - "delegation-only", NULL }; + "delegation-only", "redirect", NULL }; static cfg_type_t cfg_type_zonetype = { "zonetype", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum, &cfg_rep_string, &zonetype_enums -- GitLab