Commit 538f4a22 authored by Mark Andrews's avatar Mark Andrews
Browse files

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 <marka@isc.org>
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
parent 600cfd56
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
......
......@@ -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))
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment