if there was no SOA record in the replacment db.
[RT #13016]
-1763. [placeholder] rt13002
+1763. [func] Perform sanity checks on NS records which refer to
+ 'in zone' names. [RT #13002]
1762. [bug] isc_interfaceiter_create() could return ISC_R_SUCCESS
even when it failed. [RT #12995]
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: conf.sh.in,v 1.27 2004/03/05 04:59:12 marka Exp $
+# $Id: conf.sh.in,v 1.28 2004/11/23 05:23:35 marka Exp $
#
# Common configuration data for system tests, to be sourced into
NSUPDATE=$TOP/bin/nsupdate/nsupdate
KEYGEN=$TOP/bin/dnssec/dnssec-keygen
SIGNER=$TOP/bin/dnssec/dnssec-signzone
+CHECKZONE=$TOP/bin/check/named-checkzone
# The "stress" test is not run by default since it creates enough
# load on the machine to make it unusable to other users.
# v6synth
SUBDIRS="cacheclean checknames dnssec forward glue ixfr limits lwresd \
masterfile notify nsupdate resolver sortlist stub tkey \
- unknown upforwd views xfer xferquota"
+ unknown upforwd views xfer xferquota zonechecks"
# PERL will be an empty string if no perl interpreter was found.
PERL=@PERL@
export NAMED LWRESD DIG NSUPDATE KEYGEN SIGNER KEYSIGNER KEYSETTOOL PERL \
- SUBDIRS RNDC
+ SUBDIRS RNDC CHECKZONE
d.ttl2. 3 IN TXT "default ttl 3"
e.ttl2. 2 IN TXT "explicit ttl 2"
f.ttl2. 3 IN TXT "default ttl 3"
+ns.ttl2. 1 IN A 10.53.0.1
ttl2. 1 IN SOA ns.ttl2. hostmaster.ttl2. 1 3600 1800 1814400 3
ttl2. 1 IN SOA ns.ttl2. hostmaster.ttl2. 1 3600 1800 1814400 3
ttl2. 1 IN NS ns.ttl2.
d.ttl2. 3 IN TXT "default ttl 3"
e.ttl2. 2 IN TXT "explicit ttl 2"
f.ttl2. 3 IN TXT "default ttl 3"
+ns.ttl2. 1 IN A 10.53.0.1
ttl2. 1 IN SOA ns.ttl2. hostmaster.ttl2. 1 3600 1800 1814400 3
; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
; PERFORMANCE OF THIS SOFTWARE.
-; $Id: ttl1.db,v 1.3 2004/03/05 05:01:35 marka Exp $
+; $Id: ttl1.db,v 1.4 2004/11/23 05:23:38 marka Exp $
@ IN SOA ns hostmaster (
1 ; serial
3
)
NS ns
+ns A 10.53.0.1
a TXT "soa minttl 3"
b 2 TXT "explicit ttl 2"
c TXT "soa minttl 3"
; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
; PERFORMANCE OF THIS SOFTWARE.
-; $Id: ttl2.db,v 1.3 2004/03/05 05:01:35 marka Exp $
+; $Id: ttl2.db,v 1.4 2004/11/23 05:23:38 marka Exp $
@ 1 IN SOA ns hostmaster (
1 ; serial
3
)
NS ns
+ns A 10.53.0.1
a TXT "inherited ttl 1"
b 2 TXT "explicit ttl 2"
c TXT "inherited ttl 2"
example.nil. 300 IN SOA ns1.example.nil. hostmaster.example.nil. 2 2000 2000 1814400 3600
+example.nil. 300 IN NS ns1.example.nil.
example.nil. 300 IN NS ns2.example.nil.
-example.nil. 300 IN NS ns3.example.nil.
*.example.nil. 300 IN MX 10 mail.example.nil.
a.example.nil. 300 IN TXT "foo foo foo"
a.example.nil. 300 IN PTR foo.net.
dname03.example.nil. 3600 IN DNAME .
e.example.nil. 300 IN MX 10 mail.example.nil.
e.example.nil. 300 IN TXT "one"
-e.example.nil. 300 IN TXT "three"
e.example.nil. 300 IN TXT "two"
+e.example.nil. 300 IN TXT "three"
e.example.nil. 300 IN A 73.80.65.49
e.example.nil. 300 IN A 73.80.65.50
-e.example.nil. 300 IN A 73.80.65.52
e.example.nil. 300 IN A 73.80.65.51
+e.example.nil. 300 IN A 73.80.65.52
f.example.nil. 300 IN A 73.80.65.52
gpos01.example.nil. 3600 IN GPOS "-22.6882" "116.8652" "250.0"
gpos02.example.nil. 3600 IN GPOS "" "" ""
naptr02.example.nil. 3600 IN NAPTR 65535 65535 "blurgh" "blorf" "blegh" foo.
ns1.example.nil. 300 IN A 10.53.0.1
ns2.example.nil. 300 IN A 10.53.0.2
-nsap-ptr01.example.nil. 3600 IN NSAP-PTR foo.
nsap-ptr01.example.nil. 3600 IN NSAP-PTR .
+nsap-ptr01.example.nil. 3600 IN NSAP-PTR foo.
nsap01.example.nil. 3600 IN NSAP 0x47000580005a0000000001e133ffffff00016100
nsap02.example.nil. 3600 IN NSAP 0x47000580005a0000000001e133ffffff00016100
nxt01.example.nil. 3600 IN NXT a.secure.example.nil. NS SOA MX SIG KEY LOC NXT
wks03.example.nil. 3600 IN WKS 10.0.0.2 6 65535
x2501.example.nil. 3600 IN X25 "123456789"
example.nil. 300 IN SOA ns1.example.nil. hostmaster.example.nil. 2 2000 2000 1814400 3600
-
updated4.example.nil. 600 IN A 10.10.10.3
+example.nil. 300 IN NS ns1.example.nil.
example.nil. 300 IN NS ns2.example.nil.
-example.nil. 300 IN NS ns3.example.nil.
example.nil. 300 IN SOA ns1.example.nil. hostmaster.example.nil. 1 2000 2000 1814400 3600
+example.nil. 300 IN NS ns1.example.nil.
example.nil. 300 IN NS ns2.example.nil.
-example.nil. 300 IN NS ns3.example.nil.
*.example.nil. 300 IN MX 10 mail.example.nil.
a.example.nil. 300 IN TXT "foo foo foo"
a.example.nil. 300 IN PTR foo.net.
dname03.example.nil. 3600 IN DNAME .
e.example.nil. 300 IN MX 10 mail.example.nil.
e.example.nil. 300 IN TXT "one"
-e.example.nil. 300 IN TXT "three"
e.example.nil. 300 IN TXT "two"
+e.example.nil. 300 IN TXT "three"
e.example.nil. 300 IN A 73.80.65.49
e.example.nil. 300 IN A 73.80.65.50
-e.example.nil. 300 IN A 73.80.65.52
e.example.nil. 300 IN A 73.80.65.51
+e.example.nil. 300 IN A 73.80.65.52
f.example.nil. 300 IN A 73.80.65.52
gpos01.example.nil. 3600 IN GPOS "-22.6882" "116.8652" "250.0"
gpos02.example.nil. 3600 IN GPOS "" "" ""
naptr02.example.nil. 3600 IN NAPTR 65535 65535 "blurgh" "blorf" "blegh" foo.
ns1.example.nil. 300 IN A 10.53.0.1
ns2.example.nil. 300 IN A 10.53.0.2
-nsap-ptr01.example.nil. 3600 IN NSAP-PTR foo.
nsap-ptr01.example.nil. 3600 IN NSAP-PTR .
+nsap-ptr01.example.nil. 3600 IN NSAP-PTR foo.
nsap01.example.nil. 3600 IN NSAP 0x47000580005a0000000001e133ffffff00016100
nsap02.example.nil. 3600 IN NSAP 0x47000580005a0000000001e133ffffff00016100
nxt01.example.nil. 3600 IN NXT a.secure.example.nil. NS SOA MX SIG KEY LOC NXT
wks03.example.nil. 3600 IN WKS 10.0.0.2 6 65535
x2501.example.nil. 3600 IN X25 "123456789"
example.nil. 300 IN SOA ns1.example.nil. hostmaster.example.nil. 1 2000 2000 1814400 3600
-
; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
; PERFORMANCE OF THIS SOFTWARE.
-; $Id: example1.db,v 1.5 2004/03/05 05:01:58 marka Exp $
+; $Id: example1.db,v 1.6 2004/11/23 05:23:39 marka Exp $
$ORIGIN .
$TTL 300 ; 5 minutes
1814400 ; expire (3 weeks)
3600 ; minimum (1 hour)
)
-example.nil. NS ns2.example.nil.
+example.nil. NS ns1.example.nil.
ns1.example.nil. A 10.53.0.1
-example.nil. NS ns3.example.nil.
+example.nil. NS ns2.example.nil.
ns2.example.nil. A 10.53.0.2
$ORIGIN example.nil.
; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
; PERFORMANCE OF THIS SOFTWARE.
-; $Id: example.db,v 1.4 2004/03/05 05:02:43 marka Exp $
+; $Id: example.db,v 1.5 2004/11/23 05:23:40 marka Exp $
$TTL 300 ; 5 minutes
-@ IN SOA ns2.example. hostmaster.example. (
+@ IN SOA ns1.example. hostmaster.example. (
2000042795 ; serial
20 ; refresh (20 seconds)
20 ; retry (20 seconds)
3600 ; minimum (1 hour)
)
example. NS ns1.example.
-ns2.example. A 10.53.0.1
+ns1.example. A 10.53.0.1
; Let's see what the sortlist picks out of this...
a A 1.1.1.1
; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
; PERFORMANCE OF THIS SOFTWARE.
-; $Id: example2.db,v 1.7 2004/03/05 05:03:48 marka Exp $
+; $Id: example2.db,v 1.8 2004/11/23 05:23:41 marka Exp $
$ORIGIN .
$TTL 300 ; 5 minutes
3600 ; minimum (1 hour)
)
example. NS ns2.example.
-ns0.example. A 10.53.0.4
+ns2.example. A 10.53.0.4
$ORIGIN example.
a A 10.0.0.1
; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
; PERFORMANCE OF THIS SOFTWARE.
-; $Id: changing1.db,v 1.7 2004/03/05 05:04:05 marka Exp $
+; $Id: changing1.db,v 1.8 2004/11/23 05:23:43 marka Exp $
$TTL 600
-@ IN SOA dns.changing. postmaster.changing. (
+@ IN SOA dns1.changing. postmaster.changing. (
1 ;; serial
3600 ;; refresh period
1800 ;; retry interval
; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
; PERFORMANCE OF THIS SOFTWARE.
-; $Id: changing2.db,v 1.7 2004/03/05 05:04:05 marka Exp $
+; $Id: changing2.db,v 1.8 2004/11/23 05:23:44 marka Exp $
$TTL 600
-@ IN SOA dns.changing. postmaster.changing. (
+@ IN SOA dns1.changing. postmaster.changing. (
2 ;; serial
3600 ;; refresh period
1800 ;; retry interval
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: named.conf,v 1.19 2004/03/05 05:04:08 marka Exp $ */
+/* $Id: named.conf,v 1.20 2004/11/23 05:23:44 marka Exp $ */
controls { /* empty */ };
listen-on { 10.53.0.2; };
listen-on-v6 { none; };
recursion no;
- notify yes;
+ notify no;
transfers-in 5;
transfers-per-ns 5;
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: setup.pl,v 1.11 2004/03/05 05:04:03 marka Exp $
+# $Id: setup.pl,v 1.12 2004/11/23 05:23:42 marka Exp $
#
# Set up test data for zone transfer quota tests.
my $fn = "ns1/$zn.db";
my $f = new FileHandle($fn, "w") or die "open: $fn: $!";
print $f "\$TTL 300
-\@ IN SOA . . 1 300 120 3600 86400
+\@ IN SOA ns1 . 1 300 120 3600 86400
NS ns1
NS ns2
+ns1 A 10.53.0.1
+ns2 A 10.53.0.2
MX 10 mail1.isp.example.
MX 20 mail2.isp.example.
www A 10.0.0.1
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: tests.sh,v 1.22 2004/03/10 01:06:06 marka Exp $
+# $Id: tests.sh,v 1.23 2004/11/23 05:23:42 marka Exp $
SYSTEMTESTTOP=..
. $SYSTEMTESTTOP/conf.sh
$PERL ../digcomp.pl dig.out.ns1 dig.out.ns2 || status=1
-sleep 5
+sleep 15
$DIG +tcp +noadd +nosea +nostat +noquest +nocomm +nocmd \
a.changing. @10.53.0.1 a -p 5300 > dig.out.ns1 || status=1
--- /dev/null
+; Copyright
+@ 3600 IN SOA ns hostmaster 1 3600 1200 604800 3600
+@ 3600 IN NS 127.0.0.1
+127.0.0.1 3600 IN A 127.0.0.1
--- /dev/null
+; Copyright
+@ 3600 IN SOA ns hostmaster 1 3600 1200 604800 3600
+@ 3600 IN NS ::1
+::1 3600 IN AAAA ::1
--- /dev/null
+#!/bin/sh
+#
+# Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2001 Internet Software Consortium.
+#
+# Permission to use, copy, modify, and 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 2004/11/23 05:23:45 marka Exp $
+
+rm -f *.out
--- /dev/null
+; Copyright
+@ 3600 IN SOA ns hostmaster 1 3600 1200 604800 3600
+@ 3600 IN NS ns
+ns 3600 IN CNAME @
--- /dev/null
+; Copyright
+@ 3600 IN SOA ns hostmaster 1 3600 1200 604800 3600
+@ 3600 IN NS ns
+@ 3600 IN DNAME .
--- /dev/null
+; Copyright
+@ 3600 IN SOA ns hostmaster 1 3600 1200 604800 3600
+@ 3600 IN NS ns
+ns 3600 IN TXT this name has no address records
--- /dev/null
+; Copyright
+@ 3600 IN SOA ns hostmaster 1 3600 1200 604800 3600
+@ 3600 IN NS ns
+; There are no records at all with the ownername of "ns".
--- /dev/null
+#!/bin/sh
+#
+# Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and 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 2004/11/23 05:23:46 marka Exp $
+
+SYSTEMTESTTOP=..
+. $SYSTEMTESTTOP/conf.sh
+
+status=0
+
+#
+echo "I: checking that we detect a NS which refers to a CNAME"
+if $CHECKZONE . cname.db > cname.out 2>&1
+then
+ echo "I:failed (status)"; status=1
+else
+ if grep "is a CNAME" cname.out > /dev/null
+ then
+ :
+ else
+ echo "I:failed (message)"; status=1
+ fi
+fi
+
+#
+echo "I: checking that we detect a NS which is below a DNAME"
+if $CHECKZONE . dname.db > dname.out 2>&1
+then
+ echo "I:failed (status)"; status=1
+else
+ if grep "is below a DNAME" dname.out > /dev/null
+ then
+ :
+ else
+ echo "I:failed (message)"; status=1
+ fi
+fi
+
+#
+echo "I: checking that we detect a NS which has no address records (A/AAAA)"
+if $CHECKZONE . noaddress.db > noaddress.out
+then
+ echo "I:failed (status)"; status=1
+else
+ if grep "has no address records" noaddress.out > /dev/null
+ then
+ :
+ else
+ echo "I:failed (message)"; status=1
+ fi
+fi
+
+#
+echo "I: checking that we detect a NS which has no records"
+if $CHECKZONE . nxdomain.db > nxdomain.out
+then
+ echo "I:failed (status)"; status=1
+else
+ if grep "has no address records" noaddress.out > /dev/null
+ then
+ :
+ else
+ echo "I:failed (message)"; status=1
+ fi
+fi
+
+#
+echo "I: checking that we detect a NS which looks like a A record (fail)"
+if $CHECKZONE -n fail . a.db > a.out 2>&1
+then
+ echo "I:failed (status)"; status=1
+else
+ if grep "appears to be an address" a.out > /dev/null
+ then
+ :
+ else
+ echo "I:failed (message)"; status=1
+ fi
+fi
+
+#
+echo "I: checking that we detect a NS which looks like a A record (warn=default)"
+if $CHECKZONE . a.db > a.out 2>&1
+then
+ if grep "appears to be an address" a.out > /dev/null
+ then
+ :
+ else
+ echo "I:failed (message)"; status=1
+ fi
+else
+ echo "I:failed (status)"; status=1
+fi
+
+#
+echo "I: checking that we detect a NS which looks like a A record (ignore)"
+if $CHECKZONE -n ignore . a.db > a.out 2>&1
+then
+ if grep "appears to be an address" a.out > /dev/null
+ then
+ echo "I:failed (message)"; status=1
+ else
+ :
+ fi
+else
+ echo "I:failed (status)"; status=1
+fi
+
+#
+echo "I: checking that we detect a NS which looks like a AAAA record (fail)"
+if $CHECKZONE -n fail . aaaa.db > aaaa.out 2>&1
+then
+ echo "I:failed (status)"; status=1
+else
+ if grep "appears to be an address" aaaa.out > /dev/null
+ then
+ :
+ else
+ echo "I:failed (message)"; status=1
+ fi
+fi
+
+#
+echo "I: checking that we detect a NS which looks like a AAAA record (warn=default)"
+if $CHECKZONE . aaaa.db > aaaa.out 2>&1
+then
+ if grep "appears to be an address" aaaa.out > /dev/null
+ then
+ :
+ else
+ echo "I:failed (message)"; status=1
+ fi
+else
+ echo "I:failed (status)"; status=1
+fi
+
+#
+echo "I: checking that we detect a NS which looks like a AAAA record (ignore)"
+if $CHECKZONE -n ignore . aaaa.db > aaaa.out 2>&1
+then
+ if grep "appears to be an address" aaaa.out > /dev/null
+ then
+ echo "I:failed (message)"; status=1
+ else
+ :
+ fi
+else
+ echo "I:failed (status)"; status=1
+fi
+echo "I:exit status: $status"
+exit $?
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: zone.c,v 1.424 2004/11/22 23:52:25 marka Exp $ */
+/* $Id: zone.c,v 1.425 2004/11/23 05:23:46 marka Exp $ */
#include <config.h>
static void zonemgr_cancelio(dns_io_t *io);
static isc_result_t
-zone_get_from_db(dns_db_t *db, dns_name_t *origin, unsigned int *nscount,
+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);
+ isc_uint32_t *expire, isc_uint32_t *minimum,
+ unsigned int *cnames);
static void zone_freedbargs(dns_zone_t *zone);
static void forward_callback(isc_task_t *task, isc_event_t *event);
{
unsigned int soacount = 0;
unsigned int nscount = 0;
+ unsigned int cnames = 0;
isc_uint32_t serial, refresh, retry, expire, minimum;
isc_time_t now;
isc_boolean_t needdump = ISC_FALSE;
}
/*
- * Obtain ns and soa counts for top of zone.
+ * Obtain ns, soa and cname counts for top of zone.
*/
- nscount = 0;
- soacount = 0;
INSIST(db != NULL);
- result = zone_get_from_db(db, &zone->origin, &nscount,
- &soacount, &serial, &refresh, &retry,
- &expire, &minimum);
+ result = zone_get_from_db(zone, db, &nscount, &soacount, &serial,
+ &refresh, &retry, &expire, &minimum,
+ &cnames);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
"could not find NS and/or SOA records");
}
if (result != ISC_R_SUCCESS)
goto cleanup;
+ if (zone->type == dns_zone_master && cnames != 0) {
+ result = DNS_R_BADZONE;
+ goto cleanup;
+ }
if (zone->db != NULL) {
if (!isc_serial_ge(serial, zone->serial)) {
dns_zone_log(zone, ISC_LOG_ERROR,
goto cleanup;
}
-
#if 0
/* destroy notification example. */
{
return (ISC_FALSE);
}
+static isc_boolean_t
+zone_check_ns(dns_zone_t *zone, dns_db_t *db, dns_name_t *name) {
+ isc_result_t result;
+ char namebuf[DNS_NAME_FORMATSIZE];
+ char altbuf[DNS_NAME_FORMATSIZE];
+ dns_fixedname_t fixed;
+ dns_name_t *foundname;
+ int level;
+
+ if (zone->type == dns_zone_master)
+ level = ISC_LOG_ERROR;
+ else
+ level = ISC_LOG_WARNING;
+
+ dns_fixedname_init(&fixed);
+ foundname = dns_fixedname_name(&fixed);
+
+ result = dns_db_find(db, name, NULL, dns_rdatatype_a,
+ 0, 0, NULL, foundname, NULL, NULL);
+ if (result == ISC_R_SUCCESS)
+ return (ISC_TRUE);
+
+ if (result == DNS_R_NXRRSET) {
+ result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
+ 0, 0, NULL, foundname, NULL, NULL);
+ if (result == ISC_R_SUCCESS)
+ return (ISC_TRUE);
+ }
+
+ dns_name_format(name, namebuf, sizeof namebuf);
+ if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN) {
+ dns_zone_log(zone, level,
+ "NS '%s' has no address records (A or AAAA)",
+ namebuf);
+ return (ISC_FALSE);
+ }
+
+ if (result == DNS_R_CNAME) {
+ dns_zone_log(zone, level, "NS '%s' is a CNAME (illegal)",
+ namebuf);
+ return (ISC_FALSE);
+ }
+
+ if (result == DNS_R_DNAME) {
+ dns_name_format(foundname, altbuf, sizeof altbuf);
+ dns_zone_log(zone, level,
+ "NS '%s' is below a DNAME '%s' (illegal)",
+ namebuf, altbuf);
+ return (ISC_FALSE);
+ }
+
+ return (ISC_TRUE);
+}
+
static isc_result_t
-zone_count_ns_rr(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
- unsigned int *nscount)
+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)
{
isc_result_t result;
- unsigned int count;
+ unsigned int count = 0;
+ unsigned int ccount = 0;
dns_rdataset_t rdataset;
-
- REQUIRE(nscount != NULL);
+ dns_rdata_t rdata;
+ dns_rdata_ns_t ns;
dns_rdataset_init(&rdataset);
result = dns_db_findrdataset(db, node, version, dns_rdatatype_ns,
dns_rdatatype_none, 0, &rdataset, NULL);
- if (result == ISC_R_NOTFOUND) {
- *nscount = 0;
- result = ISC_R_SUCCESS;
- goto invalidate_rdataset;
- }
+ if (result == ISC_R_NOTFOUND)
+ goto success;
if (result != ISC_R_SUCCESS)
goto invalidate_rdataset;
- count = 0;
result = dns_rdataset_first(&rdataset);
while (result == ISC_R_SUCCESS) {
+ if (cnames != NULL && zone->rdclass == dns_rdataclass_in &&
+ (zone->type == dns_zone_master ||
+ zone->type == dns_zone_slave)) {
+ dns_rdata_init(&rdata);
+ dns_rdataset_current(&rdataset, &rdata);
+ result = dns_rdata_tostruct(&rdata, &ns, NULL);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ if (dns_name_issubdomain(&ns.name, &zone->origin) &&
+ !zone_check_ns(zone, db, &ns.name))
+ ccount++;
+ }
count++;
result = dns_rdataset_next(&rdataset);
}
dns_rdataset_disassociate(&rdataset);
- *nscount = count;
+ success:
+ if (nscount != NULL)
+ *nscount = count;
+ if (cnames != NULL)
+ *cnames = ccount;
+
result = ISC_R_SUCCESS;
invalidate_rdataset:
* zone must be locked.
*/
static isc_result_t
-zone_get_from_db(dns_db_t *db, dns_name_t *origin, unsigned int *nscount,
+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)
+ isc_uint32_t *expire, isc_uint32_t *minimum,
+ unsigned int *cnames)
{
dns_dbversion_t *version;
isc_result_t result;
dns_dbnode_t *node;
REQUIRE(db != NULL);
- REQUIRE(origin != NULL);
+ REQUIRE(zone != NULL);
version = NULL;
dns_db_currentversion(db, &version);
node = NULL;
- result = dns_db_findnode(db, origin, ISC_FALSE, &node);
+ result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
if (result != ISC_R_SUCCESS) {
answer = result;
goto closeversion;
}
- if (nscount != NULL) {
- result = zone_count_ns_rr(db, node, version, nscount);
+ if (nscount != NULL || cnames != NULL) {
+ result = zone_count_ns_rr(zone, db, node, version,
+ nscount, cnames);
if (result != ISC_R_SUCCESS)
answer = result;
}
REQUIRE(DNS_ZONE_VALID(zone));
REQUIRE(LOCKED_ZONE(zone));
- result = zone_get_from_db(db, &zone->origin, &nscount, &soacount,
- NULL, NULL, NULL, NULL, NULL);
+ result = zone_get_from_db(zone, db, &nscount, &soacount,
+ NULL, NULL, NULL, NULL, NULL, NULL);
if (result == ISC_R_SUCCESS) {
if (soacount != 1) {
dns_zone_log(zone, ISC_LOG_ERROR,
nscount = 0;
soacount = 0;
INSIST(zone->db != NULL);
- result = zone_get_from_db(zone->db, &zone->origin, &nscount,
+ result = zone_get_from_db(zone, zone->db, &nscount,
&soacount, &serial, &refresh,
- &retry, &expire, &minimum);
+ &retry, &expire, &minimum, NULL);
if (result == ISC_R_SUCCESS) {
if (soacount != 1)
dns_zone_log(zone, ISC_LOG_ERROR,