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.
This commit is contained in:
Evan Hunt 2018-11-02 23:28:25 -07:00
parent b94945e606
commit 7a47e4d85f
22 changed files with 435 additions and 30 deletions

View file

@ -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} \

View file

@ -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);

View file

@ -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>

View file

@ -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.

View file

@ -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.

View file

@ -0,0 +1,15 @@
/*
* 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; };
};

View file

@ -0,0 +1,24 @@
/*
* 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; };
};

View file

@ -0,0 +1,17 @@
/*
* 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; };
};
};

View file

@ -0,0 +1,17 @@
/*
* 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; };
};
};

View file

@ -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.
*/
plugin query "../../../plugins/lib/filter-aaaa.so" {
filter-aaaa-on-v4 yes;
filter-aaaa { 1.0.0.0/8; };
};
view myview {
match-clients { any; };
};

View file

@ -0,0 +1,14 @@
/*
* 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;
};

View file

@ -0,0 +1,14 @@
/*
* 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;
};

View file

@ -0,0 +1,15 @@
/*
* 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; };
};

View file

@ -0,0 +1,15 @@
/*
* 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; };
};

View file

@ -0,0 +1,17 @@
/*
* 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; };
};
};

View file

@ -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;

View file

@ -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

View file

@ -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;
}

View file

@ -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
*

View file

@ -30,6 +30,8 @@
#include <isc/util.h>
#include <isc/types.h>
#include <dns/view.h>
#include <ns/hooks.h>
#include <ns/log.h>
#include <ns/query.h>
@ -47,6 +49,7 @@ struct ns_module {
void *handle;
void *inst;
char *modpath;
ns_hook_check_t *check_func;
ns_hook_register_t *register_func;
ns_hook_destroy_t *destroy_func;
LINK(ns_module_t) link;
@ -97,6 +100,7 @@ load_library(isc_mem_t *mctx, const char *modpath, ns_module_t **hmodp) {
isc_result_t result;
void *handle = NULL;
ns_module_t *hmod = NULL;
ns_hook_check_t *check_func = NULL;
ns_hook_register_t *register_func = NULL;
ns_hook_destroy_t *destroy_func = NULL;
ns_hook_version_t *version_func = NULL;
@ -104,7 +108,7 @@ load_library(isc_mem_t *mctx, const char *modpath, ns_module_t **hmodp) {
REQUIRE(hmodp != NULL && *hmodp == NULL);
flags = RTLD_NOW | RTLD_LOCAL;
flags = RTLD_LAZY | RTLD_LOCAL;
#ifdef RTLD_DEEPBIND
flags |= RTLD_DEEPBIND;
#endif
@ -136,16 +140,19 @@ load_library(isc_mem_t *mctx, const char *modpath, ns_module_t **hmodp) {
CHECK(ISC_R_FAILURE);
}
CHECK(load_symbol(handle, modpath, "hook_check",
(void **)&check_func));
CHECK(load_symbol(handle, modpath, "hook_register",
(void **)&register_func));
CHECK(load_symbol(handle, modpath, "hook_destroy",
(void **)&destroy_func));
hmod = isc_mem_get(mctx, sizeof(*hmod));
hmod->mctx = NULL;
memset(hmod, 0, sizeof(*hmod));
isc_mem_attach(mctx, &hmod->mctx);
hmod->handle = handle;
hmod->modpath = isc_mem_strdup(hmod->mctx, modpath);
hmod->check_func = check_func;
hmod->register_func = register_func;
hmod->destroy_func = destroy_func;
@ -262,7 +269,7 @@ load_library(isc_mem_t *mctx, const char *modpath, ns_module_t **hmodp) {
(void **)&destroy_func));
hmod = isc_mem_get(mctx, sizeof(*hmod));
hmod->mctx = NULL;
memset(hmod, 0, sizeof(*hmod));
isc_mem_attach(mctx, &hmod->mctx);
hmod->handle = handle;
hmod->modpath = isc_mem_strdup(hmod->mctx, modpath);
@ -377,7 +384,28 @@ cleanup:
}
isc_result_t
ns_hook_createctx(isc_mem_t *mctx, ns_hookctx_t **hctxp) {
ns_module_check(const char *modpath, 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;
ns_module_t *hmod = NULL;
CHECK(load_library(mctx, modpath, &hmod));
result = hmod->check_func(parameters, cfg_file, cfg_line,
cfg, mctx, lctx, actx);
cleanup:
if (hmod != NULL) {
unload_library(&hmod);
}
return (result);
}
isc_result_t
ns_hook_createctx(isc_mem_t *mctx, dns_view_t *view, ns_hookctx_t **hctxp) {
ns_hookctx_t *hctx = NULL;
REQUIRE(hctxp != NULL && *hctxp == NULL);
@ -386,6 +414,8 @@ ns_hook_createctx(isc_mem_t *mctx, ns_hookctx_t **hctxp) {
memset(hctx, 0, sizeof(*hctx));
hctx->lctx = ns_lctx;
dns_view_attach(view, &hctx->view);
isc_mem_attach(mctx, &hctx->mctx);
hctx->magic = NS_HOOKCTX_MAGIC;
@ -405,6 +435,7 @@ ns_hook_destroyctx(ns_hookctx_t **hctxp) {
hctx->magic = 0;
dns_view_detach(&hctx->view);
isc_mem_putanddetach(&hctx->mctx, hctx, sizeof(*hctx));
}

View file

@ -233,6 +233,7 @@ LIBNS_EXTERNAL_DATA extern ns_hooktable_t *ns__hook_table;
*/
typedef struct ns_hookctx {
unsigned int magic;
dns_view_t *view;
isc_mem_t *mctx;
isc_log_t *lctx;
} ns_hookctx_t;
@ -272,14 +273,23 @@ ns_hook_register_t(const char *parameters,
*\li Other errors are possible
*/
typedef void ns_hook_destroy_t(void **instp);
typedef void
ns_hook_destroy_t(void **instp);
/*%<
* Destroy a module instance.
*
* '*instp' must be set to NULL by the function before it returns.
*/
typedef int ns_hook_version_t(void);
typedef isc_result_t
ns_hook_check_t(const char *parameters, const char *file, unsigned long line,
const void *cfg, isc_mem_t *mctx, isc_log_t *lctx, void *actx);
/*%<
* Check the validity of 'parameters'.
*/
typedef int
ns_hook_version_t(void);
/*%<
* Return the API version number a hook module was compiled with.
*
@ -291,13 +301,13 @@ typedef int ns_hook_version_t(void);
/*%
* Prototypes for API functions to be defined in each module.
*/
ns_hook_check_t hook_check;
ns_hook_destroy_t hook_destroy;
ns_hook_register_t hook_register;
ns_hook_version_t hook_version;
isc_result_t
ns_hook_createctx(isc_mem_t *mctx, ns_hookctx_t **hctxp);
ns_hook_createctx(isc_mem_t *mctx, dns_view_t *view, ns_hookctx_t **hctxp);
void
ns_hook_destroyctx(ns_hookctx_t **hctxp);
/*%<
@ -327,6 +337,16 @@ ns_module_load(const char *modpath, const char *parameters,
* created by the module's hook_register function.
*/
isc_result_t
ns_module_check(const char *modpath, const char *parameters,
const char *cfg_file, unsigned long cfg_line,
const void *cfg, isc_mem_t *mctx, isc_log_t *lctx, void *actx);
/*%<
* Open the module at 'modpath' and check the validity of
* 'parameters', logging any errors or warnings found, then
* close it without configuring it.
*/
void
ns_modlist_create(isc_mem_t *mctx, ns_modlist_t **listp);
/*%<

View file

@ -79,6 +79,7 @@ ns_log_init
ns_log_setcontext
ns_modlist_create
ns_modlist_free
ns_module_check
ns_module_load
ns_notify_start
ns_query_cancel