]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Clean up handling of NOTIFY settings for mirror zones
authorMichał Kępień <michal@isc.org>
Tue, 9 Oct 2018 08:54:51 +0000 (10:54 +0200)
committerOndřej Surý <ondrej@sury.org>
Wed, 24 Oct 2018 18:32:55 +0000 (20:32 +0200)
Previous way of handling NOTIFY settings for mirror zones was a bit
tricky: any value of the "notify" option was accepted, but it was
subsequently overridden with dns_notifytype_explicit.  Given the way
zone configuration is performed, this resulted in the following
behavior:

  - if "notify yes;" was set explicitly at any configuration level or
    inherited from default configuration, it was silently changed and so
    only hosts specified in "also-notify", if any, were notified,

  - if "notify no;" was set at any configuration level, it was
    effectively honored since even though zone->notifytype was silently
    set to dns_notifytype_explicit, the "also-notify" option was never
    processed due to "notify no;" being set.

Effectively, this only allowed the hosts specified in "also-notify" to
be notified, when either "notify yes;" or "notify explicit;" was
explicitly set or inherited from default configuration.

Clean up handling of NOTIFY settings for mirror zones by:

  - reporting a configuration error when anything else than "notify no;"
    or "notify explicit;" is set for a mirror zone at the zone level,

  - overriding inherited "notify yes;" setting with "notify explicit;"
    for mirror zones,

  - informing the user when the "notify" setting is overridden, unless
    the setting in question was inherited from default configuration.

bin/named/zoneconf.c
bin/tests/system/checkconf/bad-mirror-explicit-notify-yes.conf [new file with mode: 0644]
bin/tests/system/checkconf/good-mirror-inherited-notify-yes.conf [new file with mode: 0644]
lib/bind9/check.c
util/copyrights

index 36a29ece17def704a50b26f5353e2c7a0aec23e0..a1f2c5340ed4bcdb3accc2b9ef2297640607c2e0 100644 (file)
@@ -833,6 +833,37 @@ isself(dns_view_t *myview, dns_tsigkey_t *mykey,
        return (view == myview);
 }
 
+/*%
+ * For mirror zones, change "notify yes;" to "notify explicit;", informing the
+ * user only if "notify" was explicitly configured rather than inherited from
+ * default configuration.
+ */
+static dns_notifytype_t
+process_notifytype(dns_notifytype_t ntype, dns_zonetype_t ztype,
+                  const char *zname, const cfg_obj_t **maps)
+{
+       const cfg_obj_t *obj = NULL;
+
+       /*
+        * Return the original setting if this is not a mirror zone or if the
+        * zone is configured with something else than "notify yes;".
+        */
+       if (ztype != dns_zone_mirror || ntype != dns_notifytype_yes) {
+               return (ntype);
+       }
+
+       /*
+        * Only log a message if "notify" was set in the configuration
+        * hierarchy supplied in 'maps'.
+        */
+       if (named_config_get(maps, "notify", &obj) == ISC_R_SUCCESS) {
+               cfg_obj_log(obj, named_g_lctx, ISC_LOG_INFO,
+                           "'notify explicit;' will be used for mirror zone "
+                           "'%s'", zname);
+       }
+
+       return (dns_notifytype_explicit);
+}
 
 isc_result_t
 named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
@@ -1187,6 +1218,8 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
                        else
                                INSIST(0);
                }
+               notifytype = process_notifytype(notifytype, ztype, zname,
+                                               nodefault);
                if (raw != NULL)
                        dns_zone_setnotifytype(raw, dns_notifytype_no);
                dns_zone_setnotifytype(zone, notifytype);
@@ -1713,11 +1746,6 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
                        dns_zone_setxfracl(zone, none);
                        dns_acl_detach(&none);
                }
-               /*
-                * Only allow "also-notify".
-                */
-               notifytype = dns_notifytype_explicit;
-               dns_zone_setnotifytype(zone, notifytype);
                /* FALLTHROUGH */
        case dns_zone_slave:
        case dns_zone_stub:
diff --git a/bin/tests/system/checkconf/bad-mirror-explicit-notify-yes.conf b/bin/tests/system/checkconf/bad-mirror-explicit-notify-yes.conf
new file mode 100644 (file)
index 0000000..e0fabdf
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+zone "." {
+       type mirror;
+       masters { 127.0.0.1; };
+       notify yes;
+};
diff --git a/bin/tests/system/checkconf/good-mirror-inherited-notify-yes.conf b/bin/tests/system/checkconf/good-mirror-inherited-notify-yes.conf
new file mode 100644 (file)
index 0000000..14a29bf
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+options {
+       notify yes;
+};
+
+zone "." {
+       type mirror;
+       masters { 127.0.0.1; };
+};
index bfb891700189a846925dae82661598e4704f03e1..2a54fdf0d0dcb8a796573ecb692eddce95e6d141 100644 (file)
@@ -1915,6 +1915,52 @@ check_nonzero(const cfg_obj_t *options, isc_log_t *logctx) {
        return (result);
 }
 
+/*%
+ * Check whether NOTIFY configuration at the zone level is acceptable for a
+ * mirror zone.  Return true if it is; return false otherwise.
+ */
+static bool
+check_mirror_zone_notify(const cfg_obj_t *zoptions, const char *znamestr,
+                        isc_log_t *logctx)
+{
+       bool notify_configuration_ok = true;
+       const cfg_obj_t *obj = NULL;
+
+       (void)cfg_map_get(zoptions, "notify", &obj);
+       if (obj == NULL) {
+               /*
+                * "notify" not set at zone level.  This is fine.
+                */
+               return (true);
+       }
+
+       if (cfg_obj_isboolean(obj)) {
+               if (cfg_obj_asboolean(obj)) {
+                       /*
+                        * "notify yes;" set at zone level.  This is an error.
+                        */
+                       notify_configuration_ok = false;
+               }
+       } else {
+               const char *notifystr = cfg_obj_asstring(obj);
+               if (strcasecmp(notifystr, "explicit") != 0) {
+                       /*
+                        * Something else than "notify explicit;" set at zone
+                        * level.  This is an error.
+                        */
+                       notify_configuration_ok = false;
+               }
+       }
+
+       if (!notify_configuration_ok) {
+               cfg_obj_log(zoptions, logctx, ISC_LOG_ERROR,
+                           "zone '%s': mirror zones can only be used with "
+                           "'notify no;' or 'notify explicit;'", znamestr);
+       }
+
+       return (notify_configuration_ok);
+}
+
 static isc_result_t
 check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
               const cfg_obj_t *config, isc_symtab_t *symtab,
@@ -2186,6 +2232,16 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
                }
        }
 
+       /*
+        * Only a limited subset of all possible "notify" settings can be used
+        * at the zone level for mirror zones.
+        */
+       if (ztype == CFG_ZONE_MIRROR &&
+           !check_mirror_zone_notify(zoptions, znamestr, logctx))
+       {
+               result = ISC_R_FAILURE;
+       }
+
        /*
         * Master, slave, and mirror zones may have an "also-notify" field, but
         * shouldn't if notify is disabled.
index b7fb76b013626ba5cb58a6531f37a6f8a26766cb..4bc390043502b55721b64cac16fc744df9880857 100644 (file)
 ./bin/tests/system/checkconf/bad-maxcachettl.conf      CONF-C  2018
 ./bin/tests/system/checkconf/bad-maxncachettl.conf     CONF-C  2018
 ./bin/tests/system/checkconf/bad-maxttlmap.conf        CONF-C  2014,2016,2018
+./bin/tests/system/checkconf/bad-mirror-explicit-notify-yes.conf       CONF-C  2018
 ./bin/tests/system/checkconf/bad-noddns.conf   CONF-C  2014,2016,2018
 ./bin/tests/system/checkconf/bad-options-also-notify.conf      CONF-C  2016,2018
 ./bin/tests/system/checkconf/bad-printtime.conf        CONF-C  2016,2018
 ./bin/tests/system/checkconf/good-lmdb-mapsize-smallest.conf   CONF-C  2017,2018
 ./bin/tests/system/checkconf/good-maxcachettl.conf     CONF-C  2018
 ./bin/tests/system/checkconf/good-maxncachettl.conf    CONF-C  2018
+./bin/tests/system/checkconf/good-mirror-inherited-notify-yes.conf     CONF-C  2018
 ./bin/tests/system/checkconf/good-nested.conf  CONF-C  2015,2016,2018
 ./bin/tests/system/checkconf/good-options-also-notify.conf     CONF-C  2016,2018
 ./bin/tests/system/checkconf/good-printtime.conf       CONF-C  2016,2018