2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-02 15:45:25 +00:00

When a query matched a DNAME in a secure zone, the server did not return the

signature of the DNAME.  [RT #915]

A query should not match a DNAME whose trust level is pending.  [RT #916]
This commit is contained in:
Bob Halley
2001-02-23 02:14:14 +00:00
parent 542a74fcc4
commit f4b5a0f434
2 changed files with 66 additions and 27 deletions

View File

@@ -1,3 +1,9 @@
750. [bug] A query should not match a DNAME whose trust level
is pending. [RT #916]
749. [bug] When a query matched a DNAME in a secure zone, the
server did not return the signature of the DNAME.
[RT #915]
748. [doc] List supported RFCs in doc/misc/rfc-compliance. 748. [doc] List supported RFCs in doc/misc/rfc-compliance.
[RT #781] [RT #781]

View File

@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
/* $Id: rbtdb.c,v 1.147 2001/02/09 01:26:51 bwelling Exp $ */ /* $Id: rbtdb.c,v 1.148 2001/02/23 02:14:14 halley Exp $ */
/* /*
* Principal Author: Bob Halley * Principal Author: Bob Halley
@@ -77,6 +77,8 @@ typedef isc_uint32_t rbtdb_rdatatype_t;
RBTDB_RDATATYPE_VALUE(dns_rdatatype_sig, dns_rdatatype_ns) RBTDB_RDATATYPE_VALUE(dns_rdatatype_sig, dns_rdatatype_ns)
#define RBTDB_RDATATYPE_SIGCNAME \ #define RBTDB_RDATATYPE_SIGCNAME \
RBTDB_RDATATYPE_VALUE(dns_rdatatype_sig, dns_rdatatype_cname) RBTDB_RDATATYPE_VALUE(dns_rdatatype_sig, dns_rdatatype_cname)
#define RBTDB_RDATATYPE_SIGDNAME \
RBTDB_RDATATYPE_VALUE(dns_rdatatype_sig, dns_rdatatype_dname)
#define RBTDB_RDATATYPE_NXDOMAIN \ #define RBTDB_RDATATYPE_NXDOMAIN \
RBTDB_RDATATYPE_VALUE(0, dns_rdatatype_any) RBTDB_RDATATYPE_VALUE(0, dns_rdatatype_any)
@@ -190,6 +192,7 @@ typedef struct {
isc_boolean_t wild; isc_boolean_t wild;
dns_rbtnode_t * zonecut; dns_rbtnode_t * zonecut;
rdatasetheader_t * zonecut_rdataset; rdatasetheader_t * zonecut_rdataset;
rdatasetheader_t * zonecut_sigrdataset;
dns_fixedname_t zonecut_name; dns_fixedname_t zonecut_name;
isc_stdtime_t now; isc_stdtime_t now;
} rbtdb_search_t; } rbtdb_search_t;
@@ -1010,6 +1013,7 @@ static isc_result_t
zone_zonecut_callback(dns_rbtnode_t *node, dns_name_t *name, void *arg) { zone_zonecut_callback(dns_rbtnode_t *node, dns_name_t *name, void *arg) {
rbtdb_search_t *search = arg; rbtdb_search_t *search = arg;
rdatasetheader_t *header, *header_next; rdatasetheader_t *header, *header_next;
rdatasetheader_t *dname_header, *sigdname_header, *ns_header;
rdatasetheader_t *found; rdatasetheader_t *found;
isc_result_t result; isc_result_t result;
dns_rbtnode_t *onode; dns_rbtnode_t *onode;
@@ -1031,10 +1035,14 @@ zone_zonecut_callback(dns_rbtnode_t *node, dns_name_t *name, void *arg) {
/* /*
* Look for an NS or DNAME rdataset active in our version. * Look for an NS or DNAME rdataset active in our version.
*/ */
ns_header = NULL;
dname_header = NULL;
sigdname_header = NULL;
for (header = node->data; header != NULL; header = header_next) { for (header = node->data; header != NULL; header = header_next) {
header_next = header->next; header_next = header->next;
if (header->type == dns_rdatatype_ns || if (header->type == dns_rdatatype_ns ||
header->type == dns_rdatatype_dname) { header->type == dns_rdatatype_dname ||
header->type == RBTDB_RDATATYPE_SIGDNAME) {
do { do {
if (header->serial <= search->serial && if (header->serial <= search->serial &&
!IGNORE(header)) { !IGNORE(header)) {
@@ -1042,24 +1050,20 @@ zone_zonecut_callback(dns_rbtnode_t *node, dns_name_t *name, void *arg) {
* Is this a "this rdataset doesn't * Is this a "this rdataset doesn't
* exist" record? * exist" record?
*/ */
if ((header->attributes & if (NONEXISTENT(header))
RDATASET_ATTR_NONEXISTENT) != 0)
header = NULL; header = NULL;
break; break;
} else } else
header = header->down; header = header->down;
} while (header != NULL); } while (header != NULL);
if (header != NULL) { if (header != NULL) {
if (header->type == dns_rdatatype_dname) { if (header->type == dns_rdatatype_dname)
/* dname_header = header;
* We don't need to keep looking for else if (header->type ==
* NS records, because the DNAME has RBTDB_RDATATYPE_SIGDNAME)
* precedence. sigdname_header = header;
*/ else if (node != onode ||
found = header; IS_STUB(search->rbtdb)) {
break;
} else if (node != onode ||
IS_STUB(search->rbtdb)) {
/* /*
* We've found an NS rdataset that * We've found an NS rdataset that
* isn't at the origin node. We check * isn't at the origin node. We check
@@ -1068,12 +1072,26 @@ zone_zonecut_callback(dns_rbtnode_t *node, dns_name_t *name, void *arg) {
* treat the zone top as if it were * treat the zone top as if it were
* a delegation. * a delegation.
*/ */
found = header; ns_header = header;
} }
} }
} }
} }
/*
* Did we find anything?
*/
if (dname_header != NULL) {
/*
* Note that DNAME has precedence over NS if both exist.
*/
found = dname_header;
search->zonecut_sigrdataset = sigdname_header;
} else if (ns_header != NULL) {
found = ns_header;
search->zonecut_sigrdataset = NULL;
}
if (found != NULL) { if (found != NULL) {
/* /*
* We increment the reference count on node to ensure that * We increment the reference count on node to ensure that
@@ -1164,7 +1182,8 @@ bind_rdataset(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
static inline isc_result_t static inline isc_result_t
setup_delegation(rbtdb_search_t *search, dns_dbnode_t **nodep, setup_delegation(rbtdb_search_t *search, dns_dbnode_t **nodep,
dns_name_t *foundname, dns_rdataset_t *rdataset) dns_name_t *foundname, dns_rdataset_t *rdataset,
dns_rdataset_t *sigrdataset)
{ {
isc_result_t result; isc_result_t result;
dns_name_t *zcname; dns_name_t *zcname;
@@ -1204,6 +1223,10 @@ setup_delegation(rbtdb_search_t *search, dns_dbnode_t **nodep,
LOCK(&(search->rbtdb->node_locks[node->locknum].lock)); LOCK(&(search->rbtdb->node_locks[node->locknum].lock));
bind_rdataset(search->rbtdb, node, search->zonecut_rdataset, bind_rdataset(search->rbtdb, node, search->zonecut_rdataset,
search->now, rdataset); search->now, rdataset);
if (sigrdataset != NULL && search->zonecut_sigrdataset != NULL)
bind_rdataset(search->rbtdb, node,
search->zonecut_sigrdataset,
search->now, sigrdataset);
UNLOCK(&(search->rbtdb->node_locks[node->locknum].lock)); UNLOCK(&(search->rbtdb->node_locks[node->locknum].lock));
} }
@@ -1611,7 +1634,7 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
partial_match: partial_match:
if (search.zonecut != NULL) { if (search.zonecut != NULL) {
result = setup_delegation(&search, nodep, foundname, result = setup_delegation(&search, nodep, foundname,
rdataset); rdataset, sigrdataset);
goto tree_exit; goto tree_exit;
} }
@@ -1850,7 +1873,7 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
*/ */
UNLOCK(&(search.rbtdb->node_locks[node->locknum].lock)); UNLOCK(&(search.rbtdb->node_locks[node->locknum].lock));
result = setup_delegation(&search, nodep, foundname, result = setup_delegation(&search, nodep, foundname,
rdataset); rdataset, sigrdataset);
goto tree_exit; goto tree_exit;
} else { } else {
/* /*
@@ -1921,7 +1944,7 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
!valid_glue(&search, foundname, type, node)) { !valid_glue(&search, foundname, type, node)) {
UNLOCK(&(search.rbtdb->node_locks[node->locknum].lock)); UNLOCK(&(search.rbtdb->node_locks[node->locknum].lock));
result = setup_delegation(&search, nodep, foundname, result = setup_delegation(&search, nodep, foundname,
rdataset); rdataset, sigrdataset);
goto tree_exit; goto tree_exit;
} }
} else { } else {
@@ -1999,6 +2022,7 @@ static isc_result_t
cache_zonecut_callback(dns_rbtnode_t *node, dns_name_t *name, void *arg) { cache_zonecut_callback(dns_rbtnode_t *node, dns_name_t *name, void *arg) {
rbtdb_search_t *search = arg; rbtdb_search_t *search = arg;
rdatasetheader_t *header, *header_prev, *header_next; rdatasetheader_t *header, *header_prev, *header_next;
rdatasetheader_t *dname_header, *sigdname_header;
isc_result_t result; isc_result_t result;
/* XXX comment */ /* XXX comment */
@@ -2013,8 +2037,10 @@ cache_zonecut_callback(dns_rbtnode_t *node, dns_name_t *name, void *arg) {
LOCK(&(search->rbtdb->node_locks[node->locknum].lock)); LOCK(&(search->rbtdb->node_locks[node->locknum].lock));
/* /*
* Look for a DNAME rdataset. * Look for a DNAME or SIG DNAME rdataset.
*/ */
dname_header = NULL;
sigdname_header = NULL;
header_prev = NULL; header_prev = NULL;
for (header = node->data; header != NULL; header = header_next) { for (header = node->data; header != NULL; header = header_next) {
header_next = header->next; header_next = header->next;
@@ -2042,21 +2068,28 @@ cache_zonecut_callback(dns_rbtnode_t *node, dns_name_t *name, void *arg) {
header_prev = header; header_prev = header;
} }
} else if (header->type == dns_rdatatype_dname && } else if (header->type == dns_rdatatype_dname &&
(header->attributes & RDATASET_ATTR_NONEXISTENT) == EXISTS(header)) {
0) dname_header = header;
break; header_prev = header;
else } else if (header->type == RBTDB_RDATATYPE_SIGDNAME &&
EXISTS(header)) {
sigdname_header = header;
header_prev = header;
} else
header_prev = header; header_prev = header;
} }
if (header != NULL) { if (dname_header != NULL &&
(dname_header->trust != dns_trust_pending ||
(search->options & DNS_DBFIND_PENDINGOK) != 0)) {
/* /*
* We increment the reference count on node to ensure that * We increment the reference count on node to ensure that
* search->zonecut_rdataset will still be valid later. * search->zonecut_rdataset will still be valid later.
*/ */
new_reference(search->rbtdb, node); new_reference(search->rbtdb, node);
search->zonecut = node; search->zonecut = node;
search->zonecut_rdataset = header; search->zonecut_rdataset = dname_header;
search->zonecut_sigrdataset = sigdname_header;
search->need_cleanup = ISC_TRUE; search->need_cleanup = ISC_TRUE;
result = DNS_R_PARTIALMATCH; result = DNS_R_PARTIALMATCH;
} else } else
@@ -2252,7 +2285,7 @@ cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
if (result == DNS_R_PARTIALMATCH) { if (result == DNS_R_PARTIALMATCH) {
if (search.zonecut != NULL) { if (search.zonecut != NULL) {
result = setup_delegation(&search, nodep, foundname, result = setup_delegation(&search, nodep, foundname,
rdataset); rdataset, sigrdataset);
goto tree_exit; goto tree_exit;
} else { } else {
find_ns: find_ns: