Commit 7a47e4d8 authored by Evan Hunt's avatar Evan Hunt
Browse files

restore filter-aaaa syntax checking

- added functionality to check hook parameters in named-checkconf,
  and restored the checkconf tests that were removed from the
  filter-aaaa test.
parent b94945e6
......@@ -66,7 +66,7 @@ named-checkzone.@O@: named-checkzone.c
named-checkconf@EXEEXT@: named-checkconf.@O@ check-tool.@O@ ${ISCDEPLIBS} \
${NSDEPENDLIBS} ${DNSDEPLIBS} ${ISCCFGDEPLIBS} ${BIND9DEPLIBS}
export BASEOBJS="named-checkconf.@O@ check-tool.@O@"; \
export LIBS0="${NSLIBS} ${BIND9LIBS} ${ISCCFGLIBS} ${DNSLIBS}"; \
export LIBS0="${BIND9LIBS} ${NSLIBS} ${ISCCFGLIBS} ${DNSLIBS}"; \
${FINALBUILDCMD}
named-checkzone@EXEEXT@: named-checkzone.@O@ check-tool.@O@ ${ISCDEPLIBS} \
......
......@@ -46,6 +46,8 @@
static const char *program = "named-checkconf";
static bool loadhooks = true;
isc_log_t *logc = NULL;
#define CHECK(r)\
......@@ -562,7 +564,7 @@ main(int argc, char **argv) {
/*
* Process memory debugging argument first.
*/
#define CMDLINE_FLAGS "dhjlm:t:pvxz"
#define CMDLINE_FLAGS "cdhjlm:t:pvxz"
while ((c = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) {
switch (c) {
case 'm':
......@@ -587,6 +589,10 @@ main(int argc, char **argv) {
while ((c = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != EOF) {
switch (c) {
case 'c':
loadhooks = false;
break;
case 'd':
debug++;
break;
......@@ -677,9 +683,10 @@ main(int argc, char **argv) {
ISC_R_SUCCESS)
exit(1);
result = bind9_check_namedconf(config, logc, mctx);
if (result != ISC_R_SUCCESS)
result = bind9_check_namedconf(config, loadhooks, logc, mctx);
if (result != ISC_R_SUCCESS) {
exit_status = 1;
}
if (result == ISC_R_SUCCESS && (load_zones || list_zones)) {
result = load_zones_fromconfig(config, mctx, list_zones);
......
......@@ -52,7 +52,7 @@
<refsynopsisdiv>
<cmdsynopsis sepchar=" ">
<command>named-checkconf</command>
<arg choice="opt" rep="norepeat"><option>-hjlvz</option></arg>
<arg choice="opt" rep="norepeat"><option>-chjlvz</option></arg>
<arg choice="opt" rep="norepeat"><option>-p</option>
<arg choice="opt" rep="norepeat"><option>-x</option>
</arg></arg>
......@@ -114,6 +114,17 @@
</listitem>
</varlistentry>
<varlistentry>
<term>-c</term>
<listitem>
<para>
Check "core" configuration only. This suppresses the loading
of hook modules, and causes all parameters to
<command>hook</command> statements to be ignored.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>-p</term>
<listitem>
......
......@@ -249,8 +249,52 @@ parse_filter_aaaa_on(const cfg_obj_t *param_obj, const char *param_name,
return (result);
}
static isc_result_t
check_syntax(cfg_obj_t *fmap, const void *cfg,
isc_mem_t *mctx, isc_log_t *lctx, void *actx)
{
isc_result_t result = ISC_R_SUCCESS;
const cfg_obj_t *aclobj = NULL;
dns_acl_t *acl = NULL;
filter_aaaa_t f4 = NONE, f6 = NONE;
cfg_map_get(fmap, "filter-aaaa", &aclobj);
if (aclobj == NULL) {
return (result);
}
CHECK(cfg_acl_fromconfig(aclobj, (const cfg_obj_t *) cfg,
lctx, (cfg_aclconfctx_t *) actx,
mctx, 0, &acl));
CHECK(parse_filter_aaaa_on(fmap, "filter-aaaa-on-v4", &f4));
CHECK(parse_filter_aaaa_on(fmap, "filter-aaaa-on-v6", &f6));
if ((f4 != NONE || f6 != NONE) && dns_acl_isnone(acl)) {
cfg_obj_log(aclobj, lctx, ISC_LOG_WARNING,
"\"filter-aaaa\" is 'none;' but "
"either filter-aaaa-on-v4 or filter-aaaa-on-v6 "
"is enabled");
result = ISC_R_FAILURE;
} else if (f4 == NONE && f6 == NONE && !dns_acl_isnone(acl)) {
cfg_obj_log(aclobj, lctx, ISC_LOG_WARNING,
"\"filter-aaaa\" is set but "
"neither filter-aaaa-on-v4 or filter-aaaa-on-v6 "
"is enabled");
result = ISC_R_FAILURE;
}
cleanup:
if (acl != NULL) {
dns_acl_detach(&acl);
}
return (result);
}
static isc_result_t
parse_parameters(filter_instance_t *inst, const char *parameters,
const char *cfg_file, unsigned long cfg_line,
const void *cfg, void *actx, ns_hookctx_t *hctx)
{
isc_result_t result = ISC_R_SUCCESS;
......@@ -263,8 +307,10 @@ parse_parameters(filter_instance_t *inst, const char *parameters,
isc_buffer_constinit(&b, parameters, strlen(parameters));
isc_buffer_add(&b, strlen(parameters));
CHECK(cfg_parse_buffer(parser, &b, &cfg_type_parameters,
&param_obj));
CHECK(cfg_parse_buffer4(parser, &b, cfg_file, cfg_line,
&cfg_type_parameters, 0, &param_obj));
CHECK(check_syntax(param_obj, cfg, hctx->mctx, hctx->lctx, actx));
CHECK(parse_filter_aaaa_on(param_obj, "filter-aaaa-on-v4",
&inst->v4_aaaa));
......@@ -323,7 +369,9 @@ hook_register(const char *parameters,
isc_mem_attach(hctx->mctx, &inst->mctx);
if (parameters != NULL) {
CHECK(parse_parameters(inst, parameters, cfg, actx, hctx));
CHECK(parse_parameters(inst, parameters,
cfg_file, cfg_line,
cfg, actx, hctx));
}
CHECK(isc_mempool_create(hctx->mctx, sizeof(filter_data_t),
......@@ -358,6 +406,34 @@ hook_register(const char *parameters,
return (result);
}
isc_result_t
hook_check(const char *parameters, const char *cfg_file, unsigned long cfg_line,
const void *cfg, isc_mem_t *mctx, isc_log_t *lctx, void *actx)
{
isc_result_t result = ISC_R_SUCCESS;
cfg_parser_t *parser = NULL;
cfg_obj_t *param_obj = NULL;
isc_buffer_t b;
CHECK(cfg_parser_create(mctx, lctx, &parser));
isc_buffer_constinit(&b, parameters, strlen(parameters));
isc_buffer_add(&b, strlen(parameters));
CHECK(cfg_parse_buffer4(parser, &b, cfg_file, cfg_line,
&cfg_type_parameters, 0, &param_obj));
CHECK(check_syntax(param_obj, cfg, mctx, lctx, actx));
cleanup:
if (param_obj != NULL) {
cfg_obj_destroy(parser, &param_obj);
}
if (parser != NULL) {
cfg_parser_destroy(&parser);
}
return (result);
}
/*
* Called by ns_module_unload(); frees memory allocated by
* the module when it was registered.
......
......@@ -5308,7 +5308,7 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist,
#ifdef HAVE_DLOPEN
if (hook_list != NULL) {
CHECK(ns_hook_createctx(mctx, &hctx));
CHECK(ns_hook_createctx(mctx, view, &hctx));
INSIST(view->hooktable == NULL);
CHECK(ns_hooktable_create(view->mctx,
......@@ -8102,8 +8102,12 @@ load_configuration(const char *filename, named_server_t *server,
/*
* Check the validity of the configuration.
*
* (Ignore hook module parameters for now; they will be
* checked later when the modules are actually loaded and
* registered.)
*/
CHECK(bind9_check_namedconf(config, named_g_lctx, named_g_mctx));
CHECK(bind9_check_namedconf(config, false, named_g_lctx, named_g_mctx));
/*
* Fill in the maps array, used for resolving defaults.
......
/*
* 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.
*/
hook query "../../../hooks/lib/filter-aaaa.so" {
filter-aaaa-on-v4 yes;
filter-aaaa { none; };
};
/*
* 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.
*/
hook query "../../../hooks/lib/filter-aaaa.so" {
/*
* While this matches the defaults, it is not a good configuration
* to have in named.conf as the two options contradict each other
* indicating a error on behalf of the operator.
*
* The default is to have filter-aaaa-on-v4 off, but if it is turned
* on then it applies to all IPv4 queries. This results in
* contradictory defaults.
*/
filter-aaaa-on-v4 no;
filter-aaaa { any; };
};
/*
* 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 myview {
hook query "../../../hooks/lib/filter-aaaa.so" {
filter-aaaa-on-v4 no;
filter-aaaa { any; };
};
};
/*
* 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 myview {
hook query "../../../hooks/lib/filter-aaaa.so" {
filter-aaaa-on-v4 yes;
filter-aaaa { none; };
};
};
/*
* 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.
*/
plugin query "../../../plugins/lib/filter-aaaa.so" {
filter-aaaa-on-v4 yes;
filter-aaaa { 1.0.0.0/8; };
};
view myview {
match-clients { any; };
};
/*
* 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.
*/
hook query "../../../hooks/lib/filter-aaaa.so" {
filter-aaaa-on-v4 yes;
};
/*
* 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.
*/
hook query "../../../hooks/lib/filter-aaaa.so" {
filter-aaaa-on-v4 break-dnssec;
};
/*
* 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.
*/
hook query "../../../hooks/lib/filter-aaaa.so" {
filter-aaaa-on-v4 break-dnssec;
filter-aaaa { 1.0.0.0/8; };
};
/*
* 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.
*/
hook query "../../../hooks/lib/filter-aaaa.so" {
filter-aaaa-on-v4 yes;
filter-aaaa { 1.0.0.0/8; };
};
/*
* 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 myview {
hook query "../../../hooks/lib/filter-aaaa.so" {
filter-aaaa-on-v4 yes;
filter-aaaa { 1.0.0.0/8; };
};
};
......@@ -20,6 +20,26 @@ rm -f dig.out.*
DIGOPTS="+tcp +noadd +nosea +nostat +nocmd -p ${PORT}"
RNDCCMD="$RNDC -c $SYSTEMTESTTOP/common/rndc.conf -p ${CONTROLPORT} -s"
for conf in conf/good*.conf
do
n=`expr $n + 1`
echo_i "checking that $conf is accepted ($n)"
ret=0
$CHECKCONF "$conf" || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=`expr $status + $ret`
done
for conf in conf/bad*.conf
do
n=`expr $n + 1`
echo_i "checking that $conf is rejected ($n)"
ret=0
$CHECKCONF "$conf" >/dev/null && ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=`expr $status + $ret`
done
#
# Authoritative tests against:
# filter-aaaa-on-v4 yes;
......
......@@ -18,7 +18,7 @@ VERSION=@BIND9_VERSION@
@BIND9_MAKE_INCLUDES@
CINCLUDES = -I. ${BIND9_INCLUDES} ${DNS_INCLUDES} ${ISC_INCLUDES} \
${ISCCFG_INCLUDES} @OPENSSL_INCLUDES@
${ISCCFG_INCLUDES} ${NS_INCLUDES} @OPENSSL_INCLUDES@
CDEFINES =
CWARNINGS =
......@@ -26,6 +26,7 @@ CWARNINGS =
ISCLIBS = ../../lib/isc/libisc.@A@ @OPENSSL_LIBS@
ISCCFGLIBS = ../../lib/isccfg/libisccfg.@A@
DNSLIBS = ../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@
NSLIBS = ../../lib/ns/libns.@A@
ISCDEPLIBS = ../../lib/isc/libisc.@A@
ISCCFGDEPLIBS = ../../lib/isccfg/libisccfg.@A@
......@@ -61,8 +62,8 @@ libbind9.la: ${OBJS} ${ISCCFGDEPLIBS} ${ISCDEPLIBS} ${DNSDEPLIBS}
${LIBTOOL_MODE_LINK} \
${CC} ${ALL_CFLAGS} ${LDFLAGS} -o libbind9.la -rpath ${libdir} \
-version-info ${LIBINTERFACE}:${LIBREVISION}:${LIBAGE} \
${OBJS} ${DNSLIBS} ${ISCCFGLIBS} ${ISCLIBS} @DNS_CRYPTO_LIBS@ \
${LIBS}
${OBJS} ${NSLIBS} ${DNSLIBS} ${ISCCFGLIBS} ${ISCLIBS} \
@DNS_CRYPTO_LIBS@ ${LIBS}
timestamp: libbind9.@A@
touch timestamp
......
......@@ -54,6 +54,8 @@
#include <isccfg/grammar.h>
#include <isccfg/namedconf.h>
#include <ns/hooks.h>
#include <bind9/check.h>
static unsigned char dlviscorg_ndata[] = "\003dlv\003isc\003org";
......@@ -3349,7 +3351,7 @@ 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_symtab_t *inview,
isc_symtab_t *files, bool checkhooks, isc_symtab_t *inview,
isc_log_t *logctx, isc_mem_t *mctx)
{
const cfg_obj_t *zones = NULL;
......@@ -3365,6 +3367,7 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions,
const cfg_obj_t *obj;
const cfg_obj_t *options = NULL;
const cfg_obj_t *opts = NULL;
const cfg_obj_t *hook_list = NULL;
bool enablednssec, enablevalidation;
const char *valstr = "no";
unsigned int tflags, mflags;
......@@ -3662,6 +3665,56 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions,
if (tresult != ISC_R_SUCCESS)
result = tresult;
/*
* Load hook modules.
*/
if (checkhooks) {
if (voptions != NULL) {
(void)cfg_map_get(voptions, "hook", &hook_list);
} else {
(void)cfg_map_get(config, "hook", &hook_list);
}
}
#ifdef HAVE_DLOPEN
for (element = cfg_list_first(hook_list);
element != NULL;
element = cfg_list_next(element))
{
const cfg_obj_t *hook = cfg_listelt_value(element);
const char *type, *library;
const char *parameters = NULL;
/* Get the path to the hook module. */
obj = cfg_tuple_get(hook, "type");
type = cfg_obj_asstring(obj);
/* Only query hooks are supported currently. */
if (strcasecmp(type, "query") != 0) {
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
"unsupported hook type");
return (ISC_R_FAILURE);
}
library = cfg_obj_asstring(cfg_tuple_get(hook, "library"));
obj = cfg_tuple_get(hook, "parameters");
if (obj != NULL && cfg_obj_isstring(obj)) {
parameters = cfg_obj_asstring(obj);
}
tresult = ns_module_check(library, parameters,
cfg_obj_file(obj), cfg_obj_line(obj),
config, mctx, logctx, actx);
if (tresult != ISC_R_SUCCESS) {
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
"%s: module check failed: %s",
library, isc_result_totext(tresult));
result = tresult;
}
}
#endif /* HAVE_DLOPEN */
cleanup:
if (symtab != NULL)
isc_symtab_destroy(&symtab);
......@@ -3916,8 +3969,8 @@ bind9_check_controls(const cfg_obj_t *config, isc_log_t *logctx,
}
isc_result_t
bind9_check_namedconf(const cfg_obj_t *config, isc_log_t *logctx,
isc_mem_t *mctx)
bind9_check_namedconf(const cfg_obj_t *config, bool hooks,
isc_log_t *logctx, isc_mem_t *mctx)
{
const cfg_obj_t *options = NULL;
const cfg_obj_t *views = NULL;
......@@ -3973,13 +4026,15 @@ bind9_check_namedconf(const cfg_obj_t *config, isc_log_t *logctx,
}
if (views == NULL) {
tresult = check_viewconf(config, NULL, NULL, dns_rdataclass_in,
files, inview, logctx, mctx);
tresult = check_viewconf(config, NULL, NULL,
dns_rdataclass_in, files,
hooks, inview, logctx, mctx);
if (result == ISC_R_SUCCESS && tresult != ISC_R_SUCCESS) {
result = ISC_R_FAILURE;
}
} else {
const cfg_obj_t *zones = NULL;
const cfg_obj_t *hooks = NULL;
(void)cfg_map_get(config, "zone", &zones);
if (zones != NULL) {
......@@ -3988,6 +4043,14 @@ bind9_check_namedconf(const cfg_obj_t *config, isc_log_t *logctx,
"all zones must be in views");
result = ISC_R_FAILURE;
}
(void)cfg_map_get(config, "hook", &hooks);
if (hooks != NULL) {
cfg_obj_log(hooks, logctx, ISC_LOG_ERROR,
"when using 'view' statements, "
"all hooks must be defined in views");
result = ISC_R_FAILURE;
}
}
tresult = isc_symtab_create(mctx, 100, NULL, NULL, true, &symtab);
......@@ -4051,8 +4114,9 @@ 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, inview, logctx, mctx);
tresult = check_viewconf(config, voptions, key,
vclass, files, hooks,
inview, logctx, mctx);
if (tresult != ISC_R_SUCCESS)
result = ISC_R_FAILURE;
}
......
......@@ -35,12 +35,15 @@
ISC_LANG_BEGINDECLS
isc_result_t
bind9_check_namedconf(const cfg_obj_t *config, isc_log_t *logctx,
isc_mem_t *mctx);
bind9_check_namedconf(const cfg_obj_t *config, bool check_hooks,
isc_log_t *logctx, isc_mem_t *mctx);
/*%<
* Check the syntactic validity of a configuration parse tree generated from
* a named.conf file.
*
* If 'check_hooks' is true, load hook modules and check the validity of their
* parameters as well.
*
* Requires:
*\li config is a valid parse tree
*
......
......@@ -30,6 +30,8 @@
#include <isc/util.h>