chg: dev: Refactoring in lib/isccfg

`cfg_obj_t` objects no longer depend on the `cfg_parser_t` life-cycle; they can now persist until the last reference is detached. The `file` field, which was previously a pointer to memory allocated in the parser, is now a pointer to a subsidiary `cfg_obj_t` of type string. The API calls for creating and detaching these objects have been simplified accordingly.

Since `cfg_obj_t` is now long-lived, a zone can hold a reference to its own configuration data, making it possible to use `rndc showzone` even if `allow-new-zones` is disabled.

Several API calls related to the parser have been removed or hidden. The `cfg_parse_file()` and `cfg_parse_buffer()` functions now internally create and destroy their own parsers, eliminating the need for the caller to do so.

Most of these changes are intended to simplify dumping of running configuration data in a future commit.

Merge branch 'colin/hide-cfg-parser' into 'main'

See merge request isc-projects/bind9!11132
This commit is contained in:
Evan Hunt 2025-10-23 20:43:07 +00:00
commit 3d0ddb5f9b
34 changed files with 650 additions and 1046 deletions

View file

@ -63,32 +63,6 @@ usage(void) {
exit(EXIT_SUCCESS);
}
/*% directory callback */
static isc_result_t
directory_callback(const char *clausename, const cfg_obj_t *obj, void *arg) {
isc_result_t result;
const char *directory;
REQUIRE(strcasecmp("directory", clausename) == 0);
UNUSED(arg);
UNUSED(clausename);
/*
* Change directory.
*/
directory = cfg_obj_asstring(obj);
result = isc_dir_chdir(directory);
if (result != ISC_R_SUCCESS) {
cfg_obj_log(obj, ISC_LOG_ERROR,
"change directory to '%s' failed: %s\n", directory,
isc_result_totext(result));
return result;
}
return ISC_R_SUCCESS;
}
static bool
get_maps(const cfg_obj_t **maps, const char *name, const cfg_obj_t **obj) {
int i;
@ -574,16 +548,14 @@ output(void *closure, const char *text, int textlen) {
int
main(int argc, char **argv) {
int c;
cfg_parser_t *parser = NULL;
cfg_obj_t *config = NULL;
const char *conffile = NULL;
isc_result_t result = ISC_R_SUCCESS;
bool load_zones = false;
bool list_zones = false;
bool print = false;
bool nodeprecate = false;
bool allconfigs = false;
unsigned int flags = 0;
unsigned int parserflags = 0;
unsigned int checkflags = BIND_CHECK_PLUGINS | BIND_CHECK_ALGORITHMS;
isc_commandline_init(argc, argv);
@ -631,7 +603,7 @@ main(int argc, char **argv) {
break;
case 'i':
nodeprecate = true;
parserflags |= CFG_PCTX_NODEPRECATED;
break;
case 'j':
@ -650,7 +622,7 @@ main(int argc, char **argv) {
break;
case 'n':
allconfigs = true;
parserflags |= CFG_PCTX_ALLCONFIGS;
break;
case 't':
@ -722,18 +694,8 @@ main(int argc, char **argv) {
}
CHECK(setup_logging(stdout));
CHECK(cfg_parser_create(isc_g_mctx, &parser));
if (nodeprecate) {
cfg_parser_setflags(parser, CFG_PCTX_NODEPRECATED, true);
}
if (allconfigs) {
cfg_parser_setflags(parser, CFG_PCTX_ALLCONFIGS, true);
}
cfg_parser_setcallback(parser, directory_callback, NULL);
CHECK(cfg_parse_file(parser, conffile, &cfg_type_namedconf, &config));
CHECK(cfg_parse_file(isc_g_mctx, conffile, &cfg_type_namedconf,
parserflags, &config));
CHECK(isccfg_check_namedconf(config, checkflags, isc_g_mctx));
if (load_zones || list_zones) {
CHECK(load_zones_fromconfig(config, list_zones));
@ -745,11 +707,7 @@ main(int argc, char **argv) {
cleanup:
if (config != NULL) {
cfg_obj_destroy(parser, &config);
}
if (parser != NULL) {
cfg_parser_destroy(&parser);
cfg_obj_detach(&config);
}
return result == ISC_R_SUCCESS ? 0 : 1;

View file

@ -808,7 +808,6 @@ cleanup:
static isc_result_t
setup_dnsseckeys(dns_client_t *client, dns_view_t *toview) {
isc_result_t result;
cfg_parser_t *parser = NULL;
const cfg_obj_t *trust_anchors = NULL;
cfg_obj_t *bindkeys = NULL;
@ -824,15 +823,13 @@ setup_dnsseckeys(dns_client_t *client, dns_view_t *toview) {
CHECK(convert_name(&afn, &anchor_name, trust_anchor));
}
CHECK(cfg_parser_create(isc_g_mctx, &parser));
if (anchorfile != NULL) {
if (access(anchorfile, R_OK) != 0) {
fatal("Unable to read key file '%s'", anchorfile);
}
result = cfg_parse_file(parser, anchorfile, &cfg_type_bindkeys,
&bindkeys);
result = cfg_parse_file(isc_g_mctx, anchorfile,
&cfg_type_bindkeys, 0, &bindkeys);
if (result != ISC_R_SUCCESS) {
fatal("Unable to load keys from '%s'", anchorfile);
}
@ -841,8 +838,7 @@ setup_dnsseckeys(dns_client_t *client, dns_view_t *toview) {
isc_buffer_init(&b, anchortext, sizeof(anchortext) - 1);
isc_buffer_add(&b, sizeof(anchortext) - 1);
cfg_parser_reset(parser);
result = cfg_parse_buffer(parser, &b, NULL, 0,
result = cfg_parse_buffer(isc_g_mctx, &b, NULL, 0,
&cfg_type_bindkeys, 0, &bindkeys);
if (result != ISC_R_SUCCESS) {
fatal("Unable to parse built-in keys");
@ -862,10 +858,7 @@ setup_dnsseckeys(dns_client_t *client, dns_view_t *toview) {
cleanup:
if (bindkeys != NULL) {
cfg_obj_destroy(parser, &bindkeys);
}
if (parser != NULL) {
cfg_parser_destroy(&parser);
cfg_obj_detach(&bindkeys);
}
if (result != ISC_R_SUCCESS) {
delv_log(ISC_LOG_ERROR, "setup_dnsseckeys: %s",

View file

@ -1072,7 +1072,6 @@ parse_hmac(const char *algname) {
*/
static isc_result_t
read_confkey(void) {
cfg_parser_t *pctx = NULL;
cfg_obj_t *file = NULL;
const cfg_obj_t *keyobj = NULL;
const cfg_obj_t *secretobj = NULL;
@ -1086,12 +1085,8 @@ read_confkey(void) {
return ISC_R_FILENOTFOUND;
}
result = cfg_parser_create(isc_g_mctx, &pctx);
if (result != ISC_R_SUCCESS) {
goto cleanup;
}
result = cfg_parse_file(pctx, keyfile, &cfg_type_sessionkey, &file);
result = cfg_parse_file(isc_g_mctx, keyfile, &cfg_type_sessionkey, 0,
&file);
if (result != ISC_R_SUCCESS) {
goto cleanup;
}
@ -1117,11 +1112,8 @@ read_confkey(void) {
setup_text_key();
cleanup:
if (pctx != NULL) {
if (file != NULL) {
cfg_obj_destroy(pctx, &file);
}
cfg_parser_destroy(&pctx);
if (file != NULL) {
cfg_obj_detach(&file);
}
return result;

View file

@ -1147,14 +1147,11 @@ main(int argc, char **argv) {
keygen(&ctx, argc, argv);
} else {
cfg_parser_t *parser = NULL;
cfg_obj_t *config = NULL;
dns_kasp_t *kasp = NULL;
RUNTIME_CHECK(cfg_parser_create(isc_g_mctx, &parser) ==
ISC_R_SUCCESS);
if (cfg_parse_file(parser, ctx.configfile,
&cfg_type_namedconf,
if (cfg_parse_file(isc_g_mctx, ctx.configfile,
&cfg_type_namedconf, 0,
&config) != ISC_R_SUCCESS)
{
fatal("unable to load dnssec-policy '%s' from "
@ -1199,8 +1196,7 @@ main(int argc, char **argv) {
}
dns_kasp_detach(&kasp);
cfg_obj_destroy(parser, &config);
cfg_parser_destroy(&parser);
cfg_obj_detach(&config);
}
} else {
keygen(&ctx, argc, argv);

View file

@ -170,11 +170,9 @@ checkparams(ksr_ctx_t *ksr, const char *command) {
static void
getkasp(ksr_ctx_t *ksr, dns_kasp_t **kasp) {
cfg_parser_t *parser = NULL;
cfg_obj_t *config = NULL;
RUNTIME_CHECK(cfg_parser_create(isc_g_mctx, &parser) == ISC_R_SUCCESS);
if (cfg_parse_file(parser, ksr->configfile, &cfg_type_namedconf,
if (cfg_parse_file(isc_g_mctx, ksr->configfile, &cfg_type_namedconf, 0,
&config) != ISC_R_SUCCESS)
{
fatal("unable to load dnssec-policy '%s' from '%s'",
@ -187,8 +185,7 @@ getkasp(ksr_ctx_t *ksr, dns_kasp_t **kasp) {
if (ISC_LIST_EMPTY(dns_kasp_keys(*kasp))) {
fatal("dnssec-policy '%s' has no keys configured", ksr->policy);
}
cfg_obj_destroy(parser, &config);
cfg_parser_destroy(&parser);
cfg_obj_detach(&config);
}
static int

View file

@ -361,81 +361,30 @@ remote-servers " DEFAULT_IANA_ROOT_ZONE_PRIMARIES " {\n\
";
isc_result_t
named_config_parsedefaults(cfg_parser_t *parser, cfg_obj_t **conf) {
named_config_parsedefaults(cfg_obj_t **conf) {
isc_buffer_t b;
isc_buffer_init(&b, defaultconf, sizeof(defaultconf) - 1);
isc_buffer_add(&b, sizeof(defaultconf) - 1);
return cfg_parse_buffer(parser, &b, __FILE__, 0, &cfg_type_namedconf,
return cfg_parse_buffer(isc_g_mctx, &b, __FILE__, 0,
&cfg_type_namedconf,
CFG_PCTX_NODEPRECATED | CFG_PCTX_NOOBSOLETE |
CFG_PCTX_NOEXPERIMENTAL,
conf);
}
/*
* This function is called as soon as the 'directory' statement has been
* parsed. This can be extended to support other options if necessary.
*/
static isc_result_t
directory_callback(const char *clausename, const cfg_obj_t *obj, void *arg) {
isc_result_t result;
const char *directory;
REQUIRE(strcasecmp("directory", clausename) == 0);
UNUSED(arg);
UNUSED(clausename);
/*
* Change directory.
*/
directory = cfg_obj_asstring(obj);
if (!isc_file_ischdiridempotent(directory)) {
cfg_obj_log(obj, ISC_LOG_WARNING,
"option 'directory' contains relative path '%s'",
directory);
}
if (!isc_file_isdirwritable(directory)) {
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
ISC_LOG_ERROR, "directory '%s' is not writable",
directory);
return ISC_R_NOPERM;
}
result = isc_dir_chdir(directory);
if (result != ISC_R_SUCCESS) {
cfg_obj_log(obj, ISC_LOG_ERROR,
"change directory to '%s' failed: %s", directory,
isc_result_totext(result));
return result;
}
char cwd[PATH_MAX];
if (getcwd(cwd, sizeof(cwd)) == cwd) {
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
ISC_LOG_INFO, "the working directory is now '%s'",
cwd);
}
return ISC_R_SUCCESS;
}
isc_result_t
named_config_parsefile(cfg_parser_t *parser, cfg_obj_t **conf) {
named_config_parsefile(cfg_obj_t **conf) {
isc_result_t result;
REQUIRE(parser);
REQUIRE(conf && *conf == NULL);
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
ISC_LOG_INFO, "parsing user configuration from '%s'",
named_g_conffile);
cfg_parser_setcallback(parser, directory_callback, NULL);
result = cfg_parse_file(parser, named_g_conffile, &cfg_type_namedconf,
conf);
result = cfg_parse_file(isc_g_mctx, named_g_conffile,
&cfg_type_namedconf, 0, conf);
if (result != ISC_R_SUCCESS) {
goto cleanup;
}
@ -457,7 +406,7 @@ named_config_parsefile(cfg_parser_t *parser, cfg_obj_t **conf) {
cleanup:
if (*conf) {
cfg_obj_destroy(parser, conf);
cfg_obj_detach(conf);
}
out:

View file

@ -787,7 +787,6 @@ register_keys(const cfg_obj_t *control, const cfg_obj_t *keylist,
static isc_result_t
get_rndckey(isc_mem_t *mctx, controlkeylist_t *keyids) {
isc_result_t result;
cfg_parser_t *pctx = NULL;
cfg_obj_t *config = NULL;
const cfg_obj_t *key = NULL;
const cfg_obj_t *algobj = NULL;
@ -806,8 +805,7 @@ get_rndckey(isc_mem_t *mctx, controlkeylist_t *keyids) {
return ISC_R_FILENOTFOUND;
}
CHECK(cfg_parser_create(mctx, &pctx));
CHECK(cfg_parse_file(pctx, named_g_keyfile, &cfg_type_rndckey,
CHECK(cfg_parse_file(mctx, named_g_keyfile, &cfg_type_rndckey, 0,
&config));
CHECK(cfg_map_get(config, "key", &key));
@ -861,10 +859,7 @@ cleanup:
free_controlkey(keyid, mctx);
}
if (config != NULL) {
cfg_obj_destroy(pctx, &config);
}
if (pctx != NULL) {
cfg_parser_destroy(&pctx);
cfg_obj_detach(&config);
}
return result;
}

View file

@ -25,10 +25,10 @@
#define DEFAULT_IANA_ROOT_ZONE_PRIMARIES "_default_iana_root_zone_primaries"
isc_result_t
named_config_parsedefaults(cfg_parser_t *parser, cfg_obj_t **conf);
named_config_parsedefaults(cfg_obj_t **conf);
isc_result_t
named_config_parsefile(cfg_parser_t *parser, cfg_obj_t **conf);
named_config_parsefile(cfg_obj_t **conf);
const char *
named_config_getdefault(void);

View file

@ -61,8 +61,6 @@ EXTERN bool named_g_run_done INIT(false);
* for really short timers, another for client timers, and one
* for zone timers.
*/
EXTERN cfg_parser_t *named_g_parser INIT(NULL);
EXTERN cfg_parser_t *named_g_addparser INIT(NULL);
EXTERN const char *named_g_version INIT(PACKAGE_VERSION);
EXTERN const char *named_g_product INIT(PACKAGE_NAME);
EXTERN const char *named_g_description INIT(PACKAGE_DESCRIPTION);

View file

@ -513,7 +513,6 @@ printversion(bool verbose) {
isc_buffer_t b;
char buf[512];
#if defined(HAVE_GEOIP2)
cfg_parser_t *parser = NULL;
cfg_obj_t *config = NULL;
const cfg_obj_t *defaults = NULL, *obj = NULL;
#endif /* if defined(HAVE_GEOIP2) */
@ -611,15 +610,13 @@ printversion(bool verbose) {
#define RTC(x) RUNTIME_CHECK((x) == ISC_R_SUCCESS)
isc_mem_t *geoip_mctx = NULL;
isc_mem_create("geoip", &geoip_mctx);
RTC(cfg_parser_create(geoip_mctx, &parser));
RTC(named_config_parsedefaults(parser, &config));
RTC(named_config_parsedefaults(&config));
RTC(cfg_map_get(config, "options", &defaults));
RTC(cfg_map_get(defaults, "geoip-directory", &obj));
if (cfg_obj_isstring(obj)) {
printf(" geoip-directory: %s\n", cfg_obj_asstring(obj));
}
cfg_obj_destroy(parser, &config);
cfg_parser_destroy(&parser);
cfg_obj_detach(&config);
isc_mem_detach(&geoip_mctx);
#endif /* HAVE_GEOIP2 */
}

View file

@ -307,8 +307,6 @@ typedef struct matching_view_ctx {
*/
typedef struct ns_cfgctx {
isc_mem_t *mctx;
cfg_parser_t *conf_parser;
cfg_parser_t *add_parser;
cfg_obj_t *config;
cfg_obj_t *vconfig;
cfg_obj_t *nzf_config;
@ -2465,8 +2463,7 @@ catz_addmodzone_cb(void *arg) {
confbuf = NULL;
result = dns_catz_generate_zonecfg(cz->origin, cz->entry, &confbuf);
if (result == ISC_R_SUCCESS) {
cfg_parser_reset(cfg->add_parser);
result = cfg_parse_buffer(cfg->add_parser, confbuf, "catz", 0,
result = cfg_parse_buffer(cfg->mctx, confbuf, "catz", 0,
&cfg_type_addzoneconf, 0, &zoneconf);
isc_buffer_free(&confbuf);
}
@ -2544,7 +2541,7 @@ cleanup:
dns_zone_detach(&zone);
}
if (zoneconf != NULL) {
cfg_obj_destroy(cfg->add_parser, &zoneconf);
cfg_obj_detach(&zoneconf);
}
if (dnsforwarders != NULL) {
dns_forwarders_detach(&dnsforwarders);
@ -2744,8 +2741,7 @@ catz_reconfigure(dns_catz_entry_t *entry, void *arg1, void *arg2) {
result = dns_catz_generate_zonecfg(data->catz, entry, &confbuf);
if (result == ISC_R_SUCCESS) {
cfg_parser_reset(cfg->add_parser);
result = cfg_parse_buffer(cfg->add_parser, confbuf, "catz", 0,
result = cfg_parse_buffer(cfg->mctx, confbuf, "catz", 0,
&cfg_type_addzoneconf, 0, &zoneconf);
isc_buffer_free(&confbuf);
}
@ -2783,7 +2779,7 @@ catz_reconfigure(dns_catz_entry_t *entry, void *arg1, void *arg2) {
cleanup:
if (zoneconf != NULL) {
cfg_obj_destroy(cfg->add_parser, &zoneconf);
cfg_obj_detach(&zoneconf);
}
dns_zone_detach(&zone);
@ -7338,7 +7334,7 @@ cleanup:
static isc_result_t
setup_newzones(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
cfg_parser_t *config_parser, cfg_aclconfctx_t *aclctx) {
cfg_aclconfctx_t *aclctx) {
isc_result_t result = ISC_R_SUCCESS;
bool allow = false;
ns_cfgctx_t *nzcfg = NULL;
@ -7445,16 +7441,12 @@ setup_newzones(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
* a shutdown race later.
*/
isc_mem_attach(view->mctx, &nzcfg->mctx);
cfg_parser_attach(config_parser, &nzcfg->conf_parser);
cfg_parser_attach(named_g_addparser, &nzcfg->add_parser);
cfg_aclconfctx_attach(aclctx, &nzcfg->aclctx);
result = dns_view_setnewzones(view, true, nzcfg, newzone_cfgctx_destroy,
mapsize);
if (result != ISC_R_SUCCESS) {
cfg_aclconfctx_detach(&nzcfg->aclctx);
cfg_parser_destroy(&nzcfg->conf_parser);
cfg_parser_destroy(&nzcfg->add_parser);
isc_mem_putanddetach(&nzcfg->mctx, nzcfg, sizeof(*nzcfg));
dns_view_setnewzones(view, false, NULL, NULL, 0ULL);
return result;
@ -7548,7 +7540,7 @@ cleanup:
return result;
}
#else /* HAVE_LMDB */
#else /* HAVE_LMDB */
static isc_result_t
data_to_cfg(dns_view_t *view, MDB_val *key, MDB_val *data, isc_buffer_t **text,
@ -7597,8 +7589,7 @@ data_to_cfg(dns_view_t *view, MDB_val *key, MDB_val *data, isc_buffer_t **text,
snprintf(bufname, sizeof(bufname), "%.*s", (int)zone_name_len,
zone_name);
cfg_parser_reset(named_g_addparser);
result = cfg_parse_buffer(named_g_addparser, *text, bufname, 0,
result = cfg_parse_buffer(view->mctx, *text, bufname, 0,
&cfg_type_addzoneconf, 0, &zoneconf);
if (result != ISC_R_SUCCESS) {
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
@ -7615,7 +7606,7 @@ data_to_cfg(dns_view_t *view, MDB_val *key, MDB_val *data, isc_buffer_t **text,
cleanup:
if (zoneconf != NULL) {
cfg_obj_destroy(named_g_addparser, &zoneconf);
cfg_obj_detach(&zoneconf);
}
return result;
@ -7696,14 +7687,14 @@ for_all_newzone_cfgs(newzone_cfg_cb_t callback, cfg_obj_t *config,
/*
* Destroy the configuration object created in this iteration.
*/
cfg_obj_destroy(named_g_addparser, &zconfigobj);
cfg_obj_detach(&zconfigobj);
}
if (text != NULL) {
isc_buffer_free(&text);
}
if (zconfigobj != NULL) {
cfg_obj_destroy(named_g_addparser, &zconfigobj);
cfg_obj_detach(&zconfigobj);
}
mdb_cursor_close(cursor);
@ -7786,70 +7777,6 @@ configure_newzones(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
return result;
}
static isc_result_t
get_newzone_config(dns_view_t *view, const char *zonename,
cfg_obj_t **zoneconfig) {
isc_result_t result;
int status;
cfg_obj_t *zoneconf = NULL;
isc_buffer_t *text = NULL;
MDB_txn *txn = NULL;
MDB_dbi dbi;
MDB_val key, data;
char zname[DNS_NAME_FORMATSIZE];
dns_fixedname_t fname;
dns_name_t *name;
isc_buffer_t b;
INSIST(zoneconfig != NULL && *zoneconfig == NULL);
LOCK(&view->new_zone_lock);
CHECK(nzd_open(view, MDB_RDONLY, &txn, &dbi));
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
ISC_LOG_INFO,
"loading NZD config from '%s' "
"for zone '%s'",
view->new_zone_db, zonename);
/* Normalize zone name */
isc_buffer_constinit(&b, zonename, strlen(zonename));
isc_buffer_add(&b, strlen(zonename));
name = dns_fixedname_initname(&fname);
CHECK(dns_name_fromtext(name, &b, dns_rootname, DNS_NAME_DOWNCASE));
dns_name_format(name, zname, sizeof(zname));
key.mv_data = zname;
key.mv_size = strlen(zname);
status = mdb_get(txn, dbi, &key, &data);
if (status != MDB_SUCCESS) {
CHECK(ISC_R_FAILURE);
}
CHECK(data_to_cfg(view, &key, &data, &text, &zoneconf));
*zoneconfig = zoneconf;
zoneconf = NULL;
result = ISC_R_SUCCESS;
cleanup:
(void)nzd_close(&txn, false);
UNLOCK(&view->new_zone_lock);
if (zoneconf != NULL) {
cfg_obj_destroy(named_g_addparser, &zoneconf);
}
if (text != NULL) {
isc_buffer_free(&text);
}
return result;
}
#endif /* HAVE_LMDB */
#define APPLY_CONFIGURATION_SUBROUTINE_LOG \
@ -7857,7 +7784,7 @@ cleanup:
ISC_LOG_DEBUG(1), "apply_configuration: %s", __func__);
static isc_result_t
create_views(cfg_obj_t *config, cfg_parser_t *parser, cfg_aclconfctx_t *aclctx,
create_views(cfg_obj_t *config, cfg_aclconfctx_t *aclctx,
dns_viewlist_t *viewlist) {
isc_result_t result = ISC_R_SUCCESS;
const cfg_obj_t *views = NULL;
@ -7875,7 +7802,7 @@ create_views(cfg_obj_t *config, cfg_parser_t *parser, cfg_aclconfctx_t *aclctx,
}
INSIST(view != NULL);
result = setup_newzones(view, config, vconfig, parser, aclctx);
result = setup_newzones(view, config, vconfig, aclctx);
dns_view_detach(&view);
if (result != ISC_R_SUCCESS) {
@ -7896,7 +7823,7 @@ create_views(cfg_obj_t *config, cfg_parser_t *parser, cfg_aclconfctx_t *aclctx,
}
INSIST(view != NULL);
result = setup_newzones(view, config, NULL, parser, aclctx);
result = setup_newzones(view, config, NULL, aclctx);
dns_view_detach(&view);
}
@ -8114,9 +8041,8 @@ configure_kasplist(const cfg_obj_t *config, dns_kasplist_t *kasplist,
}
static isc_result_t
apply_configuration(cfg_parser_t *configparser, cfg_obj_t *config,
cfg_obj_t *bindkeys, named_server_t *server,
bool first_time) {
apply_configuration(cfg_obj_t *config, cfg_obj_t *bindkeys,
named_server_t *server, bool first_time) {
const cfg_obj_t *maps[3];
const cfg_obj_t *obj = NULL;
const cfg_obj_t *options = NULL;
@ -8192,7 +8118,7 @@ apply_configuration(cfg_parser_t *configparser, cfg_obj_t *config,
goto cleanup_kasplist;
}
result = create_views(config, configparser, aclctx, &viewlist);
result = create_views(config, aclctx, &viewlist);
if (result != ISC_R_SUCCESS) {
goto cleanup_viewlist;
}
@ -8217,8 +8143,7 @@ apply_configuration(cfg_parser_t *configparser, cfg_obj_t *config,
if (getcwd(cwd, sizeof(cwd)) == cwd) {
isc_log_write(NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_SERVER, ISC_LOG_INFO,
"the initial working directory is '%s'",
cwd);
"the working directory is now '%s'", cwd);
}
}
@ -9297,21 +9222,12 @@ cleanup_aclctx:
static isc_result_t
load_configuration(named_server_t *server, bool first_time) {
isc_result_t result;
cfg_parser_t *parser = NULL;
cfg_obj_t *config = NULL, *bindkeys = NULL;
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
ISC_LOG_DEBUG(1), "load_configuration");
result = cfg_parser_create(isc_g_mctx, &parser);
if (result != ISC_R_SUCCESS) {
goto out;
}
result = named_config_parsefile(parser, &config);
if (result != ISC_R_SUCCESS) {
goto cleanup;
}
CHECK(named_config_parsefile(&config));
if (named_g_bindkeysfile != NULL) {
/*
@ -9327,9 +9243,9 @@ load_configuration(named_server_t *server, bool first_time) {
"keys instead",
named_g_bindkeysfile);
} else {
cfg_parser_reset(parser);
result = cfg_parse_file(parser, named_g_bindkeysfile,
&cfg_type_bindkeys, &bindkeys);
result = cfg_parse_file(
isc_g_mctx, named_g_bindkeysfile,
&cfg_type_bindkeys, 0, &bindkeys);
if (result != ISC_R_SUCCESS) {
isc_log_write(NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_SERVER,
@ -9343,19 +9259,16 @@ load_configuration(named_server_t *server, bool first_time) {
}
}
result = apply_configuration(parser, config, bindkeys, server,
first_time);
result = apply_configuration(config, bindkeys, server, first_time);
cleanup:
if (bindkeys != NULL) {
cfg_obj_destroy(parser, &bindkeys);
cfg_obj_detach(&bindkeys);
}
if (config != NULL) {
cfg_obj_destroy(parser, &config);
cfg_obj_detach(&config);
}
cfg_parser_destroy(&parser);
out:
return result;
}
@ -9529,20 +9442,13 @@ run_server(void *arg) {
isc_timer_create(isc_loop_main(), pps_timer_tick, server,
&server->pps_timer);
CHECKFATAL(cfg_parser_create(isc_g_mctx, &named_g_parser),
"creating default configuration parser");
CHECKFATAL(named_config_parsedefaults(named_g_parser,
&named_g_defaultconfig),
CHECKFATAL(named_config_parsedefaults(&named_g_defaultconfig),
"unable to parse defaults config");
CHECKFATAL(cfg_map_get(named_g_defaultconfig, "options",
&named_g_defaultoptions),
"missing 'options' in default config");
CHECKFATAL(cfg_parser_create(isc_g_mctx, &named_g_addparser),
"creating additional configuration parser");
CHECKFATAL(load_configuration(server, true), "loading configuration");
CHECKFATAL(load_zones(server, false), "loading zones");
@ -9594,9 +9500,7 @@ shutdown_server(void *arg) {
cfg_aclconfctx_detach(&server->aclctx);
}
cfg_obj_destroy(named_g_parser, &named_g_defaultconfig);
cfg_parser_destroy(&named_g_parser);
cfg_parser_destroy(&named_g_addparser);
cfg_obj_detach(&named_g_defaultconfig);
(void)named_server_saventa(server);
@ -12547,9 +12451,8 @@ load_nzf(dns_view_t *view, ns_cfgctx_t *nzcfg) {
* Parse the configuration in the NZF file. This may be called in
* multiple views, so we reset the parser each time.
*/
cfg_parser_reset(named_g_addparser);
result = cfg_parse_file(named_g_addparser, view->new_zone_file,
&cfg_type_addzoneconf, &nzcfg->nzf_config);
result = cfg_parse_file(nzcfg->mctx, view->new_zone_file,
&cfg_type_addzoneconf, 0, &nzcfg->nzf_config);
if (result != ISC_R_SUCCESS) {
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
ISC_LOG_ERROR, "Error parsing NZF file '%s': %s",
@ -12920,9 +12823,8 @@ load_nzf(dns_view_t *view, ns_cfgctx_t *nzcfg) {
* config type, giving us a guarantee that valid configuration
* will be written to DB.
*/
cfg_parser_reset(named_g_addparser);
result = cfg_parse_file(named_g_addparser, view->new_zone_file,
&cfg_type_addzoneconf, &nzf_config);
result = cfg_parse_file(nzcfg->mctx, view->new_zone_file,
&cfg_type_addzoneconf, 0, &nzf_config);
if (result != ISC_R_SUCCESS) {
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
ISC_LOG_ERROR, "Error parsing NZF file '%s': %s",
@ -13029,7 +12931,7 @@ cleanup:
}
if (nzf_config != NULL) {
cfg_obj_destroy(named_g_addparser, &nzf_config);
cfg_obj_detach(&nzf_config);
}
return result;
@ -13076,9 +12978,9 @@ newzone_parse(named_server_t *server, char *command, dns_view_t **viewp,
*/
isc_buffer_forward(&argbuf, 3);
cfg_parser_reset(named_g_addparser);
CHECK(cfg_parse_buffer(named_g_addparser, &argbuf, bn, 0,
CHECK(cfg_parse_buffer(server->mctx, &argbuf, bn, 0,
&cfg_type_addzoneconf, 0, &zoneconf));
CHECK(cfg_map_get(zoneconf, "zone", &zlist));
if (!cfg_obj_islist(zlist)) {
CHECK(ISC_R_FAILURE);
@ -13153,7 +13055,7 @@ newzone_parse(named_server_t *server, char *command, dns_view_t **viewp,
cleanup:
if (zoneconf != NULL) {
cfg_obj_destroy(named_g_addparser, &zoneconf);
cfg_obj_detach(&zoneconf);
}
if (view != NULL) {
dns_view_detach(&view);
@ -13163,13 +13065,12 @@ cleanup:
}
static isc_result_t
delete_zoneconf(dns_view_t *view, cfg_parser_t *pctx, const cfg_obj_t *config,
delete_zoneconf(dns_view_t *view, const cfg_obj_t *config,
const dns_name_t *zname, nzfwriter_t nzfwriter) {
isc_result_t result = ISC_R_NOTFOUND;
const cfg_obj_t *zl = NULL;
REQUIRE(view != NULL);
REQUIRE(pctx != NULL);
REQUIRE(config != NULL);
REQUIRE(zname != NULL);
@ -13187,7 +13088,6 @@ delete_zoneconf(dns_view_t *view, cfg_parser_t *pctx, const cfg_obj_t *config,
dns_name_t *myname = dns_fixedname_initname(&myfixed);
const cfg_obj_t *zconf = cfg_listelt_value(elt);
const char *zn = NULL;
cfg_listelt_t *e = NULL;
zn = cfg_obj_asstring(cfg_tuple_get(zconf, "name"));
result = dns_name_fromstring(myname, zn, dns_rootname, 0, NULL);
@ -13195,10 +13095,8 @@ delete_zoneconf(dns_view_t *view, cfg_parser_t *pctx, const cfg_obj_t *config,
continue;
}
e = UNCONST(elt);
ISC_LIST_UNLINK(*list, e, link);
cfg_obj_destroy(pctx, &e->obj);
isc_mem_put(pctx->mctx, e, sizeof(*e));
cfg_obj_t *zones = UNCONST(zl);
cfg_list_unlink(zones, elt);
result = ISC_R_SUCCESS;
break;
}
@ -13335,8 +13233,7 @@ do_addzone(named_server_t *server, ns_cfgctx_t *cfg, dns_view_t *view,
cfg_obj_attach(zoneconf, &cfg->nzf_config);
} else {
cfg_obj_t *z = UNCONST(zoneobj);
CHECK(cfg_parser_mapadd(cfg->add_parser, cfg->nzf_config, z,
"zone"));
CHECK(cfg_map_add(cfg->nzf_config, z, "zone"));
}
cleanup_config = true;
#endif /* HAVE_LMDB */
@ -13385,8 +13282,7 @@ cleanup:
(void)isc_stdio_close(fp);
}
if (result != ISC_R_SUCCESS && cleanup_config) {
tresult = delete_zoneconf(view, cfg->add_parser,
cfg->nzf_config, name, NULL);
tresult = delete_zoneconf(view, cfg->nzf_config, name, NULL);
RUNTIME_CHECK(tresult == ISC_R_SUCCESS);
}
#else /* HAVE_LMDB */
@ -13519,7 +13415,7 @@ do_modzone(named_server_t *server, ns_cfgctx_t *cfg, dns_view_t *view,
#ifndef HAVE_LMDB
/* Remove old zone from configuration (and NZF file if applicable) */
if (added) {
result = delete_zoneconf(view, cfg->add_parser, cfg->nzf_config,
result = delete_zoneconf(view, cfg->nzf_config,
dns_zone_getorigin(zone),
nzf_writeconf);
if (result != ISC_R_SUCCESS) {
@ -13533,14 +13429,13 @@ do_modzone(named_server_t *server, ns_cfgctx_t *cfg, dns_view_t *view,
if (!added) {
if (cfg->vconfig == NULL) {
result = delete_zoneconf(
view, cfg->conf_parser, cfg->config,
dns_zone_getorigin(zone), NULL);
result = delete_zoneconf(view, cfg->config,
dns_zone_getorigin(zone),
NULL);
} else {
voptions = cfg_tuple_get(cfg->vconfig, "options");
result = delete_zoneconf(
view, cfg->conf_parser, voptions,
dns_zone_getorigin(zone), NULL);
view, voptions, dns_zone_getorigin(zone), NULL);
}
if (result != ISC_R_SUCCESS) {
@ -13589,7 +13484,7 @@ do_modzone(named_server_t *server, ns_cfgctx_t *cfg, dns_view_t *view,
#ifndef HAVE_LMDB
/* Store the new zone configuration; also in NZF if applicable */
z = UNCONST(zoneobj);
CHECK(cfg_parser_mapadd(cfg->add_parser, cfg->nzf_config, z, "zone"));
CHECK(cfg_map_add(cfg->nzf_config, z, "zone"));
#endif /* HAVE_LMDB */
if (added) {
@ -13616,7 +13511,6 @@ do_modzone(named_server_t *server, ns_cfgctx_t *cfg, dns_view_t *view,
}
cleanup:
#ifndef HAVE_LMDB
if (fp != NULL) {
(void)isc_stdio_close(fp);
@ -13721,7 +13615,7 @@ cleanup:
(void)putnull(text);
}
if (zoneconf != NULL) {
cfg_obj_destroy(named_g_addparser, &zoneconf);
cfg_obj_detach(&zoneconf);
}
if (view != NULL) {
dns_view_detach(&view);
@ -13815,7 +13709,7 @@ rmzone(void *arg) {
}
UNLOCK(&view->new_zone_lock);
#else /* ifdef HAVE_LMDB */
result = delete_zoneconf(view, cfg->add_parser, cfg->nzf_config,
result = delete_zoneconf(view, cfg->nzf_config,
dns_zone_getorigin(zone),
nzf_writeconf);
if (result != ISC_R_SUCCESS) {
@ -13832,13 +13726,13 @@ rmzone(void *arg) {
const cfg_obj_t *voptions = cfg_tuple_get(cfg->vconfig,
"options");
result = delete_zoneconf(
view, cfg->conf_parser, voptions,
dns_zone_getorigin(zone), NULL);
view, voptions, dns_zone_getorigin(zone), NULL);
} else {
result = delete_zoneconf(
view, cfg->conf_parser, cfg->config,
dns_zone_getorigin(zone), NULL);
result = delete_zoneconf(view, cfg->config,
dns_zone_getorigin(zone),
NULL);
}
if (result != ISC_R_SUCCESS) {
isc_log_write(NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR,
@ -14043,72 +13937,6 @@ cleanup:
return result;
}
static const cfg_obj_t *
find_name_in_list_from_map(const cfg_obj_t *config,
const char *map_key_for_list, const char *name,
bool redirect) {
const cfg_obj_t *list = NULL;
const cfg_obj_t *obj = NULL;
dns_fixedname_t fixed1, fixed2;
dns_name_t *name1 = NULL, *name2 = NULL;
isc_result_t result;
if (strcmp(map_key_for_list, "zone") == 0) {
name1 = dns_fixedname_initname(&fixed1);
name2 = dns_fixedname_initname(&fixed2);
result = dns_name_fromstring(name1, name, dns_rootname, 0,
NULL);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
}
cfg_map_get(config, map_key_for_list, &list);
CFG_LIST_FOREACH(list, element) {
const char *vname = NULL;
obj = cfg_listelt_value(element);
INSIST(obj != NULL);
vname = cfg_obj_asstring(cfg_tuple_get(obj, "name"));
if (vname == NULL) {
obj = NULL;
continue;
}
if (name1 != NULL) {
result = dns_name_fromstring(name2, vname, dns_rootname,
0, NULL);
if (result == ISC_R_SUCCESS &&
dns_name_equal(name1, name2))
{
const cfg_obj_t *zoptions =
cfg_tuple_get(obj, "options");
const cfg_obj_t *typeobj = NULL;
if (zoptions != NULL) {
const cfg_obj_t *toptions =
named_zone_templateopts(
config, zoptions);
named_config_findopt(zoptions, toptions,
"type", &typeobj);
}
if (redirect && typeobj != NULL &&
strcasecmp(cfg_obj_asstring(typeobj),
"redirect") == 0)
{
break;
} else if (!redirect) {
break;
}
}
} else if (strcasecmp(vname, name) == 0) {
break;
}
obj = NULL;
}
return obj;
}
static void
emitzone(void *arg, const char *buf, int len) {
ns_dzarg_t *dzarg = arg;
@ -14128,16 +13956,9 @@ isc_result_t
named_server_showzone(named_server_t *server, isc_lex_t *lex,
isc_buffer_t **text) {
isc_result_t result;
const cfg_obj_t *vconfig = NULL, *zconfig = NULL;
const cfg_obj_t *zconfig = NULL;
char zonename[DNS_NAME_FORMATSIZE];
const cfg_obj_t *map;
dns_view_t *view = NULL;
dns_zone_t *zone = NULL;
ns_cfgctx_t *cfg = NULL;
#ifdef HAVE_LMDB
cfg_obj_t *nzconfig = NULL;
#endif /* HAVE_LMDB */
bool added, redirect;
ns_dzarg_t dzarg;
REQUIRE(text != NULL);
@ -14149,51 +13970,9 @@ named_server_showzone(named_server_t *server, isc_lex_t *lex,
goto cleanup;
}
redirect = dns_zone_gettype(zone) == dns_zone_redirect;
added = dns_zone_getadded(zone);
view = dns_zone_getview(zone);
zconfig = dns_zone_getcfg(zone);
dns_zone_detach(&zone);
cfg = (ns_cfgctx_t *)view->new_zone_config;
if (cfg == NULL) {
result = ISC_R_FAILURE;
goto cleanup;
}
if (!added) {
/* Find the view statement */
vconfig = find_name_in_list_from_map(cfg->config, "view",
view->name, false);
/* Find the zone statement */
if (vconfig != NULL) {
map = cfg_tuple_get(vconfig, "options");
} else {
map = cfg->config;
}
zconfig = find_name_in_list_from_map(map, "zone", zonename,
redirect);
}
#ifndef HAVE_LMDB
if (zconfig == NULL && cfg->nzf_config != NULL) {
zconfig = find_name_in_list_from_map(cfg->nzf_config, "zone",
zonename, redirect);
}
#else /* HAVE_LMDB */
if (zconfig == NULL) {
const cfg_obj_t *zlist = NULL;
CHECK(get_newzone_config(view, zonename, &nzconfig));
CHECK(cfg_map_get(nzconfig, "zone", &zlist));
if (!cfg_obj_islist(zlist)) {
CHECK(ISC_R_FAILURE);
}
zconfig = cfg_listelt_value(cfg_list_first(zlist));
}
#endif /* HAVE_LMDB */
if (zconfig == NULL) {
CHECK(ISC_R_NOTFOUND);
}
@ -14210,11 +13989,6 @@ named_server_showzone(named_server_t *server, isc_lex_t *lex,
result = ISC_R_SUCCESS;
cleanup:
#ifdef HAVE_LMDB
if (nzconfig != NULL) {
cfg_obj_destroy(named_g_addparser, &nzconfig);
}
#endif /* HAVE_LMDB */
if (isc_buffer_usedlength(*text) > 0) {
(void)putnull(text);
}
@ -14230,20 +14004,14 @@ newzone_cfgctx_destroy(void **cfgp) {
cfg = *cfgp;
if (cfg->conf_parser != NULL) {
if (cfg->config != NULL) {
cfg_obj_destroy(cfg->conf_parser, &cfg->config);
}
if (cfg->vconfig != NULL) {
cfg_obj_destroy(cfg->conf_parser, &cfg->vconfig);
}
cfg_parser_destroy(&cfg->conf_parser);
if (cfg->config != NULL) {
cfg_obj_detach(&cfg->config);
}
if (cfg->add_parser != NULL) {
if (cfg->nzf_config != NULL) {
cfg_obj_destroy(cfg->add_parser, &cfg->nzf_config);
}
cfg_parser_destroy(&cfg->add_parser);
if (cfg->vconfig != NULL) {
cfg_obj_detach(&cfg->vconfig);
}
if (cfg->nzf_config != NULL) {
cfg_obj_detach(&cfg->nzf_config);
}
if (cfg->aclctx != NULL) {

View file

@ -869,6 +869,12 @@ process_notifytype(dns_notifytype_t ntype, dns_zonetype_t ztype,
return dns_notifytype_explicit;
}
static void
detach_cfg(void *arg) {
cfg_obj_t *cfg = (cfg_obj_t *)arg;
cfg_obj_detach(&cfg);
}
isc_result_t
named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
const cfg_obj_t *zconfig, cfg_aclconfctx_t *aclctx,
@ -1908,6 +1914,11 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
break;
}
/* Save the configuration for later use */
cfg_obj_t *cfg = UNCONST(zconfig);
cfg_obj_ref(cfg);
dns_zone_setcfg(zone, (void *)cfg, detach_cfg);
result = ISC_R_SUCCESS;
cleanup:

View file

@ -555,7 +555,6 @@ failure:
*/
static isc_result_t
read_sessionkey(isc_mem_t *mctx) {
cfg_parser_t *pctx = NULL;
cfg_obj_t *sessionkey = NULL;
const cfg_obj_t *key = NULL;
const cfg_obj_t *secretobj = NULL;
@ -570,12 +569,7 @@ read_sessionkey(isc_mem_t *mctx) {
return ISC_R_FILENOTFOUND;
}
result = cfg_parser_create(mctx, &pctx);
if (result != ISC_R_SUCCESS) {
goto cleanup;
}
result = cfg_parse_file(pctx, keyfile, &cfg_type_sessionkey,
result = cfg_parse_file(mctx, keyfile, &cfg_type_sessionkey, 0,
&sessionkey);
if (result != ISC_R_SUCCESS) {
goto cleanup;
@ -602,11 +596,8 @@ read_sessionkey(isc_mem_t *mctx) {
setup_keystr();
cleanup:
if (pctx != NULL) {
if (sessionkey != NULL) {
cfg_obj_destroy(pctx, &sessionkey);
}
cfg_parser_destroy(&pctx);
if (sessionkey != NULL) {
cfg_obj_detach(&sessionkey);
}
if (keystr != NULL) {

View file

@ -274,16 +274,13 @@ parse_parameters(filter_instance_t *inst, const char *parameters,
const void *cfg, const char *cfg_file, unsigned long cfg_line,
isc_mem_t *mctx, void *aclctx) {
isc_result_t result = ISC_R_SUCCESS;
cfg_parser_t *parser = NULL;
cfg_obj_t *param_obj = NULL;
const cfg_obj_t *obj = NULL;
isc_buffer_t b;
CHECK(cfg_parser_create(mctx, &parser));
isc_buffer_constinit(&b, parameters, strlen(parameters));
isc_buffer_add(&b, strlen(parameters));
CHECK(cfg_parse_buffer(parser, &b, cfg_file, cfg_line,
CHECK(cfg_parse_buffer(mctx, &b, cfg_file, cfg_line,
&cfg_type_parameters, 0, &param_obj));
CHECK(parse_filter_a_on(param_obj, "filter-a-on-v6", &inst->v6_a));
@ -300,10 +297,7 @@ parse_parameters(filter_instance_t *inst, const char *parameters,
cleanup:
if (param_obj != NULL) {
cfg_obj_destroy(parser, &param_obj);
}
if (parser != NULL) {
cfg_parser_destroy(&parser);
cfg_obj_detach(&param_obj);
}
return result;
}
@ -368,25 +362,19 @@ plugin_check(const char *parameters, const void *cfg, const char *cfg_file,
unsigned long cfg_line, isc_mem_t *mctx, void *aclctx,
const ns_pluginctx_t *ctx ISC_ATTR_UNUSED) {
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, &parser));
isc_buffer_constinit(&b, parameters, strlen(parameters));
isc_buffer_add(&b, strlen(parameters));
CHECK(cfg_parse_buffer(parser, &b, cfg_file, cfg_line,
CHECK(cfg_parse_buffer(mctx, &b, cfg_file, cfg_line,
&cfg_type_parameters, 0, &param_obj));
CHECK(check_syntax(param_obj, cfg, mctx, aclctx));
cleanup:
if (param_obj != NULL) {
cfg_obj_destroy(parser, &param_obj);
}
if (parser != NULL) {
cfg_parser_destroy(&parser);
cfg_obj_detach(&param_obj);
}
return result;
}

View file

@ -275,16 +275,13 @@ parse_parameters(filter_instance_t *inst, const char *parameters,
const void *cfg, const char *cfg_file, unsigned long cfg_line,
isc_mem_t *mctx, void *aclctx) {
isc_result_t result = ISC_R_SUCCESS;
cfg_parser_t *parser = NULL;
cfg_obj_t *param_obj = NULL;
const cfg_obj_t *obj = NULL;
isc_buffer_t b;
CHECK(cfg_parser_create(mctx, &parser));
isc_buffer_constinit(&b, parameters, strlen(parameters));
isc_buffer_add(&b, strlen(parameters));
CHECK(cfg_parse_buffer(parser, &b, cfg_file, cfg_line,
CHECK(cfg_parse_buffer(mctx, &b, cfg_file, cfg_line,
&cfg_type_parameters, 0, &param_obj));
CHECK(parse_filter_aaaa_on(param_obj, "filter-aaaa-on-v4",
@ -303,10 +300,7 @@ parse_parameters(filter_instance_t *inst, const char *parameters,
cleanup:
if (param_obj != NULL) {
cfg_obj_destroy(parser, &param_obj);
}
if (parser != NULL) {
cfg_parser_destroy(&parser);
cfg_obj_detach(&param_obj);
}
return result;
}
@ -372,25 +366,19 @@ plugin_check(const char *parameters, const void *cfg, const char *cfg_file,
unsigned long cfg_line, isc_mem_t *mctx, void *aclctx,
const ns_pluginctx_t *ctx ISC_ATTR_UNUSED) {
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, &parser));
isc_buffer_constinit(&b, parameters, strlen(parameters));
isc_buffer_add(&b, strlen(parameters));
CHECK(cfg_parse_buffer(parser, &b, cfg_file, cfg_line,
CHECK(cfg_parse_buffer(mctx, &b, cfg_file, cfg_line,
&cfg_type_parameters, 0, &param_obj));
CHECK(check_syntax(param_obj, cfg, mctx, aclctx));
cleanup:
if (param_obj != NULL) {
cfg_obj_destroy(parser, &param_obj);
}
if (parser != NULL) {
cfg_parser_destroy(&parser);
cfg_obj_detach(&param_obj);
}
return result;
}

View file

@ -573,16 +573,13 @@ synthrecord_parseconfig(synthrecord_t *inst, const char *parameters,
const dns_name_t *zname) {
isc_result_t result;
isc_mem_t *mctx = inst->mctx;
cfg_parser_t *parser = NULL;
cfg_obj_t *synthrecordcfg = NULL;
isc_buffer_t b;
CHECK(cfg_parser_create(mctx, &parser));
isc_buffer_constinit(&b, parameters, strlen(parameters));
isc_buffer_add(&b, strlen(parameters));
CHECK(cfg_parse_buffer(parser, &b, cfgfile, cfgline,
CHECK(cfg_parse_buffer(mctx, &b, cfgfile, cfgline,
&synthrecord_cfgparams, 0, &synthrecordcfg));
synthrecord_setconfigmode(inst, zname);
@ -593,11 +590,7 @@ synthrecord_parseconfig(synthrecord_t *inst, const char *parameters,
cleanup:
if (synthrecordcfg != NULL) {
cfg_obj_destroy(parser, &synthrecordcfg);
}
if (parser != NULL) {
cfg_parser_destroy(&parser);
cfg_obj_detach(&synthrecordcfg);
}
return result;

View file

@ -535,8 +535,7 @@ rndc_start(void *arg) {
}
static void
parse_config(isc_mem_t *mctx, const char *keyname, cfg_parser_t **pctxp,
cfg_obj_t **configp) {
parse_config(isc_mem_t *mctx, const char *keyname, cfg_obj_t **configp) {
isc_result_t result;
const char *conffile = admin_conffile;
const cfg_obj_t *addresses = NULL;
@ -577,12 +576,10 @@ parse_config(isc_mem_t *mctx, const char *keyname, cfg_parser_t **pctxp,
admin_keyfile, admin_conffile);
}
DO("create parser", cfg_parser_create(mctx, pctxp));
/*
* The parser will output its own errors, so DO() is not used.
*/
result = cfg_parse_file(*pctxp, conffile, conftype, &config);
result = cfg_parse_file(mctx, conffile, conftype, 0, &config);
if (result != ISC_R_SUCCESS) {
fatal("could not load rndc configuration");
}
@ -809,7 +806,6 @@ int
main(int argc, char **argv) {
bool show_final_mem = false;
isc_logconfig_t *logconfig = NULL;
cfg_parser_t *pctx = NULL;
cfg_obj_t *config = NULL;
const char *keyname = NULL;
struct in_addr in;
@ -963,7 +959,7 @@ main(int argc, char **argv) {
ISC_LOG_PRINTTAG | ISC_LOG_PRINTLEVEL, ISC_LOGCATEGORY_DEFAULT,
ISC_LOGMODULE_DEFAULT);
parse_config(isc_g_mctx, keyname, &pctx, &config);
parse_config(isc_g_mctx, keyname, &config);
isc_buffer_allocate(isc_g_mctx, &databuf, 2048);
@ -999,8 +995,7 @@ main(int argc, char **argv) {
isccc_ccmsg_invalidate(&rndc_ccmsg);
cfg_obj_destroy(pctx, &config);
cfg_parser_destroy(&pctx);
cfg_obj_detach(&config);
isc_mem_put(isc_g_mctx, args, argslen);

View file

@ -10,6 +10,7 @@
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
{% set allownewzones = allownewzones | default(True) %}
key rndc_key {
secret "1234abcd8765";
@ -27,7 +28,11 @@ options {
listen-on-v6 { none; };
allow-transfer { any; };
allow-query { any; };
{% if allownewzones %}
allow-new-zones yes;
{% else %}
allow-new-zones no;
{% endif %}
recursion no;
dnssec-validation no;
};

View file

@ -17,7 +17,6 @@ cp -f ns1/redirect.db.1 ns1/redirect.db
cp -f ns2/redirect.db.1 ns2/redirect.db
cp -f ns3/redirect.db.1 ns3/redirect.db
copy_setports ns1/named.conf.in ns1/named.conf
copy_setports ns2/named1.conf.in ns2/named.conf
copy_setports ns3/named1.conf.in ns3/named.conf

View file

@ -69,19 +69,19 @@ if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status + ret))
nextpart ns2/named.run >/dev/null
echo_i "checking addzone errors are logged correctly"
echo_i "checking addzone errors are logged correctly ($n)"
ret=0
$RNDCCMD 10.53.0.2 addzone bad.example '{ type mister; };' 2>&1 | grep 'unexpected token' >/dev/null 2>&1 || ret=1
wait_for_log_peek 20 "addzone: 'mister' unexpected" ns2/named.run || ret=1
wait_for_log_peek 20 "addzone:1: 'mister' unexpected" ns2/named.run || ret=1
n=$((n + 1))
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status + ret))
nextpart ns2/named.run >/dev/null
echo_i "checking modzone errors are logged correctly"
echo_i "checking modzone errors are logged correctly ($n)"
ret=0
$RNDCCMD 10.53.0.2 modzone added.example '{ type mister; };' 2>&1 | grep 'unexpected token' >/dev/null 2>&1 || ret=1
wait_for_log_peek 20 "modzone: 'mister' unexpected" ns2/named.run || ret=1
wait_for_log_peek 20 "modzone:1: 'mister' unexpected" ns2/named.run || ret=1
n=$((n + 1))
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status + ret))

View file

@ -0,0 +1,31 @@
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# SPDX-License-Identifier: MPL-2.0
#
# 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 https://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
import pytest
# Test that `rndc showzone` can print any zone, including those statically
# defined in named.conf, and not only those added dynamically.
@pytest.mark.parametrize(
"allow",
[
pytest.param(True, id="allow-new-zones-yes"),
pytest.param(False, id="allow-new-zones-no"),
],
)
def test_showzone_static(ns1, templates, allow):
templates.render("ns1/named.conf", {"allownewzones": allow})
ns1.rndc("reload", log=False)
zoneconfig = ns1.rndc("showzone inlinesec.example", log=False)
assert (
zoneconfig
== 'zone "inlinesec.example" { type primary; file "inlinesec.db"; };\n'
)

View file

@ -522,6 +522,7 @@ n=$((n + 1))
echo_i "check that named-checkconf -l prints out the zone list ($n)"
ret=0
$CHECKCONF -l good.conf \
| grep -v "working directory is" \
| grep -v "is deprecated" \
| grep -v "is not implemented" \
| grep -v "is not recommended" \

View file

@ -116,7 +116,6 @@ plugin_register(const char *parameters, const void *cfg, const char *cfgfile,
ns_hooktable_t *hooktable, const ns_pluginctx_t *ctx,
void **instp) {
isc_result_t result;
cfg_parser_t *parser = NULL;
cfg_obj_t *syncplugincfg = NULL;
const cfg_obj_t *obj = NULL;
isc_buffer_t b;
@ -135,12 +134,10 @@ plugin_register(const char *parameters, const void *cfg, const char *cfgfile,
*inst = (syncplugin_t){ .mctx = mctx };
*instp = inst;
CHECK(cfg_parser_create(mctx, &parser));
isc_buffer_constinit(&b, parameters, strlen(parameters));
isc_buffer_add(&b, strlen(parameters));
CHECK(cfg_parse_buffer(parser, &b, cfgfile, cfgline,
CHECK(cfg_parse_buffer(mctx, &b, cfgfile, cfgline,
&syncplugin__cfgparams, 0, &syncplugincfg));
CHECK(syncplugin__parse_rcode(syncplugincfg, &inst->rcode));
@ -217,11 +214,7 @@ cleanup:
}
if (syncplugincfg != NULL) {
cfg_obj_destroy(parser, &syncplugincfg);
}
if (parser != NULL) {
cfg_parser_destroy(&parser);
cfg_obj_detach(&syncplugincfg);
}
return result;

View file

@ -52,7 +52,6 @@ int
main(int argc, char **argv) {
isc_result_t result;
isc_mem_t *mctx = NULL;
cfg_parser_t *pctx = NULL;
cfg_obj_t *cfg = NULL;
cfg_type_t *type = NULL;
bool grammar = false;
@ -134,9 +133,7 @@ main(int argc, char **argv) {
if (type == NULL || filename == NULL) {
usage();
}
RUNTIME_CHECK(cfg_parser_create(mctx, &pctx) == ISC_R_SUCCESS);
result = cfg_parse_file(pctx, filename, type, &cfg);
result = cfg_parse_file(mctx, filename, type, 0, &cfg);
fprintf(stderr, "read config: %s\n", isc_result_totext(result));
@ -146,9 +143,7 @@ main(int argc, char **argv) {
cfg_print(cfg, output, NULL);
cfg_obj_destroy(pctx, &cfg);
cfg_parser_destroy(&pctx);
cfg_obj_detach(&cfg);
}
if (memstats) {

View file

@ -2777,6 +2777,25 @@ dns_zone_unloadplugins(dns_zone_t *zone);
* \li 'zone' to be a valid zone.
*/
void
dns_zone_setcfg(dns_zone_t *zone, void *cfg, void (*cfg_detach)(void *));
/*%<
* Set a pointer to the configuration object for 'zone', which can be
* used later to dump the configuration status.
*
* Requires:
* \li 'zone' to be a valid zone.
*/
void *
dns_zone_getcfg(dns_zone_t *zone);
/*%<
* Return a pointer to the configuration object for 'zone', that was
* previously set using _setcfg().
*
* Requires:
* \li 'zone' to be a valid zone.
*/
#if DNS_ZONE_TRACE
#define dns_zone_ref(ptr) dns_zone__ref(ptr, __func__, __FILE__, __LINE__)
#define dns_zone_unref(ptr) dns_zone__unref(ptr, __func__, __FILE__, __LINE__)

View file

@ -538,6 +538,10 @@ struct dns_zone {
void (*plugins_free)(isc_mem_t *, void **);
void *hooktable;
void (*hooktable_free)(isc_mem_t *, void **);
/* Configuration object */
void *cfg;
void (*cfg_detach)(void *);
};
#define zonediff_init(z, d) \
@ -15343,6 +15347,9 @@ zone_shutdown(void *arg) {
dns_zonemgr_releasezone(zone->zmgr, zone);
}
/* Detach the zone configuration pointer */
dns_zone_setcfg(zone, NULL, NULL);
LOCK_ZONE(zone);
INSIST(zone != zone->raw);
@ -24908,3 +24915,22 @@ dns_zone_unloadplugins(dns_zone_t *zone) {
zone->plugins_free = NULL;
}
}
void
dns_zone_setcfg(dns_zone_t *zone, void *cfg, void (*cfg_detach)(void *)) {
REQUIRE(DNS_ZONE_VALID(zone));
if (zone->cfg != NULL && zone->cfg_detach != NULL) {
zone->cfg_detach(zone->cfg);
zone->cfg = NULL;
}
zone->cfg = cfg;
zone->cfg_detach = cfg_detach;
}
void *
dns_zone_getcfg(dns_zone_t *zone) {
REQUIRE(DNS_ZONE_VALID(zone));
return zone->cfg;
}

View file

@ -85,53 +85,12 @@ typedef isc_result_t (*cfg_parsecallback_t)(const char *clausename,
*** Functions
***/
void
cfg_parser_attach(cfg_parser_t *src, cfg_parser_t **dest);
/*%<
* Reference a parser object.
*/
isc_result_t
cfg_parse_file(isc_mem_t *mctx, const char *file, const cfg_type_t *type,
unsigned int flags, cfg_obj_t **ret);
isc_result_t
cfg_parser_create(isc_mem_t *mctx, cfg_parser_t **ret);
/*%<
* Create a configuration file parser. Any warning and error
* messages will be logged.
*
* The parser object returned can be used for a single call
* to cfg_parse_file() or cfg_parse_buffer(). It must not
* be reused for parsing multiple files or buffers.
*/
void
cfg_parser_setflags(cfg_parser_t *pctx, unsigned int flags, bool turn_on);
/*%<
* Set parser context flags. The flags are not checked for sensibility.
* If 'turn_on' is 'true' the flags will be set, otherwise the flags will
* be cleared.
*
* Requires:
*\li "pctx" is not NULL.
*/
void
cfg_parser_setcallback(cfg_parser_t *pctx, cfg_parsecallback_t callback,
void *arg);
/*%<
* Make the parser call 'callback' whenever it encounters
* a configuration clause with the callback attribute,
* passing it the clause name, the clause value,
* and 'arg' as arguments.
*
* To restore the default of not invoking callbacks, pass
* callback==NULL and arg==NULL.
*/
isc_result_t
cfg_parse_file(cfg_parser_t *pctx, const char *file, const cfg_type_t *type,
cfg_obj_t **ret);
isc_result_t
cfg_parse_buffer(cfg_parser_t *pctx, isc_buffer_t *buffer, const char *file,
cfg_parse_buffer(isc_mem_t *mctx, isc_buffer_t *buffer, const char *file,
unsigned int line, const cfg_type_t *type, unsigned int flags,
cfg_obj_t **ret);
/*%<
@ -152,8 +111,9 @@ cfg_parse_buffer(cfg_parser_t *pctx, isc_buffer_t *buffer, const char *file,
* Returns an error if the file or buffer does not parse correctly.
*
* Requires:
*\li "filename" is valid.
*\li "mem" is valid.
*\li "file" is valid.
*\li "buffer" is valid.
*\li "mctx" is valid.
*\li "type" is valid.
*\li "cfg" is non-NULL and "*cfg" is NULL.
*\li "flags" be one or more of CFG_PCTX_NODEPRECATED or zero.
@ -164,31 +124,11 @@ cfg_parse_buffer(cfg_parser_t *pctx, isc_buffer_t *buffer, const char *file,
*\li others - file contains errors
*/
isc_result_t
cfg_parser_mapadd(cfg_parser_t *pctx, cfg_obj_t *mapobj, cfg_obj_t *obj,
const char *clause);
cfg_obj_t *
cfg_parser_currentfile(cfg_parser_t *pctx);
/*%<
* Add the object 'obj' to the specified clause in mapbody 'mapobj'.
* Used for adding new zones.
*
* Require:
* \li 'obj' is a valid cfg_obj_t.
* \li 'mapobj' is a valid cfg_obj_t of type map.
* \li 'pctx' is a valid cfg_parser_t.
*/
void
cfg_parser_reset(cfg_parser_t *pctx);
/*%<
* Reset an existing parser so it can be re-used for a new file or
* buffer.
*/
void
cfg_parser_destroy(cfg_parser_t **pctxp);
/*%<
* Remove a reference to a configuration parser; destroy it if there are no
* more references.
* Returns the current file of a parser (as an cfg_obj_t qstring). NULL is non
* existent.
*/
bool
@ -232,6 +172,17 @@ cfg_map_get(const cfg_obj_t *mapobj, const char *name, const cfg_obj_t **obj);
* \li #ISC_R_NOTFOUND - name not found in map
*/
isc_result_t
cfg_map_add(cfg_obj_t *mapobj, cfg_obj_t *obj, const char *clause);
/*%<
* Add the object 'obj' to the specified clause in mapbody 'mapobj'.
* Used for adding new zones.
*
* Require:
* \li 'obj' is a valid cfg_obj_t.
* \li 'mapobj' is a valid cfg_obj_t of type map.
*/
const cfg_obj_t *
cfg_map_getname(const cfg_obj_t *mapobj);
/*%<
@ -490,6 +441,13 @@ cfg_list_length(const cfg_obj_t *obj, bool recurse);
* all contained lists.
*/
void
cfg_list_unlink(cfg_obj_t *list, cfg_listelt_t *elt);
/*%<
* Unlink 'elt' from the list object 'list', and free the memory associated
* with 'elt'.
*/
cfg_obj_t *
cfg_listelt_value(const cfg_listelt_t *elt);
/*%<
@ -543,23 +501,6 @@ cfg_obj_istype(const cfg_obj_t *obj, const cfg_type_t *type);
* Return true iff 'obj' is of type 'type'.
*/
void
cfg_obj_attach(cfg_obj_t *src, cfg_obj_t **dest);
/*%<
* Reference a configuration object.
*/
void
cfg_obj_destroy(cfg_parser_t *pctx, cfg_obj_t **obj);
/*%<
* Delete a reference to a configuration object; destroy the object if
* there are no more references.
*
* Require:
* \li '*obj' is a valid cfg_obj_t.
* \li 'pctx' is a valid cfg_parser_t.
*/
void
cfg_obj_log(const cfg_obj_t *obj, int level, const char *fmt, ...)
ISC_FORMAT_PRINTF(3, 4);
@ -626,3 +567,5 @@ cfg_pluginlist_foreach(const cfg_obj_t *config, const cfg_obj_t *list,
* 'list'
* \li first 'callback' return value which was not #ISC_R_SUCCESS otherwise
*/
ISC_REFCOUNT_DECL(cfg_obj);

View file

@ -47,11 +47,8 @@ enum {
/*% Clause is obsolete (logs a warning, but is not a fatal error) */
CFG_CLAUSEFLAG_OBSOLETE = 1 << 3,
/*%
* Clause needs to be interpreted during parsing by calling a
* callback function, like the "directory" option.
*/
CFG_CLAUSEFLAG_CALLBACK = 1 << 4,
/*% Clause indicates it must change the current directory */
CFG_CLAUSEFLAG_CHDIR = 1 << 4,
/*% Clause that is only used in testing. */
CFG_CLAUSEFLAG_TESTONLY = 1 << 5,
@ -102,7 +99,7 @@ typedef isc_result_t (*cfg_parsefunc_t)(cfg_parser_t *, const cfg_type_t *type,
cfg_obj_t **);
typedef void (*cfg_printfunc_t)(cfg_printer_t *, const cfg_obj_t *);
typedef void (*cfg_docfunc_t)(cfg_printer_t *, const cfg_type_t *);
typedef void (*cfg_freefunc_t)(cfg_parser_t *, cfg_obj_t *);
typedef void (*cfg_freefunc_t)(cfg_obj_t *);
/*
* Structure definitions
@ -180,6 +177,10 @@ struct cfg_rep {
*/
struct cfg_obj {
unsigned int magic;
isc_mem_t *mctx;
isc_refcount_t references;
const cfg_type_t *type;
union {
uint32_t uint32;
@ -197,10 +198,8 @@ struct cfg_obj {
cfg_netprefix_t netprefix;
isccfg_duration_t duration;
} value;
isc_refcount_t references; /*%< reference counter */
const char *file;
unsigned int line;
cfg_parser_t *pctx;
cfg_obj_t *file; /*%< separate string with its own refcount */
unsigned int line;
};
/*% A list element. */
@ -264,9 +263,6 @@ struct cfg_parser {
/*%< Reference counter */
isc_refcount_t references;
cfg_parsecallback_t callback;
void *callbackarg;
};
/* Parser context flags */
@ -353,8 +349,9 @@ cfg_ungettoken(cfg_parser_t *pctx);
#define CFG_LEXOPT_QSTRING (ISC_LEXOPT_QSTRING | ISC_LEXOPT_QSTRINGMULTILINE)
isc_result_t
cfg_create_obj(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **objp);
void
cfg_obj_create(isc_mem_t *mctx, cfg_obj_t *file, size_t line,
const cfg_type_t *type, cfg_obj_t **ret);
void
cfg_print_rawuint(cfg_printer_t *pctx, unsigned int u);
@ -422,8 +419,8 @@ isc_result_t
cfg_parse_special(cfg_parser_t *pctx, int special);
/*%< Parse a required special character 'special'. */
isc_result_t
cfg_create_tuple(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **objp);
void
cfg_tuple_create(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **objp);
isc_result_t
cfg_parse_tuple(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
@ -435,11 +432,8 @@ void
cfg_doc_tuple(cfg_printer_t *pctx, const cfg_type_t *type);
isc_result_t
cfg_create_list(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **objp);
isc_result_t
cfg_parse_listelt(cfg_parser_t *pctx, const cfg_type_t *elttype,
cfg_listelt_t **ret);
cfg_parse_listelt(cfg_parser_t *pctx, cfg_obj_t *list,
const cfg_type_t *elttype, cfg_listelt_t **ret);
isc_result_t
cfg_parse_bracketed_list(cfg_parser_t *pctx, const cfg_type_t *type,

View file

@ -42,10 +42,10 @@
} while (0)
/*% Clean up a configuration object if non-NULL. */
#define CLEANUP_OBJ(obj) \
do { \
if ((obj) != NULL) \
cfg_obj_destroy(pctx, &(obj)); \
#define CLEANUP_OBJ(obj) \
do { \
if ((obj) != NULL) \
cfg_obj_detach(&(obj)); \
} while (0)
/*%
@ -414,7 +414,8 @@ parse_updatepolicy(cfg_parser_t *pctx, const cfg_type_t *type,
strcasecmp(TOKEN_STRING(pctx), "local") == 0)
{
cfg_obj_t *obj = NULL;
CHECK(cfg_create_obj(pctx, &cfg_type_ustring, &obj));
cfg_obj_create(pctx->mctx, cfg_parser_currentfile(pctx),
pctx->line, &cfg_type_ustring, &obj);
obj->value.string.length = strlen("local");
obj->value.string.base =
isc_mem_get(pctx->mctx, obj->value.string.length + 1);
@ -972,7 +973,9 @@ parse_qstringornone(cfg_parser_t *pctx, const cfg_type_t *type,
if (pctx->token.type == isc_tokentype_string &&
strcasecmp(TOKEN_STRING(pctx), "none") == 0)
{
return cfg_create_obj(pctx, &cfg_type_none, ret);
cfg_obj_create(pctx->mctx, cfg_parser_currentfile(pctx),
pctx->line, &cfg_type_none, ret);
return ISC_R_SUCCESS;
}
cfg_ungettoken(pctx);
return cfg_parse_qstring(pctx, type, ret);
@ -1014,7 +1017,9 @@ parse_boolorauto(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
if (pctx->token.type == isc_tokentype_string &&
strcasecmp(TOKEN_STRING(pctx), "auto") == 0)
{
return cfg_create_obj(pctx, &cfg_type_auto, ret);
cfg_obj_create(pctx->mctx, cfg_parser_currentfile(pctx),
pctx->line, &cfg_type_auto, ret);
return ISC_R_SUCCESS;
}
cfg_ungettoken(pctx);
return cfg_parse_boolean(pctx, type, ret);
@ -1068,16 +1073,17 @@ parse_serverid(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
if (pctx->token.type == isc_tokentype_string &&
strcasecmp(TOKEN_STRING(pctx), "none") == 0)
{
return cfg_create_obj(pctx, &cfg_type_none, ret);
cfg_obj_create(pctx->mctx, cfg_parser_currentfile(pctx),
pctx->line, &cfg_type_none, ret);
return ISC_R_SUCCESS;
}
if (pctx->token.type == isc_tokentype_string &&
strcasecmp(TOKEN_STRING(pctx), "hostname") == 0)
{
result = cfg_create_obj(pctx, &cfg_type_hostname, ret);
if (result == ISC_R_SUCCESS) {
(*ret)->value.boolean = true;
}
return result;
cfg_obj_create(pctx->mctx, cfg_parser_currentfile(pctx),
pctx->line, &cfg_type_hostname, ret);
(*ret)->value.boolean = true;
return ISC_R_SUCCESS;
}
cfg_ungettoken(pctx);
return cfg_parse_qstring(pctx, type, ret);
@ -1226,7 +1232,7 @@ static cfg_clausedef_t options_clauses[] = {
{ "coresize", NULL, CFG_CLAUSEFLAG_ANCIENT },
{ "datasize", NULL, CFG_CLAUSEFLAG_ANCIENT },
{ "deallocate-on-exit", NULL, CFG_CLAUSEFLAG_ANCIENT },
{ "directory", &cfg_type_qstring, CFG_CLAUSEFLAG_CALLBACK },
{ "directory", &cfg_type_qstring, CFG_CLAUSEFLAG_CHDIR },
{ "dnsrps-library", &cfg_type_qstring, CFG_CLAUSEFLAG_OBSOLETE },
#ifdef HAVE_DNSTAP
{ "dnstap-output", &cfg_type_dnstapoutput, CFG_CLAUSEFLAG_OPTIONAL },
@ -1519,7 +1525,7 @@ parse_dtout(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
cfg_obj_t *obj = NULL;
const cfg_tuplefielddef_t *fields = type->of;
CHECK(cfg_create_tuple(pctx, type, &obj));
cfg_tuple_create(pctx, type, &obj);
/* Parse the mandatory "mode" and "path" fields */
CHECK(cfg_parse_obj(pctx, fields[0].type, &obj->value.tuple[0]));
@ -1671,7 +1677,7 @@ cfg_parse_rpz_policy(cfg_parser_t *pctx, const cfg_type_t *type,
cfg_obj_t *obj = NULL;
const cfg_tuplefielddef_t *fields;
CHECK(cfg_create_tuple(pctx, type, &obj));
cfg_tuple_create(pctx, type, &obj);
fields = type->of;
CHECK(cfg_parse_obj(pctx, fields[0].type, &obj->value.tuple[0]));
@ -1705,7 +1711,7 @@ cfg_parse_kv_tuple(cfg_parser_t *pctx, const cfg_type_t *type,
int fn;
isc_result_t result;
CHECK(cfg_create_tuple(pctx, type, &obj));
cfg_tuple_create(pctx, type, &obj);
/*
* The zone first field is required and always first.
@ -2814,7 +2820,8 @@ parse_sizeval(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
}
CHECK(parse_unitstring(TOKEN_STRING(pctx), &val));
CHECK(cfg_create_obj(pctx, &cfg_type_uint64, &obj));
cfg_obj_create(pctx->mctx, cfg_parser_currentfile(pctx), pctx->line,
&cfg_type_uint64, &obj);
obj->value.uint64 = val;
*ret = obj;
return ISC_R_SUCCESS;
@ -2845,13 +2852,15 @@ parse_sizeval_percent(cfg_parser_t *pctx, const cfg_type_t *type,
percent = strtoull(TOKEN_STRING(pctx), &endp, 10);
if (*endp == '%' && *(endp + 1) == 0) {
CHECK(cfg_create_obj(pctx, &cfg_type_percentage, &obj));
cfg_obj_create(pctx->mctx, cfg_parser_currentfile(pctx),
pctx->line, &cfg_type_percentage, &obj);
obj->value.uint32 = (uint32_t)percent;
*ret = obj;
return ISC_R_SUCCESS;
} else {
CHECK(parse_unitstring(TOKEN_STRING(pctx), &val));
CHECK(cfg_create_obj(pctx, &cfg_type_uint64, &obj));
cfg_obj_create(pctx->mctx, cfg_parser_currentfile(pctx),
pctx->line, &cfg_type_uint64, &obj);
obj->value.uint64 = val;
*ret = obj;
return ISC_R_SUCCESS;
@ -3278,7 +3287,8 @@ parse_querysource(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
strcasecmp(TOKEN_STRING(pctx), "none") == 0)
{
CHECK(cfg_gettoken(pctx, 0));
CHECK(cfg_create_obj(pctx, &cfg_type_none, ret));
cfg_obj_create(pctx->mctx, cfg_parser_currentfile(pctx),
pctx->line, &cfg_type_none, ret);
} else {
CHECK(cfg_parse_sockaddr_generic(pctx, &cfg_type_querysource,
type, ret));
@ -3479,7 +3489,8 @@ parse_logseverity(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
* This makes little sense, but we support it for
* compatibility with BIND 8.
*/
CHECK(cfg_create_obj(pctx, &cfg_type_uint32, ret));
cfg_obj_create(pctx->mctx, cfg_parser_currentfile(pctx),
pctx->line, &cfg_type_uint32, ret);
(*ret)->value.uint32 = 1;
}
(*ret)->type = &cfg_type_debuglevel; /* XXX kludge */
@ -3534,7 +3545,7 @@ parse_logfile(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
cfg_obj_t *obj = NULL;
const cfg_tuplefielddef_t *fields = type->of;
CHECK(cfg_create_tuple(pctx, type, &obj));
cfg_tuple_create(pctx, type, &obj);
/* Parse the mandatory "file" field */
CHECK(cfg_parse_obj(pctx, fields[0].type, &obj->value.tuple[0]));

File diff suppressed because it is too large Load diff

View file

@ -120,7 +120,6 @@ ISC_RUN_TEST_IMPL(duration) {
"T99999999999H99999999999M99999999999S" },
};
isc_buffer_t buf1;
cfg_parser_t *p1 = NULL;
cfg_obj_t *c1 = NULL;
bool must_fail = false;
@ -144,14 +143,10 @@ ISC_RUN_TEST_IMPL(duration) {
isc_buffer_add(&buf1, strlen(conf) - 1);
/* Parse with default line numbering */
result = cfg_parser_create(isc_g_mctx, &p1);
assert_int_equal(result, ISC_R_SUCCESS);
result = cfg_parse_buffer(p1, &buf1, "text1", 0,
result = cfg_parse_buffer(isc_g_mctx, &buf1, "text1", 0,
&cfg_type_namedconf, 0, &c1);
if (must_fail) {
assert_int_equal(result, DNS_R_BADTTL);
cfg_parser_destroy(&p1);
continue;
}
assert_int_equal(result, ISC_R_SUCCESS);
@ -192,8 +187,7 @@ ISC_RUN_TEST_IMPL(duration) {
assert_int_equal(cmp, 0);
}
cfg_obj_destroy(p1, &c1);
cfg_parser_destroy(&p1);
cfg_obj_detach(&c1);
}
}

View file

@ -124,16 +124,12 @@ static void
test__query_source_print(const char *config, const char *expected) {
isc_result_t result;
isc_buffer_t buffer;
cfg_parser_t *parser = NULL;
cfg_obj_t *output_conf = NULL;
result = cfg_parser_create(mctx, &parser);
assert_int_equal(result, ISC_R_SUCCESS);
isc_buffer_constinit(&buffer, config, strlen(config));
isc_buffer_add(&buffer, strlen(config));
result = cfg_parse_buffer(parser, &buffer, "text1", 0,
result = cfg_parse_buffer(isc_g_mctx, &buffer, "text1", 0,
&cfg_type_namedconf, 0, &output_conf);
assert_int_equal(result, ISC_R_SUCCESS);
assert_non_null(output_conf);
@ -144,9 +140,7 @@ test__query_source_print(const char *config, const char *expected) {
output_conf->type->print(&pctx, output_conf);
assert_text(expected);
cfg_obj_destroy(parser, &output_conf);
cfg_parser_reset(parser);
cfg_parser_destroy(&parser);
cfg_obj_detach(&output_conf);
}
ISC_RUN_TEST_IMPL(query_source_print_none) {

View file

@ -11,6 +11,7 @@
foreach unit : [
'duration',
'grammar',
'parser',
]
test_bin = executable(

View file

@ -60,7 +60,6 @@ append(void *arg, const char *str, int len) {
ISC_RUN_TEST_IMPL(addzoneconf) {
isc_result_t result;
isc_buffer_t b;
cfg_parser_t *p = NULL;
const char *tests[] = {
"zone \"test4.baz\" { type primary; file \"e.db\"; };",
"zone \"test/.baz\" { type primary; file \"e.db\"; };",
@ -73,9 +72,6 @@ ISC_RUN_TEST_IMPL(addzoneconf) {
char buf[1024];
/* Parse with default line numbering */
result = cfg_parser_create(isc_g_mctx, &p);
assert_int_equal(result, ISC_R_SUCCESS);
for (size_t i = 0; i < ARRAY_SIZE(tests); i++) {
cfg_obj_t *conf = NULL;
const cfg_obj_t *obj = NULL, *zlist = NULL;
@ -83,7 +79,7 @@ ISC_RUN_TEST_IMPL(addzoneconf) {
isc_buffer_constinit(&b, tests[i], strlen(tests[i]));
isc_buffer_add(&b, strlen(tests[i]));
result = cfg_parse_buffer(p, &b, "text1", 0,
result = cfg_parse_buffer(isc_g_mctx, &b, "text1", 0,
&cfg_type_namedconf, 0, &conf);
assert_int_equal(result, ISC_R_SUCCESS);
@ -102,50 +98,78 @@ ISC_RUN_TEST_IMPL(addzoneconf) {
strlcat(buf, ";", sizeof(buf));
assert_string_equal(tests[i], buf);
cfg_obj_destroy(p, &conf);
cfg_parser_reset(p);
cfg_obj_detach(&conf);
}
cfg_parser_destroy(&p);
}
/* test cfg_parse_buffer() */
ISC_RUN_TEST_IMPL(parse_buffer) {
isc_result_t result;
unsigned char text[] = "options\n{\nrecursion yes;\n};\n";
isc_buffer_t buf1, buf2;
cfg_parser_t *p1 = NULL, *p2 = NULL;
cfg_obj_t *c1 = NULL, *c2 = NULL;
int fresult;
unsigned char text[] = "options\n{\nidonotexists yes;\n};\n";
char logfilebuf[512];
size_t logfilelen;
isc_buffer_t buf;
cfg_obj_t *c = NULL;
isc_buffer_init(&buf1, &text[0], sizeof(text) - 1);
isc_buffer_add(&buf1, sizeof(text) - 1);
/*
* Redirect parser errors into a specific file for checking the output
* later.
*/
constexpr char logfilename[] = "./cfglog.out";
FILE *logfile = fopen(logfilename, "w+");
assert_non_null(logfile);
/* Parse with default line numbering */
result = cfg_parser_create(isc_g_mctx, &p1);
assert_int_equal(result, ISC_R_SUCCESS);
isc_logdestination_t *logdest = ISC_LOGDESTINATION_FILE(logfile);
isc_logconfig_t *logconfig = isc_logconfig_get();
isc_log_createandusechannel(logconfig, "default_stderr",
ISC_LOG_TOFILEDESC, ISC_LOG_DYNAMIC,
logdest, 0, ISC_LOGCATEGORY_DEFAULT,
ISC_LOGMODULE_DEFAULT);
result = cfg_parse_buffer(p1, &buf1, "text1", 0, &cfg_type_namedconf, 0,
&c1);
assert_int_equal(result, ISC_R_SUCCESS);
assert_int_equal(p1->line, 5);
/* Parse with default line numbering. */
isc_buffer_init(&buf, &text[0], sizeof(text) - 1);
isc_buffer_add(&buf, sizeof(text) - 1);
result = cfg_parse_buffer(isc_g_mctx, &buf, "text1", 0,
&cfg_type_namedconf, 0, &c);
assert_int_equal(result, ISC_R_FAILURE);
assert_null(c);
isc_buffer_init(&buf2, &text[0], sizeof(text) - 1);
isc_buffer_add(&buf2, sizeof(text) - 1);
/* Parse with changed line number. */
isc_buffer_first(&buf);
result = cfg_parse_buffer(isc_g_mctx, &buf, "text2", 100,
&cfg_type_namedconf, 0, &c);
assert_int_equal(result, ISC_R_FAILURE);
assert_null(c);
/* Parse with changed line number */
result = cfg_parser_create(isc_g_mctx, &p2);
assert_int_equal(result, ISC_R_SUCCESS);
/* Parse with changed line number and no name. */
isc_buffer_first(&buf);
result = cfg_parse_buffer(isc_g_mctx, &buf, NULL, 100,
&cfg_type_namedconf, 0, &c);
assert_int_equal(result, ISC_R_FAILURE);
assert_null(c);
result = cfg_parse_buffer(p2, &buf2, "text2", 100, &cfg_type_namedconf,
0, &c2);
assert_int_equal(result, ISC_R_SUCCESS);
assert_int_equal(p2->line, 104);
/* Check log values (and, specifically, line numbers). */
logfilelen = ftell(logfile);
assert_in_range(logfilelen, 0, sizeof(logfilebuf));
cfg_obj_destroy(p1, &c1);
cfg_obj_destroy(p2, &c2);
fresult = fseek(logfile, 0, SEEK_SET);
assert_int_equal(fresult, 0);
cfg_parser_destroy(&p1);
cfg_parser_destroy(&p2);
fresult = fread(logfilebuf, 1, logfilelen, logfile);
assert_int_equal(fresult, logfilelen);
logfilebuf[logfilelen] = 0;
assert_non_null(
strstr(logfilebuf, "text1:3: unknown option 'idonotexists'"));
assert_non_null(
strstr(logfilebuf, "text2:102: unknown option 'idonotexists'"));
assert_non_null(
strstr(logfilebuf, "none:102: unknown option 'idonotexists'"));
fclose(logfile);
remove(logfilename);
}
/* test cfg_map_firstclause() */