diff --git a/CHANGES b/CHANGES index f1cc2cd75e..6bed7e4752 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +4037. [bug] also-notify was ignoring the tsig key when checking + for duplicates resulting in some expected notify + messages not being sent. [RT #38369] + 4036. [bug] Make call to open a temporary file name safe during NZF creation. [RT #38331] diff --git a/bin/tests/system/notify/clean.sh b/bin/tests/system/notify/clean.sh index ef76c6b44a..303839c4a3 100644 --- a/bin/tests/system/notify/clean.sh +++ b/bin/tests/system/notify/clean.sh @@ -20,12 +20,18 @@ # rm -f */named.memstats +rm -f dig.out.?.ns5.test* rm -f dig.out.ns2.test* rm -f dig.out.ns3.test* rm -f dig.out.ns4.test* rm -f log.out +rm -f ns*/named.lock rm -f ns2/example.db rm -f ns2/x21.db* rm -f ns3/example.bk rm -f ns4/x21.bk* -rm -f ns*/named.lock +rm -f ns5/x21.bk-b +rm -f ns5/x21.bk-b.jnl +rm -f ns5/x21.bk-c +rm -f ns5/x21.bk-c.jnl +rm -f ns5/x21.db.jnl diff --git a/bin/tests/system/notify/ns5/named.conf b/bin/tests/system/notify/ns5/named.conf new file mode 100644 index 0000000000..c73069fd27 --- /dev/null +++ b/bin/tests/system/notify/ns5/named.conf @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* $Id: named.conf,v 1.24 2007/06/18 23:47:29 tbox Exp $ */ + +controls { /* empty */ }; + +key "a" { + algorithm "hmac-md5"; + secret "aaaaaaaaaaaaaaaaaaaa"; +}; + +key "b" { + algorithm "hmac-md5"; + secret "bbbbbbbbbbbbbbbbbbbb"; +}; + +key "c" { + algorithm "hmac-md5"; + secret "cccccccccccccccccccc"; +}; + +options { + query-source address 10.53.0.5; + notify-source 10.53.0.5; + transfer-source 10.53.0.5; + port 5300; + pid-file "named.pid"; + listen-on { 10.53.0.5; }; + listen-on-v6 { none; }; + recursion yes; + acache-enable yes; + notify yes; +}; + +view "a" { + match-clients { key "a"; }; + zone "x21" { + type master; + also-notify { 10.53.0.5 key "b"; 10.53.0.5 key "c"; }; + file "x21.db"; + allow-update { any; }; + }; +}; + +view "b" { + match-clients { key "b"; }; + zone "x21" { + type slave; + masters { 10.53.0.5 key "a"; }; + file "x21.bk-b"; + }; +}; + +view "c" { + match-clients { key "c"; }; + zone "x21" { + type slave; + masters { 10.53.0.5 key "a"; }; + file "x21.bk-c"; + }; +}; diff --git a/bin/tests/system/notify/ns5/x21.db b/bin/tests/system/notify/ns5/x21.db new file mode 100644 index 0000000000..d71ae13fde --- /dev/null +++ b/bin/tests/system/notify/ns5/x21.db @@ -0,0 +1,25 @@ +; Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC") +; +; Permission to use, copy, modify, and/or distribute this software for any +; purpose with or without fee is hereby granted, provided that the above +; copyright notice and this permission notice appear in all copies. +; +; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +; PERFORMANCE OF THIS SOFTWARE. + +$TTL 300 ; 5 minutes +@ IN SOA mname1. . ( + 1 ; serial + 300 ; refresh (300 seconds) + 300 ; retry (300 seconds) + 1814400 ; expire (3 weeks) + 3600 ; minimum (1 hour) + ) + NS ns5 +ns5 A 10.53.0.5 +a A 10.0.0.1 diff --git a/bin/tests/system/notify/tests.sh b/bin/tests/system/notify/tests.sh index a6eeafb4ec..27a791d4bf 100644 --- a/bin/tests/system/notify/tests.sh +++ b/bin/tests/system/notify/tests.sh @@ -170,5 +170,35 @@ grep "test string" dig.out.ns4.test$n > /dev/null || ret=1 [ $ret = 0 ] || echo "I:failed" status=`expr $ret + $status` +n=`expr $n + 1` +echo "I:checking notify to multiple views using tsig" +ret=0 +$NSUPDATE << EOF +server 10.53.0.5 5300 +zone x21 +key a aaaaaaaaaaaaaaaaaaaa +update add added.x21 0 in txt "test string" +send +EOF + +for i in 1 2 3 4 5 6 7 8 9 +do + $DIG +tcp +noadd +nosea +nostat +noquest +nocomm +nocmd added.x21.\ + -y b:bbbbbbbbbbbbbbbbbbbb @10.53.0.5 \ + txt -p 5300 > dig.out.b.ns5.test$n || ret=1 + $DIG +tcp +noadd +nosea +nostat +noquest +nocomm +nocmd added.x21.\ + -y c:cccccccccccccccccccc @10.53.0.5 \ + txt -p 5300 > dig.out.c.ns5.test$n || ret=1 + grep "test string" dig.out.b.ns5.test$n > /dev/null && + grep "test string" dig.out.c.ns5.test$n > /dev/null && + break + sleep 1 +done +grep "test string" dig.out.b.ns5.test$n > /dev/null || ret=1 +grep "test string" dig.out.c.ns5.test$n > /dev/null || ret=1 + +[ $ret = 0 ] || echo "I:failed" +status=`expr $ret + $status` + echo "I:exit status: $status" exit $status diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 320d046f2a..70426fe064 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -10036,7 +10036,7 @@ dns_zone_setmaxretrytime(dns_zone_t *zone, isc_uint32_t val) { static isc_boolean_t notify_isqueued(dns_zone_t *zone, unsigned int flags, dns_name_t *name, - isc_sockaddr_t *addr) + isc_sockaddr_t *addr, dns_tsigkey_t *key) { dns_notify_t *notify; dns_zonemgr_t *zmgr; @@ -10052,7 +10052,8 @@ notify_isqueued(dns_zone_t *zone, unsigned int flags, dns_name_t *name, if (name != NULL && dns_name_dynamic(¬ify->ns) && dns_name_equal(name, ¬ify->ns)) goto requeue; - if (addr != NULL && isc_sockaddr_equal(addr, ¬ify->dst)) + if (addr != NULL && isc_sockaddr_equal(addr, ¬ify->dst) && + notify->key == key) goto requeue; } return (ISC_FALSE); @@ -10433,7 +10434,8 @@ notify_send(dns_notify_t *notify) { ai != NULL; ai = ISC_LIST_NEXT(ai, publink)) { dst = ai->sockaddr; - if (notify_isqueued(notify->zone, notify->flags, NULL, &dst)) + if (notify_isqueued(notify->zone, notify->flags, NULL, &dst, + NULL)) continue; if (notify_isself(notify->zone, &dst)) continue; @@ -10485,7 +10487,6 @@ zone_notify(dns_zone_t *zone, isc_time_t *now) { dns_rdataset_t nsrdset; dns_rdataset_t soardset; isc_result_t result; - dns_notify_t *notify = NULL; unsigned int i; isc_sockaddr_t dst; isc_boolean_t isqueued; @@ -10572,27 +10573,37 @@ zone_notify(dns_zone_t *zone, isc_time_t *now) { LOCK_ZONE(zone); for (i = 0; i < zone->notifycnt; i++) { dns_tsigkey_t *key = NULL; - - dst = zone->notify[i]; - if (notify_isqueued(zone, flags, NULL, &dst)) - continue; - - result = notify_create(zone->mctx, flags, ¬ify); - if (result != ISC_R_SUCCESS) - continue; - - zone_iattach(zone, ¬ify->zone); - notify->dst = dst; + dns_notify_t *notify = NULL; if ((zone->notifykeynames != NULL) && (zone->notifykeynames[i] != NULL)) { dns_view_t *view = dns_zone_getview(zone); dns_name_t *keyname = zone->notifykeynames[i]; - result = dns_view_gettsig(view, keyname, &key); - if (result == ISC_R_SUCCESS) { - notify->key = key; - key = NULL; - } + (void)dns_view_gettsig(view, keyname, &key); + } + + dst = zone->notify[i]; + if (notify_isqueued(zone, flags, NULL, &dst, key)) { + if (key != NULL) + dns_tsigkey_detach(&key); + continue; + } + + result = notify_create(zone->mctx, flags, ¬ify); + if (result != ISC_R_SUCCESS) { + if (key != NULL) + dns_tsigkey_detach(&key); + continue; + } + + zone_iattach(zone, ¬ify->zone); + notify->dst = dst; + + INSIST(notify->key == NULL); + + if (key != NULL) { + notify->key = key; + key = NULL; } ISC_LIST_APPEND(zone->notifies, notify, link); @@ -10605,7 +10616,6 @@ zone_notify(dns_zone_t *zone, isc_time_t *now) { serial); loggednotify = ISC_TRUE; } - notify = NULL; } UNLOCK_ZONE(zone); @@ -10624,6 +10634,8 @@ zone_notify(dns_zone_t *zone, isc_time_t *now) { result = dns_rdataset_first(&nsrdset); while (result == ISC_R_SUCCESS) { + dns_notify_t *notify = NULL; + dns_rdataset_current(&nsrdset, &rdata); result = dns_rdata_tostruct(&rdata, &ns, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); @@ -10646,7 +10658,7 @@ zone_notify(dns_zone_t *zone, isc_time_t *now) { } LOCK_ZONE(zone); - isqueued = notify_isqueued(zone, flags, &ns.name, NULL); + isqueued = notify_isqueued(zone, flags, &ns.name, NULL, NULL); UNLOCK_ZONE(zone); if (isqueued) { result = dns_rdataset_next(&nsrdset); @@ -10667,7 +10679,6 @@ zone_notify(dns_zone_t *zone, isc_time_t *now) { ISC_LIST_APPEND(zone->notifies, notify, link); UNLOCK_ZONE(zone); notify_find_address(notify); - notify = NULL; result = dns_rdataset_next(&nsrdset); } dns_rdataset_disassociate(&nsrdset);