diff --git a/lib/dns/zone.c b/lib/dns/zone.c index d9e95f957b..aeb58365f6 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -15498,21 +15498,93 @@ restore_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version, return (result); } +static isc_result_t +copy_non_dnssec_records(dns_zone_t *zone, dns_db_t *db, dns_db_t *version, + dns_db_t *rawdb, dns_dbiterator_t *dbiterator, + unsigned int *oldserial) +{ + dns_dbnode_t *rawnode = NULL, *node = NULL; + dns_fixedname_t fixed; + dns_name_t *name = dns_fixedname_initname(&fixed); + dns_rdataset_t rdataset; + dns_rdatasetiter_t *rdsit = NULL; + isc_result_t result; + + result = dns_dbiterator_current(dbiterator, &rawnode, name); + if (result != ISC_R_SUCCESS) { + return (ISC_R_SUCCESS); + } + + result = dns_db_findnode(db, name, true, &node); + if (result != ISC_R_SUCCESS) { + goto cleanup; + } + + result = dns_db_allrdatasets(rawdb, rawnode, NULL, 0, &rdsit); + if (result != ISC_R_SUCCESS) { + goto cleanup; + } + + dns_rdataset_init(&rdataset); + + for (result = dns_rdatasetiter_first(rdsit); + result == ISC_R_SUCCESS; + result = dns_rdatasetiter_next(rdsit)) + { + dns_rdatasetiter_current(rdsit, &rdataset); + if (rdataset.type == dns_rdatatype_nsec || + rdataset.type == dns_rdatatype_rrsig || + rdataset.type == dns_rdatatype_nsec3 || + rdataset.type == dns_rdatatype_dnskey || + rdataset.type == dns_rdatatype_nsec3param) { + /* + * Allow DNSSEC records with dnssec-policy. + * WMM: Perhaps add config option for it. + */ + if (dns_zone_getkasp(zone) == NULL) { + dns_rdataset_disassociate(&rdataset); + continue; + } + } + if (rdataset.type == dns_rdatatype_soa && oldserial != NULL) { + result = checkandaddsoa(db, node, version, + &rdataset, *oldserial); + } else { + result = dns_db_addrdataset(db, node, version, + 0, &rdataset, 0, + NULL); + } + dns_rdataset_disassociate(&rdataset); + if (result != ISC_R_SUCCESS) { + goto cleanup; + } + } + if (result == ISC_R_NOMORE) { + result = ISC_R_SUCCESS; + } + + cleanup: + if (rdsit != NULL) { + dns_rdatasetiter_destroy(&rdsit); + } + if (rawnode) { + dns_db_detachnode(rawdb, &rawnode); + } + if (node) { + dns_db_detachnode(db, &node); + } + return (result); +} + static void receive_secure_db(isc_task_t *task, isc_event_t *event) { isc_result_t result; dns_zone_t *zone; dns_db_t *rawdb, *db = NULL; - dns_dbnode_t *rawnode = NULL, *node = NULL; - dns_fixedname_t fname; - dns_name_t *name; dns_dbiterator_t *dbiterator = NULL; - dns_rdatasetiter_t *rdsit = NULL; - dns_rdataset_t rdataset; dns_dbversion_t *version = NULL; isc_time_t loadtime; - unsigned int oldserial = 0; - bool have_oldserial = false; + unsigned int oldserial = 0, *oldserialp = NULL; nsec3paramlist_t nsec3list; isc_event_t *setnsec3param_event; dns_zone_t *dummy; @@ -15525,9 +15597,6 @@ receive_secure_db(isc_task_t *task, isc_event_t *event) { rawdb = ((struct secure_event *)event)->db; isc_event_free(&event); - name = dns_fixedname_initname(&fname); - dns_rdataset_init(&rdataset); - LOCK_ZONE(zone); if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || !inline_secure(zone)) { result = ISC_R_SHUTTINGDOWN; @@ -15538,8 +15607,9 @@ receive_secure_db(isc_task_t *task, isc_event_t *event) { ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); if (zone->db != NULL) { result = dns_db_getsoaserial(zone->db, NULL, &oldserial); - if (result == ISC_R_SUCCESS) - have_oldserial = true; + if (result == ISC_R_SUCCESS) { + oldserialp = &oldserial; + } /* * assemble nsec3parameters from the old zone, and set a flag @@ -15556,8 +15626,9 @@ receive_secure_db(isc_task_t *task, isc_event_t *event) { result = dns_db_create(zone->mctx, zone->db_argv[0], &zone->origin, dns_dbtype_zone, zone->rdclass, zone->db_argc - 1, zone->db_argv + 1, &db); - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { goto failure; + } result = dns_db_setgluecachestats(db, zone->gluecachestats); if (result != ISC_R_SUCCESS && result != ISC_R_NOTIMPLEMENTED) { @@ -15565,62 +15636,28 @@ receive_secure_db(isc_task_t *task, isc_event_t *event) { } result = dns_db_newversion(db, &version); - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { goto failure; + } result = dns_db_createiterator(rawdb, 0, &dbiterator); - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { goto failure; + } for (result = dns_dbiterator_first(dbiterator); result == ISC_R_SUCCESS; - result = dns_dbiterator_next(dbiterator)) { - result = dns_dbiterator_current(dbiterator, &rawnode, name); - if (result != ISC_R_SUCCESS) - continue; - - result = dns_db_findnode(db, name, true, &node); - if (result != ISC_R_SUCCESS) + result = dns_dbiterator_next(dbiterator)) + { + result = copy_non_dnssec_records(zone, db, version, rawdb, + dbiterator, oldserialp); + if (result != ISC_R_SUCCESS) { goto failure; - - result = dns_db_allrdatasets(rawdb, rawnode, NULL, 0, &rdsit); - if (result != ISC_R_SUCCESS) - goto failure; - - for (result = dns_rdatasetiter_first(rdsit); - result == ISC_R_SUCCESS; - result = dns_rdatasetiter_next(rdsit)) { - dns_rdatasetiter_current(rdsit, &rdataset); - if (rdataset.type == dns_rdatatype_nsec || - rdataset.type == dns_rdatatype_rrsig || - rdataset.type == dns_rdatatype_nsec3 || - rdataset.type == dns_rdatatype_dnskey || - rdataset.type == dns_rdatatype_nsec3param) { - /* - * Allow DNSSEC records with dnssec-policy. - * WMM: Perhaps add config option for it. - */ - if (dns_zone_getkasp(zone) == NULL) { - dns_rdataset_disassociate(&rdataset); - continue; - } - } - if (rdataset.type == dns_rdatatype_soa && - have_oldserial) { - result = checkandaddsoa(db, node, version, - &rdataset, oldserial); - } else - result = dns_db_addrdataset(db, node, version, - 0, &rdataset, 0, - NULL); - if (result != ISC_R_SUCCESS) - goto failure; - - dns_rdataset_disassociate(&rdataset); } - dns_rdatasetiter_destroy(&rdsit); - dns_db_detachnode(rawdb, &rawnode); - dns_db_detachnode(db, &node); + } + dns_dbiterator_destroy(&dbiterator); + if (result != ISC_R_NOMORE) { + goto failure; } /* @@ -15660,9 +15697,13 @@ receive_secure_db(isc_task_t *task, isc_event_t *event) { failure: UNLOCK_ZONE(zone); - if (result != ISC_R_SUCCESS) + if (dbiterator != NULL) { + dns_dbiterator_destroy(&dbiterator); + } + if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "receive_secure_db: %s", dns_result_totext(result)); + } while (!ISC_LIST_EMPTY(nsec3list)) { nsec3param_t *nsec3p; @@ -15670,20 +15711,13 @@ receive_secure_db(isc_task_t *task, isc_event_t *event) { ISC_LIST_UNLINK(nsec3list, nsec3p, link); isc_mem_put(zone->mctx, nsec3p, sizeof(nsec3param_t)); } - if (dns_rdataset_isassociated(&rdataset)) - dns_rdataset_disassociate(&rdataset); if (db != NULL) { - if (node != NULL) - dns_db_detachnode(db, &node); - if (version != NULL) + if (version != NULL) { dns_db_closeversion(db, &version, false); + } dns_db_detach(&db); } - if (rawnode != NULL) - dns_db_detachnode(rawdb, &rawnode); dns_db_detach(&rawdb); - if (dbiterator != NULL) - dns_dbiterator_destroy(&dbiterator); dns_zone_idetach(&zone); INSIST(version == NULL);