From e01a4bcb20b7f02a7c5b013ae9ed115834f7caa9 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Fri, 25 May 2018 13:15:00 +1000 Subject: [PATCH 1/2] construct a symtab of valid in-view targets then check that the target exists --- .../system/checkconf/bad-sharedzone3.conf | 23 +++ lib/bind9/check.c | 151 +++++++++++++----- 2 files changed, 138 insertions(+), 36 deletions(-) create mode 100644 bin/tests/system/checkconf/bad-sharedzone3.conf diff --git a/bin/tests/system/checkconf/bad-sharedzone3.conf b/bin/tests/system/checkconf/bad-sharedzone3.conf new file mode 100644 index 0000000000..e174ab1165 --- /dev/null +++ b/bin/tests/system/checkconf/bad-sharedzone3.conf @@ -0,0 +1,23 @@ +/* + * 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. + */ + +view first { + zone shared.example { + in-view second; + }; +}; + +view second { + zone shared.example { + type master; + file "shared.example.db"; + }; +}; diff --git a/lib/bind9/check.c b/lib/bind9/check.c index b7e276e14b..d0b528f654 100644 --- a/lib/bind9/check.c +++ b/lib/bind9/check.c @@ -1909,14 +1909,17 @@ check_nonzero(const cfg_obj_t *options, isc_log_t *logctx) { 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, - isc_symtab_t *files, dns_rdataclass_t defclass, + isc_symtab_t *files, isc_symtab_t *inview, + const char *viewname, dns_rdataclass_t defclass, cfg_aclconfctx_t *actx, isc_log_t *logctx, isc_mem_t *mctx) { const char *znamestr; const char *typestr = NULL; + const char *target = NULL; unsigned int ztype; const cfg_obj_t *zoptions, *goptions = NULL; const cfg_obj_t *obj = NULL; + const cfg_obj_t *inviewobj = NULL; isc_result_t result = ISC_R_SUCCESS; isc_result_t tresult; unsigned int i; @@ -1954,9 +1957,10 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions, if (config != NULL) cfg_map_get(config, "options", &goptions); - obj = NULL; - (void)cfg_map_get(zoptions, "in-view", &obj); - if (obj != NULL) { + inviewobj = NULL; + (void)cfg_map_get(zoptions, "in-view", &inviewobj); + if (inviewobj != NULL) { + target = cfg_obj_asstring(inviewobj); ztype = CFG_ZONE_INVIEW; } else { obj = NULL; @@ -2000,27 +2004,30 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions, "redirect zones must be called \".\""); return (ISC_R_FAILURE); } - obj = cfg_tuple_get(zconfig, "class"); - if (cfg_obj_isstring(obj)) { - isc_textregion_t r; + } - DE_CONST(cfg_obj_asstring(obj), r.base); - r.length = strlen(r.base); - result = dns_rdataclass_fromtext(&zclass, &r); - if (result != ISC_R_SUCCESS) { - cfg_obj_log(obj, logctx, ISC_LOG_ERROR, - "zone '%s': invalid class %s", - znamestr, r.base); - return (ISC_R_FAILURE); - } - if (zclass != defclass) { - cfg_obj_log(obj, logctx, ISC_LOG_ERROR, - "zone '%s': class '%s' does not " - "match view/default class", - znamestr, r.base); - return (ISC_R_FAILURE); - } + obj = cfg_tuple_get(zconfig, "class"); + if (cfg_obj_isstring(obj)) { + isc_textregion_t r; + + DE_CONST(cfg_obj_asstring(obj), r.base); + r.length = strlen(r.base); + result = dns_rdataclass_fromtext(&zclass, &r); + if (result != ISC_R_SUCCESS) { + cfg_obj_log(obj, logctx, ISC_LOG_ERROR, + "zone '%s': invalid class %s", + znamestr, r.base); + return (ISC_R_FAILURE); } + if (zclass != defclass) { + cfg_obj_log(obj, logctx, ISC_LOG_ERROR, + "zone '%s': class '%s' does not " + "match view/default class", + znamestr, r.base); + return (ISC_R_FAILURE); + } + } else { + zclass = defclass; } /* @@ -2038,7 +2045,9 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions, "zone '%s': is not a valid name", znamestr); result = ISC_R_FAILURE; } else { - char namebuf[DNS_NAME_FORMATSIZE]; + char namebuf[DNS_NAME_FORMATSIZE + 128]; + char *tmp = namebuf; + size_t len = sizeof(namebuf); zname = dns_fixedname_name(&fixedname); dns_name_format(zname, namebuf, sizeof(namebuf)); @@ -2055,6 +2064,57 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions, rfc1918 = ISC_TRUE; else if (dns_name_isula(zname)) ula = ISC_TRUE; + tmp += strlen(tmp); + len -= strlen(tmp); + (void)snprintf(tmp, len, "%u/%s", zclass, + (ztype == CFG_ZONE_INVIEW) ? target : + (viewname != NULL) ? viewname : "_default"); + switch (ztype) { + case CFG_ZONE_INVIEW: + tresult = isc_symtab_lookup(inview, namebuf, 0, NULL); + if (tresult != ISC_R_SUCCESS) { + cfg_obj_log(inviewobj, logctx, ISC_LOG_ERROR, + "'in-view' zone '%s' " + "does not exist in view '%s', " + "or view '%s' is not yet defined", + znamestr, target, target); + if (result == ISC_R_SUCCESS) { + result = tresult; + } + } + break; + + case CFG_ZONE_FORWARD: + case CFG_ZONE_REDIRECT: + case CFG_ZONE_DELEGATION: + break; + + case CFG_ZONE_MASTER: + case CFG_ZONE_SLAVE: + case CFG_ZONE_HINT: + case CFG_ZONE_STUB: + case CFG_ZONE_STATICSTUB: + tmp = isc_mem_strdup(mctx, namebuf); + if (tmp != NULL) { + isc_symvalue_t symvalue; + + symvalue.as_cpointer = NULL; + tresult = isc_symtab_define(inview, tmp, 1, + symvalue, isc_symexists_replace); + if (tresult == ISC_R_NOMEMORY) { + isc_mem_free(mctx, tmp); + } + if (result == ISC_R_SUCCESS && + tresult != ISC_R_SUCCESS) + result = tresult; + } else if (result != ISC_R_SUCCESS) { + result = ISC_R_NOMEMORY; + } + break; + + default: + INSIST(0); + } } if (ztype == CFG_ZONE_INVIEW) { @@ -3230,7 +3290,8 @@ check_rpz_catz(const char *rpz_catz, const cfg_obj_t *rpz_obj, static isc_result_t check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions, const char *viewname, dns_rdataclass_t vclass, - isc_symtab_t *files, isc_log_t *logctx, isc_mem_t *mctx) + isc_symtab_t *files, isc_symtab_t *inview, + isc_log_t *logctx, isc_mem_t *mctx) { const cfg_obj_t *zones = NULL; const cfg_obj_t *keys = NULL; @@ -3285,8 +3346,8 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions, const cfg_obj_t *zone = cfg_listelt_value(element); tresult = check_zoneconf(zone, voptions, config, symtab, - files, vclass, actx, logctx, - mctx); + files, inview, viewname, vclass, + actx, logctx, mctx); if (tresult != ISC_R_SUCCESS) result = ISC_R_FAILURE; } @@ -3814,6 +3875,7 @@ bind9_check_namedconf(const cfg_obj_t *config, isc_log_t *logctx, isc_result_t tresult; isc_symtab_t *symtab = NULL; isc_symtab_t *files = NULL; + isc_symtab_t *inview = NULL; static const char *builtin[] = { "localhost", "localnets", "any", "none"}; @@ -3844,13 +3906,24 @@ bind9_check_namedconf(const cfg_obj_t *config, isc_log_t *logctx, */ tresult = isc_symtab_create(mctx, 100, NULL, NULL, ISC_FALSE, &files); - if (tresult != ISC_R_SUCCESS) + if (tresult != ISC_R_SUCCESS) { result = tresult; + goto cleanup; + } + + tresult = isc_symtab_create(mctx, 100, freekey, mctx, + ISC_TRUE, &inview); + if (tresult != ISC_R_SUCCESS) { + result = tresult; + goto cleanup; + } if (views == NULL) { - if (check_viewconf(config, NULL, NULL, dns_rdataclass_in, - files, logctx, mctx) != ISC_R_SUCCESS) + tresult = check_viewconf(config, NULL, NULL, dns_rdataclass_in, + files, inview, logctx, mctx); + if (result == ISC_R_SUCCESS && tresult != ISC_R_SUCCESS) { result = ISC_R_FAILURE; + } } else { const cfg_obj_t *zones = NULL; @@ -3864,8 +3937,10 @@ bind9_check_namedconf(const cfg_obj_t *config, isc_log_t *logctx, } tresult = isc_symtab_create(mctx, 100, NULL, NULL, ISC_TRUE, &symtab); - if (tresult != ISC_R_SUCCESS) + if (tresult != ISC_R_SUCCESS) { result = tresult; + goto cleanup; + } for (velement = cfg_list_first(views); velement != NULL; velement = cfg_list_next(velement)) @@ -3923,14 +3998,10 @@ bind9_check_namedconf(const cfg_obj_t *config, isc_log_t *logctx, } if (tresult == ISC_R_SUCCESS) tresult = check_viewconf(config, voptions, key, vclass, - files, logctx, mctx); + files, inview, logctx, mctx); if (tresult != ISC_R_SUCCESS) result = ISC_R_FAILURE; } - if (symtab != NULL) - isc_symtab_destroy(&symtab); - if (files != NULL) - isc_symtab_destroy(&files); if (views != NULL && options != NULL) { obj = NULL; @@ -4032,5 +4103,13 @@ bind9_check_namedconf(const cfg_obj_t *config, isc_log_t *logctx, } } +cleanup: + if (symtab != NULL) + isc_symtab_destroy(&symtab); + if (inview != NULL) + isc_symtab_destroy(&inview); + if (files != NULL) + isc_symtab_destroy(&files); + return (result); } From f7d346357e93433947e953fb4fdfe736e3a283cb Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Fri, 25 May 2018 16:29:04 +1000 Subject: [PATCH 2/2] CHANGES, copyright --- CHANGES | 3 +++ util/copyrights | 1 + 2 files changed, 4 insertions(+) diff --git a/CHANGES b/CHANGES index 6cf2b27c9e..f8f12d5353 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +4979. [bug] Named-checkconf failed to detect bad in-view targets. + [GL #288] + 4978. [test] Fix error handling and resolver configuration in the "rpz" system test. [GL #312] diff --git a/util/copyrights b/util/copyrights index 81498f6a33..56895425e6 100644 --- a/util/copyrights +++ b/util/copyrights @@ -676,6 +676,7 @@ ./bin/tests/system/checkconf/bad-sharedwritable2.conf CONF-C 2014,2016,2018 ./bin/tests/system/checkconf/bad-sharedzone1.conf CONF-C 2013,2016,2018 ./bin/tests/system/checkconf/bad-sharedzone2.conf CONF-C 2013,2016,2018 +./bin/tests/system/checkconf/bad-sharedzone3.conf CONF-C 2018 ./bin/tests/system/checkconf/bad-sig-validity.conf CONF-C 2018 ./bin/tests/system/checkconf/bad-tsig.conf CONF-C 2012,2013,2016,2018 ./bin/tests/system/checkconf/bad-update-policy1.conf CONF-C 2018