2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-29 13:38:26 +00:00

2800. [func] Reject zones which have NS records which refer to

CNAMEs, DNAMEs or don't have address record (class IN
                        only).  Reject UPDATEs which would cause the zone
                        to fail the above checks if committed. [RT #20678]
This commit is contained in:
Mark Andrews 2009-12-04 03:33:15 +00:00
parent 6ec134549f
commit 5d850024cb
6 changed files with 87 additions and 26 deletions

View File

@ -1,3 +1,8 @@
2800. [func] Reject zones which have NS records which refer to
CNAMEs, DNAMEs or don't have address record (class IN
only). Reject UPDATEs which would cause the zone
to fail the above checks if committed. [RT #20678]
2799. [cleanup] Changed the "secure-to-insecure" option to
"dnssec-secure-to-insecure", and "dnskey-ksk-only"
to "dnssec-dnskey-kskonly", for clarity. [RT #20586]

View File

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: update.c,v 1.173 2009/12/03 23:48:22 tbox Exp $ */
/* $Id: update.c,v 1.174 2009/12/04 03:33:14 marka Exp $ */
#include <config.h>
@ -4088,6 +4088,18 @@ update_action(isc_task_t *task, isc_event_t *event) {
if (! ISC_LIST_EMPTY(diff.tuples))
CHECK(check_dnssec(client, zone, db, ver, &diff));
if (! ISC_LIST_EMPTY(diff.tuples)) {
unsigned int errors = 0;
CHECK(dns_zone_nscheck(zone, db, ver, &errors));
if (errors != 0) {
update_log(client, zone, LOGLEVEL_PROTOCOL,
"update rejected: post update name server "
"sanity check failed");
result = DNS_R_REFUSED;
goto failure;
}
}
/*
* If any changes were made, increment the SOA serial number,
* update RRSIGs and NSECs (if zone is secure), and write the update

View File

@ -15,7 +15,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
# $Id: setup.sh,v 1.13 2009/07/30 15:11:41 each Exp $
# $Id: setup.sh,v 1.14 2009/12/04 03:33:15 marka Exp $
SYSTEMTESTTOP=..
. $SYSTEMTESTTOP/conf.sh
@ -43,6 +43,7 @@ update.nil IN SOA ns1.example.nil. hostmaster.example.nil. (
)
update.nil. NS ns1.update.nil.
ns1.update.nil. A 10.53.0.2
ns2.update.nil. AAAA ::1
EOF
../../../tools/genrandom 400 random.data

View File

@ -14,7 +14,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
# $Id: tests.sh,v 1.4 2007/06/19 23:47:07 tbox Exp $
# $Id: tests.sh,v 1.5 2009/12/04 03:33:15 marka Exp $
SYSTEMTESTTOP=..
. $SYSTEMTESTTOP/conf.sh
@ -161,4 +161,4 @@ else
echo "I:failed (status)"; status=1
fi
echo "I:exit status: $status"
exit $?
exit $status

View File

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: zone.h,v 1.171 2009/12/03 23:18:17 each Exp $ */
/* $Id: zone.h,v 1.172 2009/12/04 03:33:15 marka Exp $ */
#ifndef DNS_ZONE_H
#define DNS_ZONE_H 1
@ -1782,6 +1782,25 @@ dns_zone_rekey(dns_zone_t *zone);
* Update the zone's DNSKEY set from the key repository.
*/
isc_result_t
dns_zone_nscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
unsigned int *errors);
/*%
* Check if the name servers for the zone are sane (have address, don't
* refer to CNAMEs/DNAMEs. The number of constiancy errors detected in
* returned in '*errors'
*
* Requires:
* \li 'zone' to be valid.
* \li 'db' to be valid.
* \li 'version' to be valid or NULL.
* \li 'errors' to be non NULL.
*
* Returns:
* ISC_R_SUCCESS if there were no errors examining the zone contents.
*/
ISC_LANG_ENDDECLS
#endif /* DNS_ZONE_H */

View File

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: zone.c,v 1.534 2009/12/03 15:40:02 each Exp $ */
/* $Id: zone.c,v 1.535 2009/12/04 03:33:15 marka Exp $ */
/*! \file */
@ -3540,7 +3540,9 @@ exit_check(dns_zone_t *zone) {
}
static isc_boolean_t
zone_check_ns(dns_zone_t *zone, dns_db_t *db, dns_name_t *name) {
zone_check_ns(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
isc_boolean_t logit)
{
isc_result_t result;
char namebuf[DNS_NAME_FORMATSIZE];
char altbuf[DNS_NAME_FORMATSIZE];
@ -3571,30 +3573,33 @@ zone_check_ns(dns_zone_t *zone, dns_db_t *db, dns_name_t *name) {
return (ISC_TRUE);
}
dns_name_format(name, namebuf, sizeof namebuf);
if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
result == DNS_R_EMPTYNAME) {
dns_zone_log(zone, level,
"NS '%s' has no address records (A or AAAA)",
namebuf);
/* XXX950 Make fatal ISC_FALSE for 9.5.0. */
return (ISC_TRUE);
if (logit) {
dns_name_format(name, namebuf, sizeof namebuf);
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);
/* XXX950 Make fatal ISC_FALSE for 9.5.0. */
return (ISC_TRUE);
if (logit) {
dns_name_format(name, namebuf, sizeof namebuf);
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);
/* XXX950 Make fatal ISC_FALSE for 9.5.0. */
return (ISC_TRUE);
if (logit) {
dns_name_format(name, namebuf, sizeof namebuf);
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);
@ -3603,7 +3608,7 @@ 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 *errors)
unsigned int *errors, isc_boolean_t logit)
{
isc_result_t result;
unsigned int count = 0;
@ -3634,7 +3639,7 @@ zone_count_ns_rr(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node,
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))
!zone_check_ns(zone, db, &ns.name, logit))
ecount++;
}
count++;
@ -3763,7 +3768,7 @@ zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
if (nscount != NULL || errors != NULL) {
result = zone_count_ns_rr(zone, db, node, version,
nscount, errors);
nscount, errors, ISC_TRUE);
if (result != ISC_R_SUCCESS)
answer = result;
}
@ -13607,3 +13612,22 @@ dns_zone_rekey(dns_zone_t *zone) {
UNLOCK_ZONE(zone);
return (result);
}
isc_result_t
dns_zone_nscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
unsigned int *errors)
{
isc_result_t result;
dns_dbnode_t *node = NULL;
REQUIRE(DNS_ZONE_VALID(zone));
REQUIRE(errors != NULL);
result = dns_db_getoriginnode(db, &node);
if (result != ISC_R_SUCCESS)
return (result);
result = zone_count_ns_rr(zone, db, node, version, NULL, errors,
ISC_FALSE);
dns_db_detachnode(db, &node);
return (result);
}