From: Michał Kępień Date: Tue, 9 Oct 2018 08:54:51 +0000 (+0200) Subject: Prevent mirror zones from being used when recursion is disabled X-Git-Tag: v9.13.4~99^2~4 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=34dc674fed76ec87217fab5bf4d7f575e8b572d0;p=thirdparty%2Fbind9.git Prevent mirror zones from being used when recursion is disabled Since mirror zone data is treated as cache data for access control purposes, configuring a mirror zone and disabling recursion at the same time would effectively prevent mirror zone data from being used since disabling recursion also disables cache access to all clients by default. Even though this behavior can be inhibited by configuration, mirror zones are a recursive resolver feature and thus recursion is now required to use them. Ignore the fact that certain configurations might still trick named into assuming recursion is enabled when it effectively is not since this change is not meant to put a hard policy in place but rather just to prevent accidental mirror zone misuse. --- diff --git a/bin/tests/system/checkconf/bad-mirror-allow-recursion-none.conf b/bin/tests/system/checkconf/bad-mirror-allow-recursion-none.conf new file mode 100644 index 00000000000..9dabf8897ee --- /dev/null +++ b/bin/tests/system/checkconf/bad-mirror-allow-recursion-none.conf @@ -0,0 +1,20 @@ +/* + * 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 { + recursion yes; + allow-recursion { none; }; +}; + +zone "." { + type mirror; + masters { 127.0.0.1; }; +}; diff --git a/bin/tests/system/checkconf/bad-mirror-recursion-no.conf b/bin/tests/system/checkconf/bad-mirror-recursion-no.conf new file mode 100644 index 00000000000..4dff2cadfd3 --- /dev/null +++ b/bin/tests/system/checkconf/bad-mirror-recursion-no.conf @@ -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 { + recursion no; +}; + +zone "." { + type mirror; + masters { 127.0.0.1; }; +}; diff --git a/lib/bind9/check.c b/lib/bind9/check.c index 2a54fdf0d0d..6f4cf798ece 100644 --- a/lib/bind9/check.c +++ b/lib/bind9/check.c @@ -1961,6 +1961,68 @@ check_mirror_zone_notify(const cfg_obj_t *zoptions, const char *znamestr, return (notify_configuration_ok); } +/*% + * Try to determine whether recursion is available in a view without resorting + * to extraordinary measures: just check the "recursion" and "allow-recursion" + * settings. The point is to prevent accidental mirror zone misuse rather than + * to enforce some sort of policy. Recursion is assumed to be allowed by + * default if it is not explicitly disabled. + */ +static bool +check_recursion(const cfg_obj_t *config, const cfg_obj_t *voptions, + const cfg_obj_t *goptions, isc_log_t *logctx, + cfg_aclconfctx_t *actx, isc_mem_t *mctx) +{ + dns_acl_t *acl = NULL; + const cfg_obj_t *obj; + isc_result_t result; + bool retval = true; + + /* + * Check the "recursion" option first. + */ + obj = NULL; + result = ISC_R_NOTFOUND; + if (voptions != NULL) { + result = cfg_map_get(voptions, "recursion", &obj); + } + if (result != ISC_R_SUCCESS && goptions != NULL) { + result = cfg_map_get(goptions, "recursion", &obj); + } + if (result == ISC_R_SUCCESS && !cfg_obj_asboolean(obj)) { + retval = false; + goto cleanup; + } + + /* + * If recursion is not disabled by the "recursion" option, check + * whether it is disabled by the "allow-recursion" ACL. + */ + obj = NULL; + result = ISC_R_NOTFOUND; + if (voptions != NULL) { + result = cfg_map_get(voptions, "allow-recursion", &obj); + } + if (result != ISC_R_SUCCESS && goptions != NULL) { + result = cfg_map_get(goptions, "allow-recursion", &obj); + } + if (result == ISC_R_SUCCESS) { + result = cfg_acl_fromconfig(obj, config, logctx, actx, mctx, 0, + &acl); + if (result != ISC_R_SUCCESS) { + goto cleanup; + } + retval = !dns_acl_isnone(acl); + } + + cleanup: + if (acl != NULL) { + dns_acl_detach(&acl); + } + + return (retval); +} + 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, @@ -2315,6 +2377,19 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions, } } + /* + * Configuring a mirror zone and disabling recursion at the same time + * contradicts the purpose of the former. + */ + if (ztype == CFG_ZONE_MIRROR && + !check_recursion(config, voptions, goptions, logctx, actx, mctx)) + { + cfg_obj_log(zoptions, logctx, ISC_LOG_ERROR, + "zone '%s': mirror zones cannot be used if " + "recursion is disabled", znamestr); + result = ISC_R_FAILURE; + } + /* * Master zones can't have both "allow-update" and "update-policy". */ diff --git a/util/copyrights b/util/copyrights index 4bc39004350..c362e624bd3 100644 --- a/util/copyrights +++ b/util/copyrights @@ -597,7 +597,9 @@ ./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-allow-recursion-none.conf CONF-C 2018 ./bin/tests/system/checkconf/bad-mirror-explicit-notify-yes.conf CONF-C 2018 +./bin/tests/system/checkconf/bad-mirror-recursion-no.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