diff --git a/CHANGES b/CHANGES index 2e2f9865e8..3eb045a7ce 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +3958. [bug] Detect when writeable files have multiple references + in named.conf. [RT #37172] + 3957. [bug] "dnssec-keygen -S" failed for ECCGOST, ECDSAP256SHA256 and ECDSAP384SHA384. [RT #37183] diff --git a/bin/tests/system/checkconf/bad-sharedwritable1.conf b/bin/tests/system/checkconf/bad-sharedwritable1.conf new file mode 100644 index 0000000000..4997d51a73 --- /dev/null +++ b/bin/tests/system/checkconf/bad-sharedwritable1.conf @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +zone a { + type master; + file "shared.db"; +}; +zone b { + type slave; + file "shared.db"; + masters { 1.2.3.4; }; +}; diff --git a/bin/tests/system/checkconf/bad-sharedwritable2.conf b/bin/tests/system/checkconf/bad-sharedwritable2.conf new file mode 100644 index 0000000000..c9bdc43a63 --- /dev/null +++ b/bin/tests/system/checkconf/bad-sharedwritable2.conf @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +zone a { + type slave; + file "shared.db"; + masters { 1.2.3.4; }; +}; +zone b { + type slave; + file "shared.db"; + masters { 1.2.3.4; }; +}; diff --git a/bin/tests/system/checkconf/good.conf b/bin/tests/system/checkconf/good.conf index be652696b0..d14ccd8580 100644 --- a/bin/tests/system/checkconf/good.conf +++ b/bin/tests/system/checkconf/good.conf @@ -93,7 +93,7 @@ view "second" { }; zone "example1" { type master; - file "yyy"; + file "zzz"; update-policy local; zone-statistics yes; }; diff --git a/bin/tests/system/checkconf/max-ttl.conf b/bin/tests/system/checkconf/max-ttl.conf index 694ad2b518..53ce380063 100644 --- a/bin/tests/system/checkconf/max-ttl.conf +++ b/bin/tests/system/checkconf/max-ttl.conf @@ -35,4 +35,3 @@ zone "maxttl3.example" { file "maxttl-bad.db"; max-zone-ttl 120; }; - diff --git a/bin/tests/system/inline/clean.sh b/bin/tests/system/inline/clean.sh index b6861d2fd9..49eb0923ed 100644 --- a/bin/tests/system/inline/clean.sh +++ b/bin/tests/system/inline/clean.sh @@ -25,6 +25,8 @@ rm -f ns2/bits.db.jnl rm -f ns1/signer.out rm -f ns2/retransfer.db rm -f ns2/retransfer.db.jnl +rm -f ns2/retransfer3.db +rm -f ns2/retransfer3.db.jnl rm -f ns3/K* rm -f ns3/bits.bk rm -f ns3/bits.bk.jnl diff --git a/bin/tests/system/inline/ns2/named.conf b/bin/tests/system/inline/ns2/named.conf index c7e8d47bc4..4001749193 100644 --- a/bin/tests/system/inline/ns2/named.conf +++ b/bin/tests/system/inline/ns2/named.conf @@ -51,7 +51,7 @@ zone "retransfer" { zone "retransfer3" { type master; - file "retransfer.db"; + file "retransfer3.db"; allow-update { any; }; notify no; }; diff --git a/bin/tests/system/inline/setup.sh b/bin/tests/system/inline/setup.sh index 3a8ac278ee..fbbdb3c0bc 100644 --- a/bin/tests/system/inline/setup.sh +++ b/bin/tests/system/inline/setup.sh @@ -25,6 +25,7 @@ rm -f ns1/root.db.signed touch ns2/trusted.conf cp ns2/bits.db.in ns2/bits.db cp ns2/bits.db.in ns2/retransfer.db +cp ns2/bits.db.in ns2/retransfer3.db rm -f ns2/bits.db.jnl cp ns3/master.db.in ns3/master.db diff --git a/lib/bind9/check.c b/lib/bind9/check.c index e1081a5647..58668ae58b 100644 --- a/lib/bind9/check.c +++ b/lib/bind9/check.c @@ -62,6 +62,10 @@ #include +static isc_result_t +fileexist(const cfg_obj_t *obj, isc_symtab_t *symtab, isc_boolean_t writeable, + isc_log_t *logctxlogc); + static void freekey(char *key, unsigned int type, isc_symvalue_t value, void *userarg) { UNUSED(type); @@ -1504,8 +1508,8 @@ 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, - dns_rdataclass_t defclass, cfg_aclconfctx_t *actx, - isc_log_t *logctx, isc_mem_t *mctx) + isc_symtab_t *files, dns_rdataclass_t defclass, + cfg_aclconfctx_t *actx, isc_log_t *logctx, isc_mem_t *mctx) { const char *znamestr; const char *typestr; @@ -1523,6 +1527,7 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions, const cfg_listelt_t *element; isc_boolean_t dlz; dns_masterformat_t masterformat; + isc_boolean_t ddns = ISC_FALSE; static optionstable options[] = { { "allow-notify", SLAVEZONE | CHECKACL }, @@ -1827,7 +1832,7 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions, * Master zones can't have both "allow-update" and "update-policy". */ if (ztype == MASTERZONE || ztype == SLAVEZONE) { - isc_boolean_t ddns = ISC_FALSE, signing = ISC_FALSE; + isc_boolean_t signing = ISC_FALSE; isc_result_t res1, res2, res3; const cfg_obj_t *au = NULL; const char *arg; @@ -1853,7 +1858,6 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions, * we should also check for allow-update at the * view and options levels. */ - obj = NULL; if (res1 != ISC_R_SUCCESS && voptions != NULL) res1 = cfg_map_get(voptions, "allow-update", &au); if (res1 != ISC_R_SUCCESS && goptions != NULL) @@ -2153,8 +2157,8 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions, strcmp("rbt64", cfg_obj_asstring(obj)) == 0)))) { isc_result_t res1; - obj = NULL; - tresult = cfg_map_get(zoptions, "file", &obj); + const cfg_obj_t *fileobj = NULL; + tresult = cfg_map_get(zoptions, "file", &fileobj); obj = NULL; res1 = cfg_map_get(zoptions, "inline-signing", &obj); if ((tresult != ISC_R_SUCCESS && @@ -2165,6 +2169,16 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions, "zone '%s': missing 'file' entry", znamestr); result = tresult; + } else if (tresult == ISC_R_SUCCESS && + (ztype == SLAVEZONE || ddns)) { + tresult = fileexist(fileobj, files, ISC_TRUE, logctx); + if (tresult != ISC_R_SUCCESS) + result = tresult; + } else if (tresult == ISC_R_SUCCESS && + (ztype == MASTERZONE || ztype == HINTZONE)) { + tresult = fileexist(fileobj, files, ISC_FALSE, logctx); + if (tresult != ISC_R_SUCCESS) + result = tresult; } } @@ -2270,6 +2284,47 @@ bind9_check_key(const cfg_obj_t *key, isc_log_t *logctx) { return (ISC_R_SUCCESS); } +static isc_result_t +fileexist(const cfg_obj_t *obj, isc_symtab_t *symtab, isc_boolean_t writeable, + isc_log_t *logctx) +{ + isc_result_t result; + isc_symvalue_t symvalue; + unsigned int line; + const char *file; + + result = isc_symtab_lookup(symtab, cfg_obj_asstring(obj), 0, &symvalue); + if (result == ISC_R_SUCCESS) { + if (writeable) { + file = cfg_obj_file(symvalue.as_cpointer); + line = cfg_obj_line(symvalue.as_cpointer); + cfg_obj_log(obj, logctx, ISC_LOG_ERROR, + "writeable file '%s': already in use: " + "%s:%u", cfg_obj_asstring(obj), + file, line); + return (ISC_R_EXISTS); + } + result = isc_symtab_lookup(symtab, cfg_obj_asstring(obj), 2, + &symvalue); + if (result == ISC_R_SUCCESS) { + file = cfg_obj_file(symvalue.as_cpointer); + line = cfg_obj_line(symvalue.as_cpointer); + cfg_obj_log(obj, logctx, ISC_LOG_ERROR, + "writeable file '%s': already in use: " + "%s:%u", cfg_obj_asstring(obj), + file, line); + return (ISC_R_EXISTS); + } + return (ISC_R_SUCCESS); + } + + symvalue.as_cpointer = obj; + result = isc_symtab_define(symtab, cfg_obj_asstring(obj), + writeable ? 2 : 1, symvalue, + isc_symexists_reject); + return (result); +} + /* * Check key list for duplicates key names and that the key names * are valid domain names as these keys are used for TSIG. @@ -2577,7 +2632,7 @@ check_trusted_key(const cfg_obj_t *key, isc_boolean_t managed, static isc_result_t check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions, const char *viewname, dns_rdataclass_t vclass, - isc_log_t *logctx, isc_mem_t *mctx) + isc_symtab_t *files, isc_log_t *logctx, isc_mem_t *mctx) { const cfg_obj_t *zones = NULL; const cfg_obj_t *keys = NULL; @@ -2620,7 +2675,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, - vclass, actx, logctx, mctx); + files, vclass, actx, logctx, + mctx); if (tresult != ISC_R_SUCCESS) result = ISC_R_FAILURE; } @@ -3081,6 +3137,7 @@ bind9_check_namedconf(const cfg_obj_t *config, isc_log_t *logctx, isc_result_t result = ISC_R_SUCCESS; isc_result_t tresult; isc_symtab_t *symtab = NULL; + isc_symtab_t *files = NULL; static const char *builtin[] = { "localhost", "localnets", "any", "none"}; @@ -3108,9 +3165,19 @@ bind9_check_namedconf(const cfg_obj_t *config, isc_log_t *logctx, if (check_dual_stack(options, logctx) != ISC_R_SUCCESS) result = ISC_R_FAILURE; + /* + * Use case insensitve comparision as not all file systems are + * case sensitive. This will prevent people using FOO.DB and foo.db + * on case sensitive file systems but that shouldn't be a major issue. + */ + tresult = isc_symtab_create(mctx, 100, NULL, NULL, ISC_FALSE, + &files); + if (tresult != ISC_R_SUCCESS) + result = tresult; + if (views == NULL) { if (check_viewconf(config, NULL, NULL, dns_rdataclass_in, - logctx, mctx) != ISC_R_SUCCESS) + files, logctx, mctx) != ISC_R_SUCCESS) result = ISC_R_FAILURE; } else { const cfg_obj_t *zones = NULL; @@ -3181,13 +3248,15 @@ bind9_check_namedconf(const cfg_obj_t *config, isc_log_t *logctx, } } if (tresult == ISC_R_SUCCESS) - tresult = check_viewconf(config, voptions, key, - vclass, logctx, mctx); + tresult = check_viewconf(config, voptions, key, vclass, + files, 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;