From: Michał Kępień Date: Mon, 26 Feb 2018 11:30:48 +0000 (+0100) Subject: Fix MX checks for dynamic updates X-Git-Tag: v9.13.0~133^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=857a40c87bb80669ecc5cf1c51301d967e7aba53;p=thirdparty%2Fbind9.git Fix MX checks for dynamic updates The check_mx() function in lib/ns/update.c incorrectly tests whether the DNS_RDATA_CHECKMX/DNS_RDATA_CHECKMXFAIL flags are set for each applied MX record update as these flags are never set in code paths related to dynamic updates; they can only be set when loading a zone from a master file (DNS_ZONEOPT_CHECKMX -> DNS_MASTER_CHECKMX -> DNS_RDATA_CHECKMX). This flaw allows MX records containing IP addresses to be added to a zone even when "check-mx fail;" is used. Ensure correct behavior by modifying the relevant tests in check_mx() so that they use DNS_ZONEOPT_CHECKMX/DNS_ZONEOPT_CHECKMXFAIL instead. --- diff --git a/bin/tests/system/nsupdate/ns1/named.conf.in b/bin/tests/system/nsupdate/ns1/named.conf.in index fbd24a1ba35..e7b6adb39e1 100644 --- a/bin/tests/system/nsupdate/ns1/named.conf.in +++ b/bin/tests/system/nsupdate/ns1/named.conf.in @@ -43,6 +43,7 @@ zone "example.nil" { type master; file "example.db"; check-integrity no; + check-mx ignore; update-policy { grant ddns-key.example.nil subdomain example.nil ANY; }; @@ -62,6 +63,7 @@ zone "other.nil" { type master; file "other.db"; check-integrity no; + check-mx warn; update-policy local; allow-query-on { 10.53.0.1; 127.0.0.1; }; allow-transfer { any; }; @@ -76,6 +78,7 @@ zone "update.nil" { type master; file "update.db"; check-integrity no; + check-mx fail; allow-update { any; }; allow-transfer { any; }; also-notify { othermasters; }; diff --git a/bin/tests/system/nsupdate/tests.sh b/bin/tests/system/nsupdate/tests.sh index 263f57e3ad1..ae5c8c592c8 100755 --- a/bin/tests/system/nsupdate/tests.sh +++ b/bin/tests/system/nsupdate/tests.sh @@ -162,6 +162,38 @@ grep ns5.other.nil dig.out.ns1 > /dev/null 2>&1 || ret=1 grep ns6.other.nil dig.out.ns1 > /dev/null 2>&1 || ret=1 [ $ret = 0 ] || { echo_i "failed"; status=1; } +ret=0 +echo_i "ensure 'check-mx ignore' allows adding MX records containing an address without a warning" +$NSUPDATE -k ns1/ddns.key > nsupdate.out 2>&1 << END || ret=1 +server 10.53.0.1 ${PORT} +update add mx03.example.nil 600 IN MX 10 10.53.0.1 +send +END +grep REFUSED nsupdate.out > /dev/null 2>&1 && ret=1 +grep "mx03.example.nil/MX:.*MX is an address" ns1/named.run > /dev/null 2>&1 && ret=1 +[ $ret = 0 ] || { echo_i "failed"; status=1; } + +ret=0 +echo_i "ensure 'check-mx warn' allows adding MX records containing an address with a warning" +$NSUPDATE -4 -l -p ${PORT} -k ns1/session.key > nsupdate.out 2>&1 << END || ret=1 +update add mx03.other.nil 600 IN MX 10 10.53.0.1 +send +END +grep REFUSED nsupdate.out > /dev/null 2>&1 && ret=1 +grep "mx03.other.nil/MX:.*MX is an address" ns1/named.run > /dev/null 2>&1 || ret=1 +[ $ret = 0 ] || { echo_i "failed"; status=1; } + +ret=0 +echo_i "ensure 'check-mx fail' prevents adding MX records containing an address with a warning" +$NSUPDATE > nsupdate.out 2>&1 << END && ret=1 +server 10.53.0.1 ${PORT} +update add mx03.update.nil 600 IN MX 10 10.53.0.1 +send +END +grep REFUSED nsupdate.out > /dev/null 2>&1 || ret=1 +grep "mx03.update.nil/MX:.*MX is an address" ns1/named.run > /dev/null 2>&1 || ret=1 +[ $ret = 0 ] || { echo_i "failed"; status=1; } + ret=0 echo_i "check SIG(0) key is accepted" key=`$KEYGEN -q -r $RANDFILE -a NSEC3RSASHA1 -b 1024 -T KEY -n ENTITY xxx` diff --git a/lib/ns/update.c b/lib/ns/update.c index 8ad98a1c724..05e60d592d9 100644 --- a/lib/ns/update.c +++ b/lib/ns/update.c @@ -1737,7 +1737,7 @@ check_mx(ns_client_t *client, dns_zone_t *zone, dns_name_format(&mx.mx, namebuf, sizeof(namebuf)); dns_name_format(&t->name, ownerbuf, sizeof(ownerbuf)); isaddress = ISC_FALSE; - if ((options & DNS_RDATA_CHECKMX) != 0 && + if ((options & DNS_ZONEOPT_CHECKMX) != 0 && strlcpy(tmp, namebuf, sizeof(tmp)) < sizeof(tmp)) { if (tmp[strlen(tmp) - 1] == '.') tmp[strlen(tmp) - 1] = '\0'; @@ -1746,7 +1746,7 @@ check_mx(ns_client_t *client, dns_zone_t *zone, isaddress = ISC_TRUE; } - if (isaddress && (options & DNS_RDATA_CHECKMXFAIL) != 0) { + if (isaddress && (options & DNS_ZONEOPT_CHECKMXFAIL) != 0) { update_log(client, zone, ISC_LOG_ERROR, "%s/MX: '%s': %s", ownerbuf, namebuf,