From: Mark Andrews Date: Fri, 30 Nov 2012 00:39:37 +0000 (+1100) Subject: 3429. [bug] dns_zone_getserial2 could a return success without X-Git-Tag: v9.10.0a1~682^2~6 X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=538f4a22b1cbde59a9e53fef51583904a7f7393f;p=thirdparty%2Fbind9.git 3429. [bug] dns_zone_getserial2 could a return success without returning a valid serial. [RT #32007] Squashed commit of the following: commit 0057f4b6e843c3998b987dbc7f32ceeee8afc150 Author: Mark Andrews Date: Fri Nov 30 08:13:15 2012 +1100 zone_get_from_db could return success without setting return valuses; serial is only valid if soacount is none zero --- diff --git a/CHANGES b/CHANGES index 233e26c23fe..ea87ecbe078 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +3429. [bug] dns_zone_getserial2 could a return success without + returning a valid serial. [RT #32007] + 3428. [cleanup] dig: Add timezone to date output. [RT #2269] 3427. [bug] dig +trace incorrectly displayed name server diff --git a/lib/dns/zone.c b/lib/dns/zone.c index c59501346c0..58fa171a14a 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -1155,6 +1155,7 @@ dns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype) { isc_result_t dns_zone_getserial2(dns_zone_t *zone, isc_uint32_t *serialp) { isc_result_t result; + unsigned int soacount; REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(serialp != NULL); @@ -1162,8 +1163,11 @@ dns_zone_getserial2(dns_zone_t *zone, isc_uint32_t *serialp) { LOCK_ZONE(zone); ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); if (zone->db != NULL) { - result = zone_get_from_db(zone, zone->db, NULL, NULL, serialp, - NULL, NULL, NULL, NULL, NULL); + result = zone_get_from_db(zone, zone->db, NULL, &soacount, + serialp, NULL, NULL, NULL, NULL, + NULL); + if (result == ISC_R_SUCCESS && soacount == 0) + result = ISC_R_FAILURE; } else result = DNS_R_NOTLOADED; ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); @@ -1915,14 +1919,15 @@ zone_gotreadhandle(isc_task_t *task, isc_event_t *event) { static void get_raw_serial(dns_zone_t *raw, dns_masterrawheader_t *rawdata) { isc_result_t result; + unsigned int soacount; LOCK(&raw->lock); if (raw->db != NULL) { - result = zone_get_from_db(raw, raw->db, NULL, NULL, + result = zone_get_from_db(raw, raw->db, NULL, &soacount, &rawdata->sourceserial, NULL, NULL, NULL, NULL, NULL); - if (result == ISC_R_SUCCESS) + if (result == ISC_R_SUCCESS && soacount > 0U) rawdata->flags |= DNS_MASTERRAW_SOURCESERIALSET; } UNLOCK(&raw->lock); @@ -3669,10 +3674,12 @@ maybe_send_secure(dns_zone_t *zone) { if (zone->raw->db != NULL) { if (zone->db != NULL) { isc_uint32_t serial; + unsigned int soacount; + result = zone_get_from_db(zone->raw, zone->raw->db, - NULL, NULL, &serial, NULL, + NULL, &soacount, &serial, NULL, NULL, NULL, NULL, NULL); - if (result == ISC_R_SUCCESS) + if (result == ISC_R_SUCCESS && soacount > 0U) zone_send_secureserial(zone->raw, ISC_TRUE, serial); } else zone_send_securedb(zone->raw, ISC_TRUE, zone->raw->db); @@ -3914,14 +3921,18 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, } if (zone->db != NULL) { + unsigned int oldsoacount; + /* * This is checked in zone_replacedb() for slave zones * as they don't reload from disk. */ - result = zone_get_from_db(zone, zone->db, NULL, NULL, - &oldserial, NULL, NULL, NULL, - NULL, NULL); + result = zone_get_from_db(zone, zone->db, NULL, + &oldsoacount, &oldserial, + NULL, NULL, NULL, NULL, + NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); + RUNTIME_CHECK(soacount > 0U); if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) && !isc_serial_gt(serial, oldserial)) { isc_uint32_t serialmin, serialmax; @@ -4364,6 +4375,19 @@ zone_load_soa_rr(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, *expire = soa.expire; if (minimum != NULL) *minimum = soa.minimum; + } else { + if (soacount != NULL) + *soacount = 0; + if (serial != NULL) + *serial = 0; + if (refresh != NULL) + *refresh = 0; + if (retry != NULL) + *retry = 0; + if (expire != NULL) + *expire = 0; + if (minimum != NULL) + *minimum = 0; } result = ISC_R_SUCCESS; @@ -8727,16 +8751,18 @@ dns_zone_markdirty(dns_zone_t *zone) { LOCK_ZONE(zone); if (zone->type == dns_zone_master) { if (inline_raw(zone)) { + unsigned int soacount; + ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); if (zone->db != NULL) { result = zone_get_from_db(zone, zone->db, NULL, - NULL, &serial, NULL, + &soacount, &serial, NULL, NULL, NULL, - NULL); + NULL, NULL); } else result = DNS_R_NOTLOADED; ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); - if (result == ISC_R_SUCCESS) + if (result == ISC_R_SUCCESS && soacount > 0U) zone_send_secureserial(zone, ISC_FALSE, serial); } @@ -9950,7 +9976,7 @@ stub_callback(isc_task_t *task, isc_event_t *event) { isc_time_t now; isc_boolean_t exiting = ISC_FALSE; isc_interval_t i; - unsigned int j; + unsigned int j, soacount; stub = revent->ev_arg; INSIST(DNS_STUB_VALID(stub)); @@ -10093,9 +10119,9 @@ stub_callback(isc_task_t *task, isc_event_t *event) { ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); if (zone->db == NULL) zone_attachdb(zone, stub->db); - result = zone_get_from_db(zone, zone->db, NULL, NULL, NULL, &refresh, - &retry, &expire, NULL, NULL); - if (result == ISC_R_SUCCESS) { + result = zone_get_from_db(zone, zone->db, NULL, &soacount, NULL, + &refresh, &retry, &expire, NULL, NULL); + if (result == ISC_R_SUCCESS && soacount > 0U) { zone->refresh = RANGE(refresh, zone->minrefresh, zone->maxrefresh); zone->retry = RANGE(retry, zone->minretry, zone->maxretry); @@ -10434,10 +10460,12 @@ refresh_callback(isc_task_t *task, isc_event_t *event) { serial = soa.serial; if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { - result = zone_get_from_db(zone, zone->db, NULL, NULL, + unsigned int soacount; + result = zone_get_from_db(zone, zone->db, NULL, &soacount, &oldserial, NULL, NULL, NULL, NULL, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); + RUNTIME_CHECK(soacount > 0U); zone_debuglog(zone, me, 1, "serial: new %u, old %u", serial, oldserial); } else @@ -11690,6 +11718,7 @@ dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from, result = dns_rdataset_first(rdataset); if (result == ISC_R_SUCCESS) { isc_uint32_t serial = 0, oldserial; + unsigned int soacount; dns_rdataset_current(rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &soa, NULL); @@ -11699,10 +11728,11 @@ dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from, * The following should safely be performed without DB * lock and succeed in this context. */ - result = zone_get_from_db(zone, zone->db, NULL, NULL, - &oldserial, NULL, NULL, NULL, - NULL, NULL); + result = zone_get_from_db(zone, zone->db, NULL, + &soacount, &oldserial, NULL, + NULL, NULL, NULL, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); + RUNTIME_CHECK(soacount > 0U); if (isc_serial_le(serial, oldserial)) { dns_zone_log(zone, ISC_LOG_INFO, @@ -12964,6 +12994,7 @@ zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) { !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) { isc_uint32_t serial, oldserial; + unsigned int soacount; dns_zone_log(zone, ISC_LOG_DEBUG(3), "generating diffs"); @@ -12978,10 +13009,11 @@ zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) { /* * This is checked in zone_postload() for master zones. */ - result = zone_get_from_db(zone, zone->db, NULL, NULL, + result = zone_get_from_db(zone, zone->db, NULL, &soacount, &oldserial, NULL, NULL, NULL, NULL, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); + RUNTIME_CHECK(soacount > 0U); if ((zone->type == dns_zone_slave || (zone->type == dns_zone_redirect && zone->masters != NULL))