diff --git a/CHANGES b/CHANGES index 1feb72cc31..27cb1bcf00 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,5 @@ +3289. [bug] 'rndc retransfer' failed for inline zones. [RT #28036] + 3288. [bug] dlz_destroy() function wasn't correctly registered by the DLZ dlopen driver. [RT #28056] diff --git a/bin/named/server.c b/bin/named/server.c index a332a3b713..6921feb5c9 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: server.c,v 1.646 2012/02/22 00:37:53 each Exp $ */ +/* $Id: server.c,v 1.647 2012/02/23 06:53:15 marka Exp $ */ /*! \file */ @@ -5992,6 +5992,7 @@ isc_result_t ns_server_retransfercommand(ns_server_t *server, char *args) { isc_result_t result; dns_zone_t *zone = NULL; + dns_zone_t *raw = NULL; dns_zonetype_t type; result = zone_from_args(server, args, NULL, &zone, NULL, ISC_TRUE); @@ -5999,6 +6000,12 @@ ns_server_retransfercommand(ns_server_t *server, char *args) { return (result); if (zone == NULL) return (ISC_R_UNEXPECTEDEND); + dns_zone_getraw(zone, &raw); + if (raw != NULL) { + dns_zone_detach(&zone); + dns_zone_attach(raw, &zone); + dns_zone_detach(&raw); + } type = dns_zone_gettype(zone); if (type == dns_zone_slave || type == dns_zone_stub) dns_zone_forcereload(zone); diff --git a/bin/named/zoneconf.c b/bin/named/zoneconf.c index fad1351217..748d114229 100644 --- a/bin/named/zoneconf.c +++ b/bin/named/zoneconf.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: zoneconf.c,v 1.188 2012/01/31 23:47:31 tbox Exp $ */ +/* $Id: zoneconf.c,v 1.189 2012/02/23 06:53:15 marka Exp $ */ /*% */ @@ -1134,7 +1134,7 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig, dns_zone_setoption(raw, DNS_ZONEOPT_IXFRFROMDIFFS, ISC_TRUE); dns_zone_setoption(zone, DNS_ZONEOPT_IXFRFROMDIFFS, - ISC_FALSE); + ISC_TRUE); } else dns_zone_setoption(zone, DNS_ZONEOPT_IXFRFROMDIFFS, ixfrdiff); diff --git a/bin/tests/system/inline/clean.sh b/bin/tests/system/inline/clean.sh index 1f4a85cad0..707ab31e7c 100644 --- a/bin/tests/system/inline/clean.sh +++ b/bin/tests/system/inline/clean.sh @@ -12,7 +12,7 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: clean.sh,v 1.12 2012/01/17 08:26:03 marka Exp $ +# $Id: clean.sh,v 1.13 2012/02/23 06:53:15 marka Exp $ rm -f */named.memstats rm -f */named.run @@ -24,6 +24,9 @@ rm -f ns1/root.db rm -f ns1/root.db.signed rm -f ns2/bits.db rm -f ns2/bits.db.jnl +rm -f ns1/signer.out +rm -f ns2/retransfer.db +rm -f ns2/retransfer.db.jnl rm -f ns3/K* rm -f ns3/bits.bk rm -f ns3/bits.bk.jnl @@ -49,6 +52,10 @@ rm -f ns3/expired.db rm -f ns3/expired.db.jnl rm -f ns3/expired.db.signed rm -f ns3/expired.db.signed.jnl +rm -f ns3/retransfer.bk +rm -f ns3/retransfer.bk.jnl +rm -f ns3/retransfer.bk.signed +rm -f ns3/retransfer.bk.signed.jnl rm -f ns4/K* rm -f ns4/noixfr.db rm -f ns4/noixfr.db.jnl diff --git a/bin/tests/system/inline/ns1/root.db.in b/bin/tests/system/inline/ns1/root.db.in index b91c6bd647..6a65dcf36f 100644 --- a/bin/tests/system/inline/ns1/root.db.in +++ b/bin/tests/system/inline/ns1/root.db.in @@ -12,7 +12,7 @@ ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ; PERFORMANCE OF THIS SOFTWARE. -; $Id: root.db.in,v 1.7 2012/01/10 23:46:58 tbox Exp $ +; $Id: root.db.in,v 1.8 2012/02/23 06:53:15 marka Exp $ $TTL 300 . IN SOA gson.nominum.com. a.root.servers.nil. ( @@ -44,3 +44,6 @@ ns3.updated. A 10.53.0.3 expired. NS ns3.expired. ns3.expired. A 10.53.0.3 + +retransfer. NS ns3.retransfer. +ns3.retransfer. A 10.53.0.3 diff --git a/bin/tests/system/inline/ns1/sign.sh b/bin/tests/system/inline/ns1/sign.sh index b2688ea2b8..d09b9c203c 100644 --- a/bin/tests/system/inline/ns1/sign.sh +++ b/bin/tests/system/inline/ns1/sign.sh @@ -14,7 +14,7 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: sign.sh,v 1.3 2011/12/22 07:32:40 each Exp $ +# $Id: sign.sh,v 1.4 2012/02/23 06:53:15 marka Exp $ SYSTEMTESTTOP=../.. . $SYSTEMTESTTOP/conf.sh @@ -26,7 +26,8 @@ rm -f K.+*+*.key rm -f K.+*+*.private keyname=`$KEYGEN -q -r $RANDFILE -a RSASHA1 -b 768 -n zone $zone` keyname=`$KEYGEN -q -r $RANDFILE -a RSASHA1 -b 1024 -n zone -f KSK $zone` -$SIGNER -S -x -T 1200 -o ${zone} root.db > /dev/null 2>&1 +$SIGNER -S -x -T 1200 -o ${zone} root.db > signer.out 2>&1 +[ $? = 0 ] || cat signer.out cat ${keyname}.key | grep -v '^; ' | $PERL -n -e ' local ($dn, $class, $type, $flags, $proto, $alg, @rest) = split; diff --git a/bin/tests/system/inline/ns2/named.conf b/bin/tests/system/inline/ns2/named.conf index 2392a64718..68db53f881 100644 --- a/bin/tests/system/inline/ns2/named.conf +++ b/bin/tests/system/inline/ns2/named.conf @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: named.conf,v 1.2 2011/08/30 23:46:52 tbox Exp $ */ +/* $Id: named.conf,v 1.3 2012/02/23 06:53:15 marka Exp $ */ // NS2 @@ -38,3 +38,10 @@ zone "bits" { file "bits.db"; allow-update { any; }; }; + +zone "retransfer" { + type master; + file "retransfer.db"; + allow-update { any; }; + notify no; +}; diff --git a/bin/tests/system/inline/ns3/named.conf b/bin/tests/system/inline/ns3/named.conf index f0ac5950ce..ebfb8d9b9a 100644 --- a/bin/tests/system/inline/ns3/named.conf +++ b/bin/tests/system/inline/ns3/named.conf @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: named.conf,v 1.7 2012/01/10 23:46:58 tbox Exp $ */ +/* $Id: named.conf,v 1.8 2012/02/23 06:53:15 marka Exp $ */ // NS3 @@ -86,3 +86,11 @@ zone "expired" { allow-update { any; }; file "expired.db"; }; + +zone "retransfer" { + type slave; + masters { 10.53.0.2; }; + inline-signing yes; + auto-dnssec maintain; + file "retransfer.bk"; +}; diff --git a/bin/tests/system/inline/ns3/sign.sh b/bin/tests/system/inline/ns3/sign.sh index 58eb9aca79..ed9123fd76 100644 --- a/bin/tests/system/inline/ns3/sign.sh +++ b/bin/tests/system/inline/ns3/sign.sh @@ -14,7 +14,7 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: sign.sh,v 1.7 2012/01/10 23:46:58 tbox Exp $ +# $Id: sign.sh,v 1.8 2012/02/23 06:53:15 marka Exp $ SYSTEMTESTTOP=../.. . $SYSTEMTESTTOP/conf.sh @@ -66,3 +66,10 @@ keyname=`$KEYGEN -q -r $RANDFILE -a RSASHA1 -b 768 -n zone $zone` keyname=`$KEYGEN -q -r $RANDFILE -a RSASHA1 -b 1024 -n zone -f KSK $zone` $DSFROMKEY -T 1200 $keyname >> ../ns1/root.db $SIGNER -PS -s 20100101000000 -e 20110101000000 -O raw -L 2000042407 -o ${zone} ${zone}.db > /dev/null 2>&1 + +zone=retransfer +rm -f K${zone}.+*+*.key +rm -f K${zone}.+*+*.private +keyname=`$KEYGEN -q -r $RANDFILE -a RSASHA1 -b 768 -n zone $zone` +keyname=`$KEYGEN -q -r $RANDFILE -a RSASHA1 -b 1024 -n zone -f KSK $zone` +$DSFROMKEY -T 1200 $keyname >> ../ns1/root.db diff --git a/bin/tests/system/inline/setup.sh b/bin/tests/system/inline/setup.sh index cc55dbcb5b..d18ad651b2 100644 --- a/bin/tests/system/inline/setup.sh +++ b/bin/tests/system/inline/setup.sh @@ -12,7 +12,7 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: setup.sh,v 1.10 2012/01/10 23:46:58 tbox Exp $ +# $Id: setup.sh,v 1.11 2012/02/23 06:53:15 marka Exp $ sh clean.sh @@ -21,6 +21,7 @@ rm -f ns1/root.db.signed touch ns2/trusted.conf cp ns2/bits.db.in ns2/bits.db +cp ns2/bits.db.in ns2/retransfer.db rm -f ns2/bits.db.jnl cp ns3/master.db.in ns3/master.db diff --git a/bin/tests/system/inline/tests.sh b/bin/tests/system/inline/tests.sh index 736b938901..4870097577 100644 --- a/bin/tests/system/inline/tests.sh +++ b/bin/tests/system/inline/tests.sh @@ -14,7 +14,7 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: tests.sh,v 1.17 2012/01/31 01:13:09 each Exp $ +# $Id: tests.sh,v 1.18 2012/02/23 06:53:15 marka Exp $ SYSTEMTESTTOP=.. . $SYSTEMTESTTOP/conf.sh @@ -693,4 +693,53 @@ $RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 sync -clean dynamic 2>&1 || re if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` +$NSUPDATE << EOF +zone retransfer +server 10.53.0.2 5300 +update add added.retransfer 0 A 1.2.3.4 +send + +EOF + +n=`expr $n + 1` +echo "I:checking that the retransfer record is added on the hidden master ($n)" +ret=0 +$DIG $DIGOPTS @10.53.0.2 -p 5300 added.retransfer A > dig.out.ns2.test$n +grep "status: NOERROR" dig.out.ns2.test$n > /dev/null || ret=1 +grep "ANSWER: 1," dig.out.ns2.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I:checking that the change has not been transfered due to notify ($n)" +ret=0 +for i in 0 1 2 3 4 5 6 7 8 9 +do + ans=0 + $DIG $DIGOPTS @10.53.0.3 -p 5300 added.retransfer A > dig.out.ns3.test$n + grep "status: NOERROR" dig.out.ns3.test$n > /dev/null || ans=1 + [ $ans = 0 ] && break + sleep 1 +done +if [ $ans != 1 ]; then echo "I:failed"; ret=1; fi +status=`expr $status + $ret` +n=`expr $n + 1` + +echo "I:check rndc retransfer of a inline slave zone works ($n)" +ret=0 +$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 retransfer retransfer 2>&1 || ret=1 +for i in 0 1 2 3 4 5 6 7 8 9 +do + ans=0 + $DIG $DIGOPTS @10.53.0.3 -p 5300 added.retransfer A > dig.out.ns3.test$n + grep "status: NOERROR" dig.out.ns3.test$n > /dev/null || ans=1 + grep "ANSWER: 2," dig.out.ns3.test$n > /dev/null || ans=1 + [ $ans = 0 ] && break + sleep 1 +done +[ $ans = 1 ] && ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + exit $status diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 8064316fcb..938b1808d4 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: zone.c,v 1.673 2012/02/22 00:37:54 each Exp $ */ +/* $Id: zone.c,v 1.674 2012/02/23 06:53:15 marka Exp $ */ /*! \file */ @@ -12416,6 +12416,14 @@ receive_secure_serial(isc_task_t *task, isc_event_t *event) { UNUSED(task); + /* + * zone->db may be NULL if the load from disk failed. + */ + if (zone->db == NULL) { + result = ISC_R_FAILURE; + goto failure; + } + /* * We first attempt to sync the raw zone to the secure zone * by using the raw zone's journal, applying all the deltas @@ -12566,6 +12574,56 @@ zone_send_secureserial(dns_zone_t *zone, isc_boolean_t locked, return (ISC_R_SUCCESS); } +static isc_result_t +checkandaddsoa(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, + dns_rdataset_t *rdataset, isc_uint32_t oldserial) +{ + dns_rdata_soa_t soa; + dns_rdata_t rdata = DNS_RDATA_INIT; + dns_rdatalist_t temprdatalist; + dns_rdataset_t temprdataset; + isc_buffer_t b; + isc_result_t result; + unsigned char buf[DNS_SOA_BUFFERSIZE]; + + result = dns_rdataset_first(rdataset); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + dns_rdataset_current(rdataset, &rdata); + dns_rdata_tostruct(&rdata, &soa, NULL); + + if (isc_serial_gt(soa.serial, oldserial)) + return (dns_db_addrdataset(db, node, version, 0, rdataset, 0, + NULL)); + /* + * Always bump the serial. + */ + oldserial++; + if (oldserial == 0) + oldserial++; + soa.serial = oldserial; + + /* + * Construct a replacement rdataset. + */ + dns_rdata_reset(&rdata); + isc_buffer_init(&b, buf, sizeof(buf)); + result = dns_rdata_fromstruct(&rdata, rdataset->rdclass, + dns_rdatatype_soa, &soa, &b); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + temprdatalist.rdclass = rdata.rdclass; + temprdatalist.type = rdata.type; + temprdatalist.covers = 0; + temprdatalist.ttl = rdataset->ttl; + ISC_LIST_INIT(temprdatalist.rdata); + ISC_LIST_APPEND(temprdatalist.rdata, &rdata, link); + + dns_rdataset_init(&temprdataset); + result = dns_rdatalist_tordataset(&temprdatalist, &temprdataset); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + return (dns_db_addrdataset(db, node, version, 0, &temprdataset, + 0, NULL)); +} + static void receive_secure_db(isc_task_t *task, isc_event_t *event) { isc_result_t result; @@ -12579,6 +12637,8 @@ receive_secure_db(isc_task_t *task, isc_event_t *event) { dns_rdataset_t rdataset; dns_dbversion_t *version = NULL; isc_time_t loadtime; + unsigned int oldserial = 0; + isc_boolean_t have_oldserial = ISC_FALSE; UNUSED(task); @@ -12593,6 +12653,11 @@ receive_secure_db(isc_task_t *task, isc_event_t *event) { dns_rdataset_init(&rdataset); TIME_NOW(&loadtime); + if (zone->db != NULL) { + result = dns_db_getsoaserial(zone->db, NULL, &oldserial); + if (result == ISC_R_SUCCESS) + have_oldserial = ISC_TRUE; + } result = dns_db_create(zone->mctx, zone->db_argv[0], &zone->origin, dns_dbtype_zone, zone->rdclass, @@ -12635,9 +12700,14 @@ receive_secure_db(isc_task_t *task, isc_event_t *event) { dns_rdataset_disassociate(&rdataset); continue; } - - result = dns_db_addrdataset(db, node, version, 0, - &rdataset, 0, NULL); + 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; @@ -12886,9 +12956,7 @@ zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) { dns_db_closeversion(db, &ver, ISC_FALSE); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3), - "replacing zone database"); + dns_zone_log(zone, ISC_LOG_DEBUG(3), "replacing zone database"); if (zone->db != NULL) zone_detachdb(zone);