diff --git a/CHANGES b/CHANGES index d7f1a0dad8..cc9027b024 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +4980. [bug] Named-checkconf failed to detect bad in-view targets. + [GL #288] + 4979. [bug] Non-libcap builds were not checking whether all requested capabilities are present in the permitted capability set. [GL #321] diff --git a/bin/named/main.c b/bin/named/main.c index 1434229659..39c2166fd3 100644 --- a/bin/named/main.c +++ b/bin/named/main.c @@ -1115,7 +1115,7 @@ setup(void) { isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_MAIN, ISC_LOG_NOTICE, "compiled with OpenSSL version: %s", - OPENSSL_VERSION_TEXT); + OPENSSL_VERSION_TEXT); #if !defined(LIBRESSL_VERSION_NUMBER) && \ OPENSSL_VERSION_NUMBER >= 0x10100000L /* 1.1.0 or higher */ isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL, 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 f6ba9369b5..210529423c 100644 --- a/lib/bind9/check.c +++ b/lib/bind9/check.c @@ -1882,14 +1882,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; @@ -1927,9 +1930,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; @@ -1969,27 +1973,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; } /* @@ -2007,7 +2014,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)); @@ -2024,6 +2033,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) { @@ -3178,7 +3238,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; @@ -3233,8 +3294,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; } @@ -3753,6 +3814,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"}; @@ -3783,13 +3845,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; @@ -3803,8 +3876,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)) @@ -3862,14 +3937,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; @@ -3971,5 +4042,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); } diff --git a/lib/isccfg/parser.c b/lib/isccfg/parser.c index 540cc981ae..acfa036760 100644 --- a/lib/isccfg/parser.c +++ b/lib/isccfg/parser.c @@ -636,8 +636,8 @@ cfg_parse_buffer3(cfg_parser_t *pctx, isc_buffer_t *buffer, isc_result_t cfg_parse_buffer4(cfg_parser_t *pctx, isc_buffer_t *buffer, - const char *file, unsigned int line, - const cfg_type_t *type, unsigned int flags, + const char *file, unsigned int line, + const cfg_type_t *type, unsigned int flags, cfg_obj_t **ret) { isc_result_t result; @@ -1728,19 +1728,19 @@ cfg_parse_mapbody(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) (clause->flags & CFG_CLAUSEFLAG_DEPRECATED) != 0) { cfg_parser_warning(pctx, 0, "option '%s' is deprecated", - clause->name); + clause->name); } if ((clause->flags & CFG_CLAUSEFLAG_OBSOLETE) != 0) { cfg_parser_warning(pctx, 0, "option '%s' is obsolete", - clause->name); + clause->name); } if ((clause->flags & CFG_CLAUSEFLAG_NOTIMP) != 0) { cfg_parser_warning(pctx, 0, "option '%s' is " - "not implemented", clause->name); + "not implemented", clause->name); } if ((clause->flags & CFG_CLAUSEFLAG_NYI) != 0) { cfg_parser_warning(pctx, 0, "option '%s' is " - "not implemented", clause->name); + "not implemented", clause->name); } if ((clause->flags & CFG_CLAUSEFLAG_NOOP) != 0) { cfg_parser_warning(pctx, 0, "option '%s' was not " diff --git a/util/copyrights b/util/copyrights index fc690558b1..c7d0b4f326 100644 --- a/util/copyrights +++ b/util/copyrights @@ -670,6 +670,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-tsig.conf CONF-C 2012,2013,2016,2018 ./bin/tests/system/checkconf/bad-update-policy1.conf CONF-C 2018 ./bin/tests/system/checkconf/bad-update-policy2.conf CONF-C 2018