From d9c4f954a1ddf7fcd5bf86bb7bbc12f669f81507 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Thu, 5 Jan 2006 01:09:14 +0000 Subject: [PATCH] 1958. [bug] Named failed to update the zone's secure state until the zone was reloaded. [RT #15412] --- CHANGES | 3 ++ lib/dns/rbtdb.c | 112 +++++++++++++++++++++++++++++------------------- 2 files changed, 72 insertions(+), 43 deletions(-) diff --git a/CHANGES b/CHANGES index bb7ae23678..34b4156fc6 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +1958. [bug] Named failed to update the zone's secure state + until the zone was reloaded. [RT #15412] + 1957. [bug] Dig mishandled responses to class ANY queries. [RT #15402] diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c index c307e9013c..e364d25a60 100644 --- a/lib/dns/rbtdb.c +++ b/lib/dns/rbtdb.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rbtdb.c,v 1.223 2005/10/14 01:14:08 marka Exp $ */ +/* $Id: rbtdb.c,v 1.224 2006/01/05 01:09:14 marka Exp $ */ /*! \file */ @@ -1300,6 +1300,47 @@ cleanup_nondirty(rbtdb_version_t *version, rbtdb_changedlist_t *cleanup_list) { } } +static isc_boolean_t +iszonesecure(dns_db_t *db, dns_dbnode_t *origin) { + dns_rdataset_t keyset; + dns_rdataset_t nsecset, signsecset; + isc_boolean_t haszonekey = ISC_FALSE; + isc_boolean_t hasnsec = ISC_FALSE; + isc_result_t result; + + dns_rdataset_init(&keyset); + result = dns_db_findrdataset(db, origin, NULL, dns_rdatatype_dnskey, 0, + 0, &keyset, NULL); + if (result == ISC_R_SUCCESS) { + dns_rdata_t keyrdata = DNS_RDATA_INIT; + result = dns_rdataset_first(&keyset); + while (result == ISC_R_SUCCESS) { + dns_rdataset_current(&keyset, &keyrdata); + if (dns_zonekey_iszonekey(&keyrdata)) { + haszonekey = ISC_TRUE; + break; + } + result = dns_rdataset_next(&keyset); + } + dns_rdataset_disassociate(&keyset); + } + if (!haszonekey) + return (ISC_FALSE); + + dns_rdataset_init(&nsecset); + dns_rdataset_init(&signsecset); + result = dns_db_findrdataset(db, origin, NULL, dns_rdatatype_nsec, 0, + 0, &nsecset, &signsecset); + if (result == ISC_R_SUCCESS) { + if (dns_rdataset_isassociated(&signsecset)) { + hasnsec = ISC_TRUE; + dns_rdataset_disassociate(&signsecset); + } + dns_rdataset_disassociate(&nsecset); + } + return (hasnsec); +} + static void closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) { dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; @@ -1458,6 +1499,12 @@ closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) { least_serial = rbtdb->least_serial; RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write); + /* + * Update the zone's secure status. + */ + if (version->writer && commit && !IS_CACHE(rbtdb)) + rbtdb->secure = iszonesecure(db, rbtdb->origin_node); + if (cleanup_version != NULL) { INSIST(EMPTY(cleanup_version->changed_list)); isc_mem_put(rbtdb->common.mctx, cleanup_version, @@ -4798,6 +4845,13 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, if (delegating) RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_write); + /* + * Update the zone's secure status. If version is non-NULL + * this is defered until closeversion() is called. + */ + if (result == ISC_R_SUCCESS && version == NULL && !IS_CACHE(rbtdb)) + rbtdb->secure = iszonesecure(db, rbtdb->origin_node); + return (result); } @@ -4954,6 +5008,13 @@ subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, isc_rwlocktype_write); + /* + * Update the zone's secure status. If version is non-NULL + * this is defered until closeversion() is called. + */ + if (result == ISC_R_SUCCESS && version == NULL && !IS_CACHE(rbtdb)) + rbtdb->secure = iszonesecure(db, rbtdb->origin_node); + return (result); } @@ -4999,6 +5060,13 @@ deleterdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, isc_rwlocktype_write); + /* + * Update the zone's secure status. If version is non-NULL + * this is defered until closeversion() is called. + */ + if (result == ISC_R_SUCCESS && version == NULL && !IS_CACHE(rbtdb)) + rbtdb->secure = iszonesecure(db, rbtdb->origin_node); + return (result); } @@ -5115,48 +5183,6 @@ beginload(dns_db_t *db, dns_addrdatasetfunc_t *addp, dns_dbload_t **dbloadp) { return (ISC_R_SUCCESS); } -static isc_boolean_t -iszonesecure(dns_db_t *db, dns_dbnode_t *origin) { - dns_rdataset_t keyset; - dns_rdataset_t nsecset, signsecset; - isc_boolean_t haszonekey = ISC_FALSE; - isc_boolean_t hasnsec = ISC_FALSE; - isc_result_t result; - - dns_rdataset_init(&keyset); - result = dns_db_findrdataset(db, origin, NULL, dns_rdatatype_dnskey, 0, - 0, &keyset, NULL); - if (result == ISC_R_SUCCESS) { - dns_rdata_t keyrdata = DNS_RDATA_INIT; - result = dns_rdataset_first(&keyset); - while (result == ISC_R_SUCCESS) { - dns_rdataset_current(&keyset, &keyrdata); - if (dns_zonekey_iszonekey(&keyrdata)) { - haszonekey = ISC_TRUE; - break; - } - result = dns_rdataset_next(&keyset); - } - dns_rdataset_disassociate(&keyset); - } - if (!haszonekey) - return (ISC_FALSE); - - dns_rdataset_init(&nsecset); - dns_rdataset_init(&signsecset); - result = dns_db_findrdataset(db, origin, NULL, dns_rdatatype_nsec, 0, - 0, &nsecset, &signsecset); - if (result == ISC_R_SUCCESS) { - if (dns_rdataset_isassociated(&signsecset)) { - hasnsec = ISC_TRUE; - dns_rdataset_disassociate(&signsecset); - } - dns_rdataset_disassociate(&nsecset); - } - return (hasnsec); - -} - static isc_result_t endload(dns_db_t *db, dns_dbload_t **dbloadp) { rbtdb_load_t *loadctx;