From: Colin Vidal Date: Mon, 26 May 2025 14:53:31 +0000 (+0200) Subject: add namedconf support for plugin inside a zone X-Git-Tag: v9.21.14~56^2~15 X-Git-Url: http://git.ipfire.org/index.cgi?a=commitdiff_plain;h=7ea70b4e19e71d102bce16dee9a7df7ba5e5f8ad;p=thirdparty%2Fbind9.git add namedconf support for plugin inside a zone The named.conf parser now accepts the plugin clause inside a zone definition. This enables us to add (in later commits) support for zone plugins. --- diff --git a/bin/named/server.c b/bin/named/server.c index cce0be6d7bf..5629508a486 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -13200,7 +13200,8 @@ do_addzone(named_server_t *server, ns_cfgctx_t *cfg, dns_view_t *view, } result = isccfg_check_zoneconf(zoneobj, voptions, cfg->config, NULL, NULL, NULL, NULL, view->name, - view->rdclass, cfg->actx, cfg->mctx); + view->rdclass, BIND_CHECK_PLUGINS, + cfg->actx, cfg->mctx); if (result != ISC_R_SUCCESS) { isc_loopmgr_resume(); goto cleanup; @@ -13397,7 +13398,8 @@ do_modzone(named_server_t *server, ns_cfgctx_t *cfg, dns_view_t *view, } result = isccfg_check_zoneconf(zoneobj, voptions, cfg->config, NULL, NULL, NULL, NULL, view->name, - view->rdclass, cfg->actx, cfg->mctx); + view->rdclass, BIND_CHECK_PLUGINS, + cfg->actx, cfg->mctx); if (result != ISC_R_SUCCESS) { isc_loopmgr_resume(); goto cleanup; diff --git a/doc/misc/mirror.zoneopt b/doc/misc/mirror.zoneopt index aa193235a72..346f093d335 100644 --- a/doc/misc/mirror.zoneopt +++ b/doc/misc/mirror.zoneopt @@ -33,6 +33,7 @@ zone [ ] { notify-delay ; notify-source ( | * ); notify-source-v6 ( | * ); + plugin ( query ) [ { } ]; // may occur multiple times primaries [ port ] [ source ( | * ) ] [ source-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; provide-zoneversion ; request-expire ; diff --git a/doc/misc/options b/doc/misc/options index 0c80800b58b..e11f0c4d869 100644 --- a/doc/misc/options +++ b/doc/misc/options @@ -427,6 +427,7 @@ template { parental-agents [ port ] [ source ( | * ) ] [ source-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; parental-source ( | * ); parental-source-v6 ( | * ); + plugin ( query ) [ { } ]; // may occur multiple times primaries [ port ] [ source ( | * ) ] [ source-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; provide-zoneversion ; request-expire ; diff --git a/doc/misc/primary.zoneopt b/doc/misc/primary.zoneopt index dd1b94756b7..dfebff879b7 100644 --- a/doc/misc/primary.zoneopt +++ b/doc/misc/primary.zoneopt @@ -53,6 +53,7 @@ zone [ ] { parental-agents [ port ] [ source ( | * ) ] [ source-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; parental-source ( | * ); parental-source-v6 ( | * ); + plugin ( query ) [ { } ]; // may occur multiple times provide-zoneversion ; send-report-channel ; serial-update-method ( date | increment | unixtime ); diff --git a/doc/misc/redirect.zoneopt b/doc/misc/redirect.zoneopt index e338b6e2316..077b01af256 100644 --- a/doc/misc/redirect.zoneopt +++ b/doc/misc/redirect.zoneopt @@ -10,6 +10,7 @@ zone [ ] { max-records-per-type ; max-types-per-name ; max-zone-ttl ( unlimited | ); // deprecated + plugin ( query ) [ { } ]; // may occur multiple times primaries [ port ] [ source ( | * ) ] [ source-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; template ; zone-statistics ( full | terse | none | ); diff --git a/doc/misc/secondary.zoneopt b/doc/misc/secondary.zoneopt index 7529112a334..cbbd5fea528 100644 --- a/doc/misc/secondary.zoneopt +++ b/doc/misc/secondary.zoneopt @@ -50,6 +50,7 @@ zone [ ] { parental-agents [ port ] [ source ( | * ) ] [ source-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; parental-source ( | * ); parental-source-v6 ( | * ); + plugin ( query ) [ { } ]; // may occur multiple times primaries [ port ] [ source ( | * ) ] [ source-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; provide-zoneversion ; request-expire ; diff --git a/lib/isccfg/check.c b/lib/isccfg/check.c index 3569f7fc18d..1d06e1e303d 100644 --- a/lib/isccfg/check.c +++ b/lib/isccfg/check.c @@ -2922,6 +2922,68 @@ check: return result; } +/*% + * Data structure used for the 'callback_data' argument to check_one_plugin(). + */ +struct check_one_plugin_data { + isc_mem_t *mctx; + cfg_aclconfctx_t *actx; + isc_result_t *check_result; +}; + +/*% + * A callback for the cfg_pluginlist_foreach() call in check_plugins() below. + * Since the point is to check configuration of all plugins even when + * processing some of them fails, always return ISC_R_SUCCESS and indicate any + * check failures through the 'check_result' variable passed in via the + * 'callback_data' structure. + */ +static isc_result_t +check_one_plugin(const cfg_obj_t *config, const cfg_obj_t *obj, + const char *plugin_path, const char *parameters, + void *callback_data) { + struct check_one_plugin_data *data = callback_data; + char full_path[PATH_MAX]; + isc_result_t result = ISC_R_SUCCESS; + + result = ns_plugin_expandpath(plugin_path, full_path, + sizeof(full_path)); + if (result != ISC_R_SUCCESS) { + cfg_obj_log(obj, ISC_LOG_ERROR, + "%s: plugin check failed: " + "unable to get full plugin path: %s", + plugin_path, isc_result_totext(result)); + return result; + } + + result = ns_plugin_check(full_path, parameters, config, + cfg_obj_file(obj), cfg_obj_line(obj), + data->mctx, data->actx); + if (result != ISC_R_SUCCESS) { + cfg_obj_log(obj, ISC_LOG_ERROR, "%s: plugin check failed: %s", + full_path, isc_result_totext(result)); + *data->check_result = result; + } + + return ISC_R_SUCCESS; +} + +static isc_result_t +check_plugins(const cfg_obj_t *plugins, const cfg_obj_t *config, + cfg_aclconfctx_t *actx, isc_mem_t *mctx) { + isc_result_t result = ISC_R_SUCCESS; + struct check_one_plugin_data check_one_plugin_data = { + .mctx = mctx, + .actx = actx, + .check_result = &result, + }; + + (void)cfg_pluginlist_foreach(config, plugins, check_one_plugin, + &check_one_plugin_data); + + return result; +} + /* * Try to find a zone option in one of up to four levels of options: * for example, the zone, template, view, and global option blocks. @@ -2957,8 +3019,8 @@ isccfg_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, isc_symtab_t *keydirs, isc_symtab_t *inview, const char *viewname, - dns_rdataclass_t defclass, cfg_aclconfctx_t *actx, - isc_mem_t *mctx) { + dns_rdataclass_t defclass, unsigned int flags, + cfg_aclconfctx_t *actx, isc_mem_t *mctx) { const char *znamestr = NULL; const char *typestr = NULL; const char *target = NULL; @@ -3926,6 +3988,16 @@ isccfg_check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions, } } + if ((flags & BIND_CHECK_PLUGINS) != 0 && zoptions != NULL) { + const cfg_obj_t *plugins = NULL; + + (void)cfg_map_get(zoptions, "plugin", &plugins); + tresult = check_plugins(plugins, config, actx, mctx); + if (tresult != ISC_R_SUCCESS) { + result = tresult; + } + } + return result; } @@ -5179,52 +5251,6 @@ check_catz(const cfg_obj_t *catz_obj, const char *viewname, isc_mem_t *mctx) { return result; } -/*% - * Data structure used for the 'callback_data' argument to check_one_plugin(). - */ -struct check_one_plugin_data { - isc_mem_t *mctx; - cfg_aclconfctx_t *actx; - isc_result_t *check_result; -}; - -/*% - * A callback for the cfg_pluginlist_foreach() call in check_viewconf() below. - * Since the point is to check configuration of all plugins even when - * processing some of them fails, always return ISC_R_SUCCESS and indicate any - * check failures through the 'check_result' variable passed in via the - * 'callback_data' structure. - */ -static isc_result_t -check_one_plugin(const cfg_obj_t *config, const cfg_obj_t *obj, - const char *plugin_path, const char *parameters, - void *callback_data) { - struct check_one_plugin_data *data = callback_data; - char full_path[PATH_MAX]; - isc_result_t result = ISC_R_SUCCESS; - - result = ns_plugin_expandpath(plugin_path, full_path, - sizeof(full_path)); - if (result != ISC_R_SUCCESS) { - cfg_obj_log(obj, ISC_LOG_ERROR, - "%s: plugin check failed: " - "unable to get full plugin path: %s", - plugin_path, isc_result_totext(result)); - return result; - } - - result = ns_plugin_check(full_path, parameters, config, - cfg_obj_file(obj), cfg_obj_line(obj), - data->mctx, data->actx); - if (result != ISC_R_SUCCESS) { - cfg_obj_log(obj, ISC_LOG_ERROR, "%s: plugin check failed: %s", - full_path, isc_result_totext(result)); - *data->check_result = result; - } - - return ISC_R_SUCCESS; -} - static isc_result_t check_dnstap(const cfg_obj_t *voptions, const cfg_obj_t *config) { #ifdef HAVE_DNSTAP @@ -5276,11 +5302,9 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions, const cfg_obj_t *obj = NULL; const cfg_obj_t *options = NULL; const cfg_obj_t *opts = NULL; - const cfg_obj_t *plugin_list = NULL; bool autovalidation = false; unsigned int dflags = 0; int i; - bool check_plugins = (flags & BIND_CHECK_PLUGINS) != 0; bool check_algorithms = (flags & BIND_CHECK_ALGORITHMS) != 0; /* @@ -5314,9 +5338,9 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions, CFG_LIST_FOREACH(zones, element) { const cfg_obj_t *zone = cfg_listelt_value(element); - tresult = isccfg_check_zoneconf(zone, voptions, config, symtab, - files, keydirs, inview, - viewname, vclass, actx, mctx); + tresult = isccfg_check_zoneconf( + zone, voptions, config, symtab, files, keydirs, inview, + viewname, vclass, flags, actx, mctx); if (tresult != ISC_R_SUCCESS) { result = ISC_R_FAILURE; } @@ -5571,27 +5595,16 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions, result = tresult; } - /* - * Load plugins. - */ - if (check_plugins) { + if ((flags & BIND_CHECK_PLUGINS) != 0) { + const cfg_obj_t *plugins = NULL; + if (voptions != NULL) { - (void)cfg_map_get(voptions, "plugin", &plugin_list); + (void)cfg_map_get(voptions, "plugin", &plugins); } else { - (void)cfg_map_get(config, "plugin", &plugin_list); + (void)cfg_map_get(config, "plugin", &plugins); } - } - { - struct check_one_plugin_data check_one_plugin_data = { - .mctx = mctx, - .actx = actx, - .check_result = &tresult, - }; - - (void)cfg_pluginlist_foreach(config, plugin_list, - check_one_plugin, - &check_one_plugin_data); + tresult = check_plugins(plugins, config, actx, mctx); if (tresult != ISC_R_SUCCESS) { result = tresult; } diff --git a/lib/isccfg/include/isccfg/check.h b/lib/isccfg/include/isccfg/check.h index 9a670bbd3d0..f3980204d20 100644 --- a/lib/isccfg/include/isccfg/check.h +++ b/lib/isccfg/include/isccfg/check.h @@ -73,8 +73,8 @@ isccfg_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, isc_symtab_t *keydirs, isc_symtab_t *inview, const char *viewname, - dns_rdataclass_t defclass, cfg_aclconfctx_t *actx, - isc_mem_t *mctx); + dns_rdataclass_t defclass, unsigned int flags, + cfg_aclconfctx_t *actx, isc_mem_t *mctx); /*%< * Check the syntactic validity of a zone statement, either in a * named.conf file or in an "rndc addzone" or "rndc modzone" command. diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index 8ec7607d7ae..69e5fb0ba99 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -2463,6 +2463,9 @@ static cfg_clausedef_t zone_only_clauses[] = { CFG_ZONE_REDIRECT | CFG_CLAUSEFLAG_NODOC }, { "parental-agents", &cfg_type_namesockaddrkeylist, CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY }, + { "plugin", &cfg_type_plugin, + CFG_CLAUSEFLAG_MULTI | CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | + CFG_ZONE_REDIRECT | CFG_ZONE_MIRROR }, { "primaries", &cfg_type_namesockaddrkeylist, CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR | CFG_ZONE_STUB | CFG_ZONE_REDIRECT },