From: Christopher Zimmermann Date: Sat, 11 Jan 2020 14:49:04 +0000 (+0100) Subject: allow privileged initialisation of modules X-Git-Tag: release-1.21.0rc1~48^2~8^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c96e4ca121f4b932701d5158d4d56f9fdef61757;p=thirdparty%2Funbound.git allow privileged initialisation of modules --- diff --git a/cachedb/cachedb.c b/cachedb/cachedb.c index eed4d5fd9..06738972f 100644 --- a/cachedb/cachedb.c +++ b/cachedb/cachedb.c @@ -229,7 +229,7 @@ cachedb_apply_cfg(struct cachedb_env* cachedb_env, struct config_file* cfg) } int -cachedb_init(struct module_env* env, int id) +cachedb_setup(struct module_env* env, int id) { struct cachedb_env* cachedb_env = (struct cachedb_env*)calloc(1, sizeof(struct cachedb_env)); @@ -268,7 +268,7 @@ cachedb_init(struct module_env* env, int id) } void -cachedb_deinit(struct module_env* env, int id) +cachedb_desetup(struct module_env* env, int id) { struct cachedb_env* cachedb_env; if(!env || !env->modinfo[id]) @@ -846,7 +846,7 @@ cachedb_get_mem(struct module_env* env, int id) */ static struct module_func_block cachedb_block = { "cachedb", - &cachedb_init, &cachedb_deinit, &cachedb_operate, + &module_dummy_init, &module_dummy_init, &cachedb_setup, &cachedb_desetup, &cachedb_operate, &cachedb_inform_super, &cachedb_clear, &cachedb_get_mem }; diff --git a/cachedb/cachedb.h b/cachedb/cachedb.h index 05c4368e6..117916e4b 100644 --- a/cachedb/cachedb.h +++ b/cachedb/cachedb.h @@ -90,9 +90,9 @@ struct cachedb_backend { #define CACHEDB_HASHSIZE 256 /* bit hash */ /** Init the cachedb module */ -int cachedb_init(struct module_env* env, int id); +int cachedb_setup(struct module_env* env, int id); /** Deinit the cachedb module */ -void cachedb_deinit(struct module_env* env, int id); +void cachedb_desetup(struct module_env* env, int id); /** Operate on an event on a query (in qstate). */ void cachedb_operate(struct module_qstate* qstate, enum module_ev event, int id, struct outbound_entry* outbound); diff --git a/daemon/daemon.c b/daemon/daemon.c index 5d4279259..05f16cc60 100644 --- a/daemon/daemon.c +++ b/daemon/daemon.c @@ -251,7 +251,7 @@ daemon_init(void) tzset(); #endif daemon->need_to_exit = 0; - modstack_init(&daemon->mods); + memset(&daemon->mods, 0, sizeof(daemon->mods)); if(!(daemon->env = (struct module_env*)calloc(1, sizeof(*daemon->env)))) { free(daemon); @@ -293,7 +293,7 @@ daemon_init(void) return daemon; } -int +int daemon_open_shared_ports(struct daemon* daemon) { log_assert(daemon); @@ -365,6 +365,22 @@ daemon_open_shared_ports(struct daemon* daemon) return 1; } +int +daemon_privileged(struct daemon* daemon) +{ + if(!daemon_open_shared_ports(daemon)) + fatal_exit("could not open ports"); + + daemon->env->cfg = daemon->cfg; + daemon->env->alloc = &daemon->superalloc; + daemon->env->worker = NULL; + if(!modstack_init(&daemon->mods, daemon->cfg->module_conf, + daemon->env)) { + fatal_exit("failed to init modules"); + } + return 1; +} + /** * Setup modules. setup module stack. * @param daemon: the daemon diff --git a/daemon/daemon.h b/daemon/daemon.h index 3effbafb7..7d8b99fc4 100644 --- a/daemon/daemon.h +++ b/daemon/daemon.h @@ -147,12 +147,13 @@ struct daemon { struct daemon* daemon_init(void); /** - * Open shared listening ports (if needed). + * Do daemon setup that needs privileges + * like opening privileged ports or opening device files. * The cfg member pointer must have been set for the daemon. * @param daemon: the daemon. * @return: false on error. */ -int daemon_open_shared_ports(struct daemon* daemon); +int daemon_privileged(struct daemon* daemon); /** * Fork workers and start service. diff --git a/daemon/unbound.c b/daemon/unbound.c index ceb3da6f5..32604728d 100644 --- a/daemon/unbound.c +++ b/daemon/unbound.c @@ -668,8 +668,8 @@ run_daemon(const char* cfgfile, int cmdline_verbose, int debug_mode, int need_pi config_lookup_uid(cfg); /* prepare */ - if(!daemon_open_shared_ports(daemon)) - fatal_exit("could not open ports"); + if(!daemon_privileged(daemon)) + fatal_exit("could not do privileged setup"); if(!done_setup) { perform_setup(daemon, cfg, debug_mode, &cfgfile, need_pidfile); done_setup = 1; diff --git a/dns64/dns64.c b/dns64/dns64.c index 5c70119a5..97ecce4b0 100644 --- a/dns64/dns64.c +++ b/dns64/dns64.c @@ -394,7 +394,7 @@ dns64_apply_cfg(struct dns64_env* dns64_env, struct config_file* cfg) * \param id This instance's ID number. */ int -dns64_init(struct module_env* env, int id) +dns64_setup(struct module_env* env, int id) { struct dns64_env* dns64_env = (struct dns64_env*)calloc(1, sizeof(struct dns64_env)); @@ -428,7 +428,7 @@ free_ignore_aaaa_node(rbnode_type* node, void* ATTR_UNUSED(arg)) * \param id This instance's ID number. */ void -dns64_deinit(struct module_env* env, int id) +dns64_desetup(struct module_env* env, int id) { struct dns64_env* dns64_env; if (!env) @@ -1019,8 +1019,8 @@ dns64_get_mem(struct module_env* env, int id) */ static struct module_func_block dns64_block = { "dns64", - &dns64_init, &dns64_deinit, &dns64_operate, &dns64_inform_super, - &dns64_clear, &dns64_get_mem + &module_dummy_init, &module_dummy_init, &dns64_setup, &dns64_desetup, + &dns64_operate, &dns64_inform_super, &dns64_clear, &dns64_get_mem }; /** diff --git a/dns64/dns64.h b/dns64/dns64.h index 2f0c01a22..532a5bed3 100644 --- a/dns64/dns64.h +++ b/dns64/dns64.h @@ -50,10 +50,10 @@ struct module_func_block *dns64_get_funcblock(void); /** dns64 init */ -int dns64_init(struct module_env* env, int id); +int dns64_setup(struct module_env* env, int id); /** dns64 deinit */ -void dns64_deinit(struct module_env* env, int id); +void dns64_desetup(struct module_env* env, int id); /** dns64 operate on a query */ void dns64_operate(struct module_qstate* qstate, enum module_ev event, int id, diff --git a/edns-subnet/subnetmod.c b/edns-subnet/subnetmod.c index 37dc550cd..cb2969352 100644 --- a/edns-subnet/subnetmod.c +++ b/edns-subnet/subnetmod.c @@ -188,7 +188,7 @@ subnet_markdel(void* key) } int -subnetmod_init(struct module_env *env, int id) +subnetmod_setup(struct module_env *env, int id) { struct subnet_env *sn_env = (struct subnet_env*)calloc(1, sizeof(struct subnet_env)); @@ -246,7 +246,7 @@ subnetmod_init(struct module_env *env, int id) } void -subnetmod_deinit(struct module_env *env, int id) +subnetmod_desetup(struct module_env *env, int id) { struct subnet_env *sn_env; if(!env || !env->modinfo[id]) @@ -846,8 +846,10 @@ subnetmod_get_mem(struct module_env *env, int id) * The module function block */ static struct module_func_block subnetmod_block = { - "subnet", &subnetmod_init, &subnetmod_deinit, &subnetmod_operate, - &subnetmod_inform_super, &subnetmod_clear, &subnetmod_get_mem + "subnet", + &module_dummy_init, &module_dummy_init, &subnetmod_setup, + &subnetmod_desetup, &subnetmod_operate, &subnetmod_inform_super, + &subnetmod_clear, &subnetmod_get_mem }; struct module_func_block* diff --git a/edns-subnet/subnetmod.h b/edns-subnet/subnetmod.h index e408627b0..7936d889e 100644 --- a/edns-subnet/subnetmod.h +++ b/edns-subnet/subnetmod.h @@ -97,10 +97,10 @@ size_t msg_cache_sizefunc(void* k, void* d); struct module_func_block* subnetmod_get_funcblock(void); /** subnet module init */ -int subnetmod_init(struct module_env* env, int id); +int subnetmod_setup(struct module_env* env, int id); /** subnet module deinit */ -void subnetmod_deinit(struct module_env* env, int id); +void subnetmod_desetup(struct module_env* env, int id); /** subnet module operate on a query */ void subnetmod_operate(struct module_qstate* qstate, enum module_ev event, diff --git a/ipsecmod/ipsecmod.c b/ipsecmod/ipsecmod.c index a1f40a512..ce461f00a 100644 --- a/ipsecmod/ipsecmod.c +++ b/ipsecmod/ipsecmod.c @@ -67,7 +67,7 @@ ipsecmod_apply_cfg(struct ipsecmod_env* ipsecmod_env, struct config_file* cfg) } int -ipsecmod_init(struct module_env* env, int id) +ipsecmod_setup(struct module_env* env, int id) { struct ipsecmod_env* ipsecmod_env = (struct ipsecmod_env*)calloc(1, sizeof(struct ipsecmod_env)); @@ -85,7 +85,7 @@ ipsecmod_init(struct module_env* env, int id) } void -ipsecmod_deinit(struct module_env* env, int id) +ipsecmod_desetup(struct module_env* env, int id) { struct ipsecmod_env* ipsecmod_env; if(!env || !env->modinfo[id]) @@ -598,8 +598,9 @@ ipsecmod_get_mem(struct module_env* env, int id) */ static struct module_func_block ipsecmod_block = { "ipsecmod", - &ipsecmod_init, &ipsecmod_deinit, &ipsecmod_operate, - &ipsecmod_inform_super, &ipsecmod_clear, &ipsecmod_get_mem + &module_dummy_init, &module_dummy_init, &ipsecmod_setup, + &ipsecmod_desetup, &ipsecmod_operate, &ipsecmod_inform_super, + &ipsecmod_clear, &ipsecmod_get_mem }; struct module_func_block* diff --git a/ipsecmod/ipsecmod.h b/ipsecmod/ipsecmod.h index e00816d4b..96d28717b 100644 --- a/ipsecmod/ipsecmod.h +++ b/ipsecmod/ipsecmod.h @@ -74,9 +74,9 @@ struct ipsecmod_qstate { }; /** Init the ipsecmod module */ -int ipsecmod_init(struct module_env* env, int id); +int ipsecmod_setup(struct module_env* env, int id); /** Deinit the ipsecmod module */ -void ipsecmod_deinit(struct module_env* env, int id); +void ipsecmod_desetup(struct module_env* env, int id); /** Operate on an event on a query (in qstate). */ void ipsecmod_operate(struct module_qstate* qstate, enum module_ev event, int id, struct outbound_entry* outbound); diff --git a/ipset/ipset.c b/ipset/ipset.c index f6e2c4a9d..bf4cbea47 100755 --- a/ipset/ipset.c +++ b/ipset/ipset.c @@ -223,7 +223,7 @@ static int ipset_update(struct module_env *env, struct dns_msg *return_msg, stru return 0; } -int ipset_init(struct module_env* env, int id) { +int ipset_setup(struct module_env* env, int id) { struct ipset_env *ipset_env; ipset_env = (struct ipset_env *)calloc(1, sizeof(struct ipset_env)); @@ -250,7 +250,7 @@ int ipset_init(struct module_env* env, int id) { return 1; } -void ipset_deinit(struct module_env *env, int id) { +void ipset_desetup(struct module_env *env, int id) { struct mnl_socket *mnl; struct ipset_env *ipset_env; @@ -373,7 +373,7 @@ size_t ipset_get_mem(struct module_env *env, int id) { */ static struct module_func_block ipset_block = { "ipset", - &ipset_init, &ipset_deinit, &ipset_operate, + &module_dummy_init, &module_dummy_init, &ipset_setup, &ipset_desetup, &ipset_operate, &ipset_inform_super, &ipset_clear, &ipset_get_mem }; diff --git a/ipset/ipset.h b/ipset/ipset.h index f60a8be8c..6273ec789 100755 --- a/ipset/ipset.h +++ b/ipset/ipset.h @@ -51,9 +51,9 @@ struct ipset_qstate { }; /** Init the ipset module */ -int ipset_init(struct module_env* env, int id); +int ipset_setup(struct module_env* env, int id); /** Deinit the ipset module */ -void ipset_deinit(struct module_env* env, int id); +void ipset_desetup(struct module_env* env, int id); /** Operate on an event on a query (in qstate). */ void ipset_operate(struct module_qstate* qstate, enum module_ev event, int id, struct outbound_entry* outbound); diff --git a/iterator/iterator.c b/iterator/iterator.c index eea2f2fb2..af209f84d 100644 --- a/iterator/iterator.c +++ b/iterator/iterator.c @@ -73,7 +73,7 @@ int UNKNOWN_SERVER_NICENESS = 376; int -iter_init(struct module_env* env, int id) +iter_setup(struct module_env* env, int id) { struct iter_env* iter_env = (struct iter_env*)calloc(1, sizeof(struct iter_env)); @@ -107,7 +107,7 @@ caps_free(struct rbnode_type* n, void* ATTR_UNUSED(d)) } void -iter_deinit(struct module_env* env, int id) +iter_desetup(struct module_env* env, int id) { struct iter_env* iter_env; if(!env || !env->modinfo[id]) @@ -3849,8 +3849,8 @@ iter_get_mem(struct module_env* env, int id) */ static struct module_func_block iter_block = { "iterator", - &iter_init, &iter_deinit, &iter_operate, &iter_inform_super, - &iter_clear, &iter_get_mem + &module_dummy_init, &module_dummy_init, &iter_setup, &iter_desetup, + &iter_operate, &iter_inform_super, &iter_clear, &iter_get_mem }; struct module_func_block* diff --git a/iterator/iterator.h b/iterator/iterator.h index 26ff39559..30bc47289 100644 --- a/iterator/iterator.h +++ b/iterator/iterator.h @@ -429,10 +429,10 @@ const char* iter_state_to_string(enum iter_state state); int iter_state_is_responsestate(enum iter_state s); /** iterator init */ -int iter_init(struct module_env* env, int id); +int iter_setup(struct module_env* env, int id); /** iterator deinit */ -void iter_deinit(struct module_env* env, int id); +void iter_desetup(struct module_env* env, int id); /** iterator operate on a query */ void iter_operate(struct module_qstate* qstate, enum module_ev event, int id, diff --git a/libunbound/context.c b/libunbound/context.c index 6d62e32b5..e04cd653d 100644 --- a/libunbound/context.c +++ b/libunbound/context.c @@ -69,6 +69,8 @@ context_finalize(struct ub_ctx* ctx) log_init(cfg->logfile, cfg->use_syslog, NULL); } config_apply(cfg); + if(!modstack_init(&ctx->mods, cfg->module_conf, ctx->env)) + return UB_INITFAIL; if(!modstack_setup(&ctx->mods, cfg->module_conf, ctx->env)) return UB_INITFAIL; log_edns_known_options(VERB_ALGO, ctx->env); diff --git a/libunbound/libunbound.c b/libunbound/libunbound.c index 3b30419b3..e1abfe64a 100644 --- a/libunbound/libunbound.c +++ b/libunbound/libunbound.c @@ -156,7 +156,7 @@ static struct ub_ctx* ub_ctx_create_nopipe(void) ctx->env->alloc = &ctx->superalloc; ctx->env->worker = NULL; ctx->env->need_to_validate = 0; - modstack_init(&ctx->mods); + memset(&ctx->mods, 0, sizeof(ctx->mods)); rbtree_init(&ctx->queries, &context_query_cmp); return ctx; } @@ -172,6 +172,7 @@ ub_ctx_create(void) ub_randfree(ctx->seed_rnd); config_delete(ctx->env->cfg); modstack_desetup(&ctx->mods, ctx->env); + modstack_deinit(&ctx->mods, ctx->env); edns_known_options_delete(ctx->env); free(ctx->env); free(ctx); @@ -184,6 +185,7 @@ ub_ctx_create(void) ub_randfree(ctx->seed_rnd); config_delete(ctx->env->cfg); modstack_desetup(&ctx->mods, ctx->env); + modstack_deinit(&ctx->mods, ctx->env); edns_known_options_delete(ctx->env); free(ctx->env); free(ctx); @@ -303,6 +305,7 @@ ub_ctx_delete(struct ub_ctx* ctx) libworker_delete_event(ctx->event_worker); modstack_desetup(&ctx->mods, ctx->env); + modstack_deinit(&ctx->mods, ctx->env); a = ctx->alloc_list; while(a) { na = a->super; diff --git a/respip/respip.c b/respip/respip.c index 6fa4f1885..44aea841c 100644 --- a/respip/respip.c +++ b/respip/respip.c @@ -547,7 +547,7 @@ copy_rrset(const struct ub_packed_rrset_key* key, struct regional* region) } int -respip_init(struct module_env* env, int id) +respip_setup(struct module_env* env, int id) { (void)env; (void)id; @@ -555,7 +555,7 @@ respip_init(struct module_env* env, int id) } void -respip_deinit(struct module_env* env, int id) +respip_desetup(struct module_env* env, int id) { (void)env; (void)id; @@ -1273,8 +1273,8 @@ respip_get_mem(struct module_env* env, int id) */ static struct module_func_block respip_block = { "respip", - &respip_init, &respip_deinit, &respip_operate, &respip_inform_super, - &respip_clear, &respip_get_mem + &module_dummy_init, &module_dummy_init, &respip_setup, &respip_desetup, &respip_operate, + &respip_inform_super, &respip_clear, &respip_get_mem }; struct module_func_block* diff --git a/respip/respip.h b/respip/respip.h index bbd471421..d26014766 100644 --- a/respip/respip.h +++ b/respip/respip.h @@ -192,10 +192,10 @@ int respip_rewrite_reply(const struct query_info* qinfo, struct module_func_block* respip_get_funcblock(void); /** response-ip init */ -int respip_init(struct module_env* env, int id); +int respip_setup(struct module_env* env, int id); /** response-ip deinit */ -void respip_deinit(struct module_env* env, int id); +void respip_desetup(struct module_env* env, int id); /** response-ip operate on a query */ void respip_operate(struct module_qstate* qstate, enum module_ev event, int id, diff --git a/services/modstack.c b/services/modstack.c index 68e592814..5a57ecd2d 100644 --- a/services/modstack.c +++ b/services/modstack.c @@ -85,14 +85,7 @@ count_modules(const char* s) return num; } -void -modstack_init(struct module_stack* stack) -{ - stack->num = 0; - stack->mod = NULL; -} - -int +int modstack_config(struct module_stack* stack, const char* module_conf) { int i; @@ -210,18 +203,17 @@ module_func_block* module_factory(const char** str) return NULL; } -int -modstack_setup(struct module_stack* stack, const char* module_conf, +int +modstack_init(struct module_stack* stack, const char* module_conf, struct module_env* env) { - int i; - if(stack->num != 0) - modstack_desetup(stack, env); + int i; + if (stack->num != 0) + fatal_exit("unexpected already initialised modules"); /* fixed setup of the modules */ if(!modstack_config(stack, module_conf)) { return 0; } - env->need_to_validate = 0; /* set by module init below */ for(i=0; inum; i++) { verbose(VERB_OPS, "init module %d: %s", i, stack->mod[i]->name); @@ -235,8 +227,45 @@ modstack_setup(struct module_stack* stack, const char* module_conf, return 1; } -void +int +modstack_setup(struct module_stack* stack, const char* module_conf, + struct module_env* env) +{ + int i; + env->need_to_validate = 0; /* set by module setup below */ + for(i=0; inum; i++) { + while(*module_conf && isspace(*module_conf)) + module_conf++; + if(strncmp(stack->mod[i]->name, module_conf, + strlen(stack->mod[i]->name))) { + log_err("changed module ordering during reload not supported"); + return 0; + } + module_conf += strlen(stack->mod[i]->name); + verbose(VERB_OPS, "setup module %d: %s", + i, stack->mod[i]->name); + fptr_ok(fptr_whitelist_mod_setup(stack->mod[i]->setup)); + if(!(*stack->mod[i]->setup)(env, i)) { + log_err("module setup for module %s failed", + stack->mod[i]->name); + return 0; + } + } + return 1; +} + +void modstack_desetup(struct module_stack* stack, struct module_env* env) +{ + int i; + for(i=0; inum; i++) { + fptr_ok(fptr_whitelist_mod_desetup(stack->mod[i]->desetup)); + (*stack->mod[i]->desetup)(env, i); + } +} + +void +modstack_deinit(struct module_stack* stack, struct module_env* env) { int i; for(i=0; inum; i++) { @@ -248,7 +277,7 @@ modstack_desetup(struct module_stack* stack, struct module_env* env) stack->mod = NULL; } -int +int modstack_find(struct module_stack* stack, const char* name) { int i; diff --git a/services/modstack.h b/services/modstack.h index 3ff01b54d..3e79595ed 100644 --- a/services/modstack.h +++ b/services/modstack.h @@ -55,10 +55,16 @@ struct module_stack { }; /** - * Init a stack of modules - * @param stack: initialised as empty. + * Initialises modules and assignes ids. + * @param stack: Expected empty, filled according to module_conf + * @param module_conf: string what modules to initialize + * @param env: module environment which is inited by the modules. + * environment should have a superalloc, cfg, + * env.need_to_validate is set by the modules. + * @return on false a module init failed. */ -void modstack_init(struct module_stack* stack); +int modstack_init(struct module_stack* stack, const char* module_conf, + struct module_env* env); /** * Read config file module settings and set up the modfunc block @@ -83,10 +89,10 @@ struct module_func_block* module_factory(const char** str); const char** module_list_avail(void); /** - * Setup modules. Assigns ids and calls module_init. - * @param stack: if not empty beforehand, it will be desetup()ed. - * It is then modstack_configged(). - * @param module_conf: string what modules to insert. + * Setup modules. Calls module_setup(). + * @param stack: It is modstack_setupped(). + * @param module_conf: module ordering to check against the ordering in stack. + * fails on changed ordering. * @param env: module environment which is inited by the modules. * environment should have a superalloc, cfg, * env.need_to_validate is set by the modules. @@ -96,12 +102,19 @@ int modstack_setup(struct module_stack* stack, const char* module_conf, struct module_env* env); /** - * Desetup the modules, deinit, delete. + * Desetup the modules * @param stack: made empty. * @param env: module env for module deinit() calls. */ void modstack_desetup(struct module_stack* stack, struct module_env* env); +/** + * Deinit the modules, deinit, delete. + * @param stack: made empty. + * @param env: module env for module deinit() calls. + */ +void modstack_deinit(struct module_stack* stack, struct module_env* env); + /** * Find index of module by name. * @param stack: to look in diff --git a/smallapp/unbound-checkconf.c b/smallapp/unbound-checkconf.c index 3fc638cae..a1f70a8e6 100644 --- a/smallapp/unbound-checkconf.c +++ b/smallapp/unbound-checkconf.c @@ -137,9 +137,11 @@ check_mod(struct config_file* cfg, struct module_func_block* fb) fatal_exit("out of memory"); if(!edns_known_options_init(&env)) fatal_exit("out of memory"); - if(!(*fb->init)(&env, 0)) { + if(!(*fb->setup)(&env, 0)) fatal_exit("bad config for %s module", fb->name); - } + if(!(*fb->setup)(&env, 0)) + fatal_exit("bad config for %s module", fb->name); + (*fb->desetup)(&env, 0); (*fb->deinit)(&env, 0); sldns_buffer_free(env.scratch_buffer); regional_destroy(env.scratch); diff --git a/util/fptr_wlist.c b/util/fptr_wlist.c index b124e7169..35d8bfaed 100644 --- a/util/fptr_wlist.c +++ b/util/fptr_wlist.c @@ -382,52 +382,72 @@ fptr_whitelist_modenv_detect_cycle(int (*fptr)( return 0; } -int +int fptr_whitelist_mod_init(int (*fptr)(struct module_env* env, int id)) { - if(fptr == &iter_init) return 1; - else if(fptr == &val_init) return 1; - else if(fptr == &dns64_init) return 1; - else if(fptr == &respip_init) return 1; + if(fptr == &module_dummy_init) return 1; +#ifdef USE_IPSET + else if(fptr == &ipset_init) return 1; +#endif + return 0; +} + +int +fptr_whitelist_mod_deinit(int (*fptr)(struct module_env* env, int id)) +{ + if(fptr == &module_dummy_init) return 1; +#ifdef USE_IPSET + else if(fptr == &ipset_deinit) return 1; +#endif + return 0; +} + +int +fptr_whitelist_mod_setup(int (*fptr)(struct module_env* env, int id)) +{ + if(fptr == &iter_setup) return 1; + else if(fptr == &val_setup) return 1; + else if(fptr == &dns64_setup) return 1; + else if(fptr == &respip_setup) return 1; #ifdef WITH_PYTHONMODULE - else if(fptr == &pythonmod_init) return 1; + else if(fptr == &pythonmod_setup) return 1; #endif #ifdef USE_CACHEDB - else if(fptr == &cachedb_init) return 1; + else if(fptr == &cachedb_setup) return 1; #endif #ifdef USE_IPSECMOD - else if(fptr == &ipsecmod_init) return 1; + else if(fptr == &ipsecmod_setup) return 1; #endif #ifdef CLIENT_SUBNET - else if(fptr == &subnetmod_init) return 1; + else if(fptr == &subnetmod_setup) return 1; #endif #ifdef USE_IPSET - else if(fptr == &ipset_init) return 1; + else if(fptr == &ipset_setup) return 1; #endif return 0; } int -fptr_whitelist_mod_deinit(void (*fptr)(struct module_env* env, int id)) +fptr_whitelist_mod_desetup(void (*fptr)(struct module_env* env, int id)) { - if(fptr == &iter_deinit) return 1; - else if(fptr == &val_deinit) return 1; - else if(fptr == &dns64_deinit) return 1; - else if(fptr == &respip_deinit) return 1; + if(fptr == &iter_desetup) return 1; + else if(fptr == &val_desetup) return 1; + else if(fptr == &dns64_desetup) return 1; + else if(fptr == &respip_desetup) return 1; #ifdef WITH_PYTHONMODULE - else if(fptr == &pythonmod_deinit) return 1; + else if(fptr == &pythonmod_desetup) return 1; #endif #ifdef USE_CACHEDB - else if(fptr == &cachedb_deinit) return 1; + else if(fptr == &cachedb_desetup) return 1; #endif #ifdef USE_IPSECMOD - else if(fptr == &ipsecmod_deinit) return 1; + else if(fptr == &ipsecmod_desetup) return 1; #endif #ifdef CLIENT_SUBNET - else if(fptr == &subnetmod_deinit) return 1; + else if(fptr == &subnetmod_desetup) return 1; #endif #ifdef USE_IPSET - else if(fptr == &ipset_deinit) return 1; + else if(fptr == &ipset_desetup) return 1; #endif return 0; } diff --git a/util/fptr_wlist.h b/util/fptr_wlist.h index cd331febb..3f74fc8b0 100644 --- a/util/fptr_wlist.h +++ b/util/fptr_wlist.h @@ -270,12 +270,20 @@ int fptr_whitelist_modenv_detect_cycle(int (*fptr)( int fptr_whitelist_mod_init(int (*fptr)(struct module_env* env, int id)); /** - * Check function pointer whitelist for module deinit call values. + * Check function pointer whitelist for module setup call values. * * @param fptr: function pointer to check. * @return false if not in whitelist. */ -int fptr_whitelist_mod_deinit(void (*fptr)(struct module_env* env, int id)); +int fptr_whitelist_mod_setup(int (*fptr)(struct module_env* env, int id)); + +/** + * Check function pointer whitelist for module desetup call values. + * + * @param fptr: function pointer to check. + * @return false if not in whitelist. + */ +int fptr_whitelist_mod_desetup(void (*fptr)(struct module_env* env, int id)); /** * Check function pointer whitelist for module operate call values. diff --git a/util/module.c b/util/module.c index f16583183..a94b0fffa 100644 --- a/util/module.c +++ b/util/module.c @@ -246,3 +246,8 @@ copy_state_to_super(struct module_qstate* qstate, int ATTR_UNUSED(id), super->was_ratelimited = qstate->was_ratelimited; } } + +int module_dummy_init(struct module_env* env, int id) +{ + return 1; +} diff --git a/util/module.h b/util/module.h index fa89c647e..e7b1f33e5 100644 --- a/util/module.h +++ b/util/module.h @@ -672,21 +672,40 @@ struct module_func_block { /** text string name of module */ const char* name; - /** - * init the module. Called once for the global state. + /** + * initialise the module. This is called only once at startup. + * Privileged operations like opening device files may be done here. + * @param id: module id number. + * return: 0 on error + */ + int (*init)(struct module_env* env, int id); + + /** + * deinitialise the module. This is called only once before shutdown to + * free resources allocated during init(). + * Closing privileged ports or files must be done here. + * @param id: module id number. + * return: 0 on error + */ + int (*deinit)(struct module_env* env, int id); + + /** + * setup the module. Called when restarting or reloading the + * daemon. * This is the place to apply settings from the config file. * @param env: module environment. * @param id: module id number. * return: 0 on error */ - int (*init)(struct module_env* env, int id); + int (*setup)(struct module_env* env, int id); /** - * de-init, delete, the module. Called once for the global state. + * de-setup, undo stuff done during setup(). + * Called before reloading the daemon. * @param env: module environment. * @param id: module id number. */ - void (*deinit)(struct module_env* env, int id); + void (*desetup)(struct module_env* env, int id); /** * accept a new query, or work further on existing query. @@ -858,4 +877,6 @@ void log_edns_known_options(enum verbosity_value level, void copy_state_to_super(struct module_qstate* qstate, int id, struct module_qstate* super); +int module_dummy_init(struct module_env* env, int id); + #endif /* UTIL_MODULE_H */ diff --git a/validator/validator.c b/validator/validator.c index c3ca0a27d..fa5fe4c0e 100644 --- a/validator/validator.c +++ b/validator/validator.c @@ -165,7 +165,7 @@ val_apply_cfg(struct module_env* env, struct val_env* val_env, void ecdsa_evp_workaround_init(void); #endif int -val_init(struct module_env* env, int id) +val_setup(struct module_env* env, int id) { struct val_env* val_env = (struct val_env*)calloc(1, sizeof(struct val_env)); @@ -190,7 +190,7 @@ val_init(struct module_env* env, int id) } void -val_deinit(struct module_env* env, int id) +val_desetup(struct module_env* env, int id) { struct val_env* val_env; if(!env || !env->modinfo[id]) @@ -3266,8 +3266,8 @@ val_get_mem(struct module_env* env, int id) */ static struct module_func_block val_block = { "validator", - &val_init, &val_deinit, &val_operate, &val_inform_super, &val_clear, - &val_get_mem + &module_dummy_init, &module_dummy_init, &val_setup, &val_desetup, + &val_operate, &val_inform_super, &val_clear, &val_get_mem }; struct module_func_block* diff --git a/validator/validator.h b/validator/validator.h index 9e4c8a941..caa18d7fd 100644 --- a/validator/validator.h +++ b/validator/validator.h @@ -254,10 +254,10 @@ struct module_func_block* val_get_funcblock(void); const char* val_state_to_string(enum val_state state); /** validator init */ -int val_init(struct module_env* env, int id); +int val_setup(struct module_env* env, int id); /** validator deinit */ -void val_deinit(struct module_env* env, int id); +void val_desetup(struct module_env* env, int id); /** validator operate on a query */ void val_operate(struct module_qstate* qstate, enum module_ev event, int id,