]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
[v9_11] Ensure all master definitions in a catalog zone contain an IP address
authorMichał Kępień <michal@isc.org>
Mon, 15 Jan 2018 19:49:05 +0000 (20:49 +0100)
committerMichał Kępień <michal@isc.org>
Mon, 15 Jan 2018 19:52:54 +0000 (20:52 +0100)
4864. [bug] named acting as a slave for a catalog zone crashed if
the latter contained a master definition without an IP
address. [RT #45999]

(cherry picked from commit ae51a676c9921907cbbffa151910b96f87848d0d)

CHANGES
bin/named/server.c
bin/tests/system/catz/tests.sh
lib/dns/catz.c

diff --git a/CHANGES b/CHANGES
index 06016bb955a4190248ad6a13d4f73a7ed200ffa3..7830fb83a40717c002f15f2fec0318fea8bb71b7 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,7 @@
+4864.  [bug]           named acting as a slave for a catalog zone crashed if
+                       the latter contained a master definition without an IP
+                       address. [RT #45999]
+
 4863.  [bug]           Fix various other bugs reported by Valgrind's
                        memcheck tool. [RT #46978]
 
index 9d48c6fba1ea2dfa7c111edd46c028a3fa789a96..cba3be8420a82449a5789e0127f9528c9147485a 100644 (file)
@@ -2194,11 +2194,17 @@ catz_addmodzone_taskaction(isc_task_t *task, isc_event_t *event0) {
        RUNTIME_CHECK(zone == NULL);
        /* Create a config for new zone */
        confbuf = NULL;
-       dns_catz_generate_zonecfg(ev->origin, ev->entry, &confbuf);
-       cfg_parser_reset(cfg->add_parser);
-       result = cfg_parse_buffer3(cfg->add_parser, confbuf, "catz", 0,
-                                  &cfg_type_addzoneconf, &zoneconf);
-       isc_buffer_free(&confbuf);
+       result = dns_catz_generate_zonecfg(ev->origin, ev->entry, &confbuf);
+       if (result == ISC_R_SUCCESS) {
+               cfg_parser_reset(cfg->add_parser);
+               result = cfg_parse_buffer3(cfg->add_parser, confbuf, "catz", 0,
+                                          &cfg_type_addzoneconf, &zoneconf);
+               isc_buffer_free(&confbuf);
+       }
+       /*
+        * Fail if either dns_catz_generate_zonecfg() or cfg_parse_buffer3()
+        * failed.
+        */
        if (result != ISC_R_SUCCESS) {
                isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
                              NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
index 11b1fc8c62d9a23cce94f895fbfc3dbaf4c9a659..0896cc41e27b7448c495e2b4546204156aa87c14 100644 (file)
@@ -341,7 +341,7 @@ status=`expr $status + $ret`
 ##########################################################################
 echo "I:Testing masters suboption and random labels"
 n=`expr $n + 1`
-echo "I: adding dom5.example with 'masters' suboption set and a random label ($n)"
+echo "I: adding dom5.example with a valid masters suboption (IP without TSIG) and a random label ($n)"
 ret=0
 $NSUPDATE -d <<END >> nsupdate.out.test$n 2>&1 || ret=1
     server 10.53.0.1 5300
@@ -433,7 +433,7 @@ status=`expr $status + $ret`
 ##########################################################################
 echo "I:Testing masters global option"
 n=`expr $n + 1`
-echo "I: adding dom6.example and global masters option ($n)"
+echo "I: adding dom6.example and a valid global masters option (IP without TSIG) ($n)"
 ret=0
 $NSUPDATE -d <<END >> nsupdate.out.test$n 2>&1 || ret=1
     server 10.53.0.1 5300
@@ -526,6 +526,77 @@ grep "status: REFUSED" dig.out.test$n > /dev/null || ret=1
 if [ $ret != 0 ]; then echo "I: failed"; fi
 status=`expr $status + $ret`
 
+cur=`awk 'BEGIN {l=0} /^/ {l++} END { print l }' ns2/named.run`
+
+n=`expr $n + 1`
+echo "I: adding dom6.example and an invalid global masters option (TSIG without IP) ($n)"
+ret=0
+$NSUPDATE -d <<END >> nsupdate.out.test$n 2>&1 || ret=1
+    server 10.53.0.1 5300
+    update add label1.masters.catalog1.example 3600 IN TXT "tsig_key"
+    update add 4346f565b4d63ddb99e5d2497ff22d04e878e8f8.zones.catalog1.example 3600 IN PTR dom6.example.
+    send
+END
+if [ $ret != 0 ]; then echo "I: failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo "I: waiting for slave to sync up ($n)"
+ret=1
+try=0
+while test $try -lt 45
+do
+    sleep 1
+    sed -n "$cur,"'$p' < ns2/named.run | grep "catz: adding zone 'dom6.example' from catalog 'catalog1.example'" > /dev/null && {
+       ret=0
+       break
+    }
+    try=`expr $try + 1`
+done
+if [ $ret = 0 ]; then
+       ret=1
+       try=0
+       while test $try -lt 45
+       do
+           sleep 1
+           sed -n "$cur,"'$p' < ns2/named.run | grep "error .* while trying to generate config for zone \"dom6.example\"" > /dev/null && {
+
+               ret=0
+               break
+           }
+           try=`expr $try + 1`
+       done
+fi
+if [ $ret != 0 ]; then echo "I: failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo "I: removing dom6.example ($n)"
+ret=0
+$NSUPDATE -d <<END >> nsupdate.out.test$n 2>&1 || ret=1
+    server 10.53.0.1 5300
+    update delete label1.masters.catalog1.example 3600 IN TXT "tsig_key"
+    update delete 4346f565b4d63ddb99e5d2497ff22d04e878e8f8.zones.catalog1.example 3600 IN PTR dom6.example.
+    send
+END
+if [ $ret != 0 ]; then echo "I: failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo "I: waiting for slave to sync up ($n)"
+ret=1
+try=0
+while test $try -lt 45
+do
+    sleep 1
+    sed -n "$cur,"'$p' < ns2/named.run | grep "catz: deleting zone 'dom6.example' from catalog 'catalog1.example'" > /dev/null && {
+       ret=0
+       break
+    }
+    try=`expr $try + 1`
+done
+if [ $ret != 0 ]; then echo "I: failed"; fi
+status=`expr $status + $ret`
 
 ##########################################################################
 n=`expr $n + 1`
@@ -769,7 +840,7 @@ status=`expr $status + $ret`
 cur=`awk 'BEGIN {l=0} /^/ {l++} END { print l }' ns2/named.run`
 
 n=`expr $n + 1`
-echo "I: adding domain dom9.example to catalog1 zone with masters and tsig key($n)"
+echo "I: adding domain dom9.example to catalog1 zone with a valid masters suboption (IP with TSIG) ($n)"
 ret=0
 $NSUPDATE -d <<END >> nsupdate.out.test$n 2>&1 || ret=1
     server 10.53.0.1 5300
@@ -819,7 +890,7 @@ if [ $ret != 0 ]; then echo "I: failed"; fi
 status=`expr $status + $ret`
 
 n=`expr $n + 1`
-echo "I: deleting domain dom9.example from catalog1 zone($n)"
+echo "I: deleting domain dom9.example from catalog1 zone ($n)"
 ret=0
 $NSUPDATE -d <<END >> nsupdate.out.test$n 2>&1 || ret=1
     server 10.53.0.1 5300
@@ -855,6 +926,78 @@ grep "status: REFUSED" dig.out.test$n > /dev/null || ret=1
 if [ $ret != 0 ]; then echo "I: failed"; fi
 status=`expr $status + $ret`
 
+cur=`awk 'BEGIN {l=0} /^/ {l++} END { print l }' ns2/named.run`
+
+n=`expr $n + 1`
+echo "I: adding domain dom9.example to catalog1 zone with an invalid masters suboption (TSIG without IP) ($n)"
+ret=0
+$NSUPDATE -d <<END >> nsupdate.out.test$n 2>&1 || ret=1
+    server 10.53.0.1 5300
+    update add f0f989bc71c5c8ca3a1eb9c9ab5246521907e3af.zones.catalog1.example 3600 IN PTR dom9.example.
+    update add label1.masters.f0f989bc71c5c8ca3a1eb9c9ab5246521907e3af.zones.catalog1.example 3600 IN TXT "tsig_key"
+    send
+END
+if [ $ret != 0 ]; then echo "I: failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo "I: waiting for slave to sync up ($n)"
+ret=1
+try=0
+while test $try -lt 45
+do
+    sleep 1
+    sed -n "$cur,"'$p' < ns2/named.run | grep "catz: adding zone 'dom9.example' from catalog 'catalog1.example'" > /dev/null && {
+       ret=0
+       break
+    }
+    try=`expr $try + 1`
+done
+if [ $ret = 0 ]; then
+       ret=1
+       try=0
+       while test $try -lt 45
+       do
+           sleep 1
+           sed -n "$cur,"'$p' < ns2/named.run | grep "error .* while trying to generate config for zone \"dom9.example\"" > /dev/null && {
+
+               ret=0
+               break
+           }
+           try=`expr $try + 1`
+       done
+fi
+if [ $ret != 0 ]; then echo "I: failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo "I: deleting domain dom9.example from catalog1 zone ($n)"
+ret=0
+$NSUPDATE -d <<END >> nsupdate.out.test$n 2>&1 || ret=1
+    server 10.53.0.1 5300
+    update delete f0f989bc71c5c8ca3a1eb9c9ab5246521907e3af.zones.catalog1.example 3600 IN PTR dom9.example.
+    update delete label1.masters.f0f989bc71c5c8ca3a1eb9c9ab5246521907e3af.zones.catalog1.example 3600 IN TXT "tsig_key"
+    send
+END
+if [ $ret != 0 ]; then echo "I: failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo "I: waiting for slave to sync up ($n)"
+ret=1
+try=0
+while test $try -lt 45
+do
+    sleep 1
+    sed -n "$cur,"'$p' < ns2/named.run | grep "catz: deleting zone 'dom9.example' from catalog 'catalog1.example'" > /dev/null && {
+       ret=0
+       break
+    }
+    try=`expr $try + 1`
+done
+if [ $ret != 0 ]; then echo "I: failed"; fi
+status=`expr $status + $ret`
+
 ##########################################################################
 echo "I:Testing very long domain in catalog"
 n=`expr $n + 1`
@@ -933,7 +1076,7 @@ if [ $ret != 0 ]; then echo "I: failed"; fi
 status=`expr $status + $ret`
 
 n=`expr $n + 1`
-echo "I: checking that zone-directory is populated with a hashed filename($n)"
+echo "I: checking that zone-directory is populated with a hashed filename ($n)"
 ret=0
 [ -f "ns2/zonedir/__catz__4d70696f2335687069467f11f5d5378c480383f97782e553fb2d04a7bb2a23ed.db" ] || ret=1
 if [ $ret != 0 ]; then echo "I: failed"; fi
@@ -1329,7 +1472,15 @@ if [ $ret != 0 ]; then echo "I: failed"; fi
 status=`expr $status + $ret`
 
 n=`expr $n + 1`
-echo "I: reconfiguring slave - removing catalog4 catalog zone ($n)"
+echo "I: reconfiguring slave - removing catalog4 catalog zone, adding non-existent catalog5 catalog zone ($n)"
+ret=0
+cat ns2/named.conf.in | sed -e "s/^#T2//" > ns2/named.conf
+$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 reconfig > /dev/null 2>&1 && ret=1
+if [ $ret != 0 ]; then echo "I: failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo "I: reconfiguring slave - removing non-existent catalog5 catalog zone ($n)"
 ret=0
 cat ns2/named.conf.in > ns2/named.conf
 $RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 reconfig || ret=1
@@ -1405,7 +1556,7 @@ status=`expr $status + $ret`
 cur=`awk 'BEGIN {l=0} /^/ {l++} END { print l }' ns2/named.run`
 
 n=`expr $n + 1`
-echo "I: Adding domain dom13.example to catalog1 zone with ns1 as master($n)"
+echo "I: Adding domain dom13.example to catalog1 zone with ns1 as master ($n)"
 ret=0
 $NSUPDATE -d <<END >> nsupdate.out.test$n 2>&1 || ret=1
     server 10.53.0.1 5300
@@ -1457,7 +1608,7 @@ if [ $ret != 0 ]; then echo "I: failed"; fi
 status=`expr $status + $ret`
 
 n=`expr $n + 1`
-echo "I: Adding domain dom13.example to catalog2 zone with ns3 as master($n)"
+echo "I: Adding domain dom13.example to catalog2 zone with ns3 as master ($n)"
 ret=0
 $NSUPDATE -d <<END >> nsupdate.out.test$n 2>&1 || ret=1
     server 10.53.0.3 5300
@@ -1617,7 +1768,7 @@ status=`expr $status + $ret`
 cur=`awk 'BEGIN {l=0} /^/ {l++} END { print l }' ns2/named.run`
 
 n=`expr $n + 1`
-echo "I: Adding domain dom14.example with rndc with ns1 as master($n)"
+echo "I: Adding domain dom14.example with rndc with ns1 as master ($n)"
 ret=0
 $RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 addzone dom14.example '{type slave; masters {10.53.0.1;};};' || ret=1
 if [ $ret != 0 ]; then echo "I: failed"; fi
@@ -1651,7 +1802,7 @@ if [ $ret != 0 ]; then echo "I: failed"; fi
 status=`expr $status + $ret`
 
 n=`expr $n + 1`
-echo "I: Adding domain dom14.example to catalog2 zone with ns3 as master($n)"
+echo "I: Adding domain dom14.example to catalog2 zone with ns3 as master ($n)"
 ret=0
 $NSUPDATE -d <<END >> nsupdate.out.test$n 2>&1 || ret=1
     server 10.53.0.3 5300
@@ -1784,7 +1935,7 @@ status=`expr $status + $ret`
 sleep 3
 
 n=`expr $n + 1`
-echo "I: checking that dom15.example is served by slave($n)"
+echo "I: checking that dom15.example is served by slave ($n)"
 for try in 0 1 2 3 4 5 6 7 8 9; do
     $DIG soa dom15.example @10.53.0.2 -p 5300 > dig.out.test$n
     ret=0
index b3036a8b78fa40a0c7143916ede5d7cc22b92eb5..13f979d14e2a88ed8738390aa453a79f9f81f192 100644 (file)
@@ -1517,6 +1517,7 @@ dns_catz_generate_zonecfg(dns_catz_zone_t *zone, dns_catz_entry_t *entry,
        isc_uint32_t i;
        isc_netaddr_t netaddr;
        char pbuf[sizeof("65535")]; /* used both for port number and DSCP */
+       char zname[DNS_NAME_FORMATSIZE];
 
        REQUIRE(zone != NULL);
        REQUIRE(entry != NULL);
@@ -1552,6 +1553,24 @@ dns_catz_generate_zonecfg(dns_catz_zone_t *zone, dns_catz_entry_t *entry,
 
        isc_buffer_putstr(buffer, " { ");
        for (i = 0; i < entry->opts.masters.count; i++) {
+               /*
+                * Every master must have an IP address assigned.
+                */
+               switch (entry->opts.masters.addrs[i].type.sa.sa_family) {
+               case AF_INET:
+               case AF_INET6:
+                       break;
+               default:
+                       dns_name_format(&entry->name, zname,
+                                       DNS_NAME_FORMATSIZE);
+                       isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
+                                     DNS_LOGMODULE_MASTER, ISC_LOG_ERROR,
+                                     "catz: zone '%s' uses an invalid master "
+                                     "(no IP address assigned)",
+                                     zname);
+                       result = ISC_R_FAILURE;
+                       goto cleanup;
+               }
                isc_netaddr_fromsockaddr(&netaddr,
                                         &entry->opts.masters.addrs[i]);
                isc_buffer_reserve(&buffer, INET6_ADDRSTRLEN);
@@ -1572,26 +1591,26 @@ dns_catz_generate_zonecfg(dns_catz_zone_t *zone, dns_catz_entry_t *entry,
                }
                isc_buffer_putstr(buffer, "; ");
        }
-       isc_buffer_putstr(buffer, "};");
+       isc_buffer_putstr(buffer, "}; ");
        if (entry->opts.in_memory == ISC_FALSE) {
                isc_buffer_putstr(buffer, "file \"");
                result = dns_catz_generate_masterfilename(zone, entry, &buffer);
                if (result != ISC_R_SUCCESS)
                        goto cleanup;
-               isc_buffer_putstr(buffer, "\";");
+               isc_buffer_putstr(buffer, "\"; ");
 
        }
        if (entry->opts.allow_query != NULL) {
                isc_buffer_putstr(buffer, "allow-query { ");
                isc_buffer_usedregion(entry->opts.allow_query, &region);
                isc_buffer_copyregion(buffer, &region);
-               isc_buffer_putstr(buffer, "};");
+               isc_buffer_putstr(buffer, "}; ");
        }
        if (entry->opts.allow_transfer != NULL) {
                isc_buffer_putstr(buffer, "allow-transfer { ");
                isc_buffer_usedregion(entry->opts.allow_transfer, &region);
                isc_buffer_copyregion(buffer, &region);
-               isc_buffer_putstr(buffer, "};");
+               isc_buffer_putstr(buffer, "}; ");
        }
 
        isc_buffer_putstr(buffer, "};");
@@ -1599,12 +1618,11 @@ dns_catz_generate_zonecfg(dns_catz_zone_t *zone, dns_catz_entry_t *entry,
        return (ISC_R_SUCCESS);
 
 cleanup:
-       if (buffer)
+       if (buffer != NULL)
                isc_buffer_free(&buffer);
        return (result);
 }
 
-
 void
 dns_catz_update_taskaction(isc_task_t *task, isc_event_t *event) {
        isc_result_t result;