diff --git a/bin/check/named-checkconf.c b/bin/check/named-checkconf.c index a4da14d8e3..169fd66ef7 100644 --- a/bin/check/named-checkconf.c +++ b/bin/check/named-checkconf.c @@ -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; diff --git a/bin/delv/delv.c b/bin/delv/delv.c index cfcc67fe5c..b05e05f2d2 100644 --- a/bin/delv/delv.c +++ b/bin/delv/delv.c @@ -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", diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c index c7d8016362..5928c265bd 100644 --- a/bin/dig/dighost.c +++ b/bin/dig/dighost.c @@ -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; diff --git a/bin/dnssec/dnssec-keygen.c b/bin/dnssec/dnssec-keygen.c index c7b4abe98a..6c6e82f097 100644 --- a/bin/dnssec/dnssec-keygen.c +++ b/bin/dnssec/dnssec-keygen.c @@ -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); diff --git a/bin/dnssec/dnssec-ksr.c b/bin/dnssec/dnssec-ksr.c index 86eb1362fc..a4ef81b82e 100644 --- a/bin/dnssec/dnssec-ksr.c +++ b/bin/dnssec/dnssec-ksr.c @@ -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 diff --git a/bin/named/config.c b/bin/named/config.c index ce0c17ac41..00006a8522 100644 --- a/bin/named/config.c +++ b/bin/named/config.c @@ -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: diff --git a/bin/named/controlconf.c b/bin/named/controlconf.c index 84003f86d6..0376d2b770 100644 --- a/bin/named/controlconf.c +++ b/bin/named/controlconf.c @@ -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; } diff --git a/bin/named/include/named/config.h b/bin/named/include/named/config.h index 744f583423..3de19d73f8 100644 --- a/bin/named/include/named/config.h +++ b/bin/named/include/named/config.h @@ -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); diff --git a/bin/named/include/named/globals.h b/bin/named/include/named/globals.h index fa5fd5581c..e5ed76d6e6 100644 --- a/bin/named/include/named/globals.h +++ b/bin/named/include/named/globals.h @@ -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); diff --git a/bin/named/main.c b/bin/named/main.c index ef466ba7a8..5f171385c8 100644 --- a/bin/named/main.c +++ b/bin/named/main.c @@ -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 */ } diff --git a/bin/named/server.c b/bin/named/server.c index 82072750be..5d7f74cb19 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -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) { diff --git a/bin/named/zoneconf.c b/bin/named/zoneconf.c index ae3d95bda1..ae82d76feb 100644 --- a/bin/named/zoneconf.c +++ b/bin/named/zoneconf.c @@ -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: diff --git a/bin/nsupdate/nsupdate.c b/bin/nsupdate/nsupdate.c index 8f8b47af15..4ceff56466 100644 --- a/bin/nsupdate/nsupdate.c +++ b/bin/nsupdate/nsupdate.c @@ -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) { diff --git a/bin/plugins/filter-a.c b/bin/plugins/filter-a.c index e9c314b008..2d98b70692 100644 --- a/bin/plugins/filter-a.c +++ b/bin/plugins/filter-a.c @@ -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, ¶m_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, ¶m_obj); - } - if (parser != NULL) { - cfg_parser_destroy(&parser); + cfg_obj_detach(¶m_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, ¶m_obj)); CHECK(check_syntax(param_obj, cfg, mctx, aclctx)); cleanup: if (param_obj != NULL) { - cfg_obj_destroy(parser, ¶m_obj); - } - if (parser != NULL) { - cfg_parser_destroy(&parser); + cfg_obj_detach(¶m_obj); } return result; } diff --git a/bin/plugins/filter-aaaa.c b/bin/plugins/filter-aaaa.c index 84dd0acd62..dad917464c 100644 --- a/bin/plugins/filter-aaaa.c +++ b/bin/plugins/filter-aaaa.c @@ -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, ¶m_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, ¶m_obj); - } - if (parser != NULL) { - cfg_parser_destroy(&parser); + cfg_obj_detach(¶m_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, ¶m_obj)); CHECK(check_syntax(param_obj, cfg, mctx, aclctx)); cleanup: if (param_obj != NULL) { - cfg_obj_destroy(parser, ¶m_obj); - } - if (parser != NULL) { - cfg_parser_destroy(&parser); + cfg_obj_detach(¶m_obj); } return result; } diff --git a/bin/plugins/synthrecord.c b/bin/plugins/synthrecord.c index b5582bad49..1fab2a3a37 100644 --- a/bin/plugins/synthrecord.c +++ b/bin/plugins/synthrecord.c @@ -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; diff --git a/bin/rndc/rndc.c b/bin/rndc/rndc.c index d191fd97d1..46d0aa0c97 100644 --- a/bin/rndc/rndc.c +++ b/bin/rndc/rndc.c @@ -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); diff --git a/bin/tests/system/addzone/ns1/named.conf.in b/bin/tests/system/addzone/ns1/named.conf.j2 similarity index 88% rename from bin/tests/system/addzone/ns1/named.conf.in rename to bin/tests/system/addzone/ns1/named.conf.j2 index 30731c46a6..c3302760ae 100644 --- a/bin/tests/system/addzone/ns1/named.conf.in +++ b/bin/tests/system/addzone/ns1/named.conf.j2 @@ -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; }; diff --git a/bin/tests/system/addzone/setup.sh b/bin/tests/system/addzone/setup.sh index b2227c16b2..b6e778f629 100644 --- a/bin/tests/system/addzone/setup.sh +++ b/bin/tests/system/addzone/setup.sh @@ -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 diff --git a/bin/tests/system/addzone/tests.sh b/bin/tests/system/addzone/tests.sh index 66c76bca18..ed897b9ba7 100755 --- a/bin/tests/system/addzone/tests.sh +++ b/bin/tests/system/addzone/tests.sh @@ -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)) diff --git a/bin/tests/system/addzone/tests_showzone_static.py b/bin/tests/system/addzone/tests_showzone_static.py new file mode 100644 index 0000000000..6edaa497f6 --- /dev/null +++ b/bin/tests/system/addzone/tests_showzone_static.py @@ -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' + ) diff --git a/bin/tests/system/checkconf/tests.sh b/bin/tests/system/checkconf/tests.sh index efb781188b..aec7b13639 100644 --- a/bin/tests/system/checkconf/tests.sh +++ b/bin/tests/system/checkconf/tests.sh @@ -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" \ diff --git a/bin/tests/system/hooks/driver/test-syncplugin.c b/bin/tests/system/hooks/driver/test-syncplugin.c index 556a91d065..620829c8cc 100644 --- a/bin/tests/system/hooks/driver/test-syncplugin.c +++ b/bin/tests/system/hooks/driver/test-syncplugin.c @@ -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; diff --git a/doc/misc/cfg_test.c b/doc/misc/cfg_test.c index d039bf07cf..f29600c2aa 100644 --- a/doc/misc/cfg_test.c +++ b/doc/misc/cfg_test.c @@ -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) { diff --git a/lib/dns/include/dns/zone.h b/lib/dns/include/dns/zone.h index 24cd59fd16..7a7a8325cf 100644 --- a/lib/dns/include/dns/zone.h +++ b/lib/dns/include/dns/zone.h @@ -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__) diff --git a/lib/dns/zone.c b/lib/dns/zone.c index b14b7fffb4..d4275f24d3 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -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; +} diff --git a/lib/isccfg/include/isccfg/cfg.h b/lib/isccfg/include/isccfg/cfg.h index 34ca10b793..90c94c1b73 100644 --- a/lib/isccfg/include/isccfg/cfg.h +++ b/lib/isccfg/include/isccfg/cfg.h @@ -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); diff --git a/lib/isccfg/include/isccfg/grammar.h b/lib/isccfg/include/isccfg/grammar.h index 6c3c1cb39b..b91c090130 100644 --- a/lib/isccfg/include/isccfg/grammar.h +++ b/lib/isccfg/include/isccfg/grammar.h @@ -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, diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index 4b022cefe2..5d0117ac5a 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -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])); diff --git a/lib/isccfg/parser.c b/lib/isccfg/parser.c index 07bc4879fa..f5e2dbffd9 100644 --- a/lib/isccfg/parser.c +++ b/lib/isccfg/parser.c @@ -50,6 +50,7 @@ #include #include #include +#include #include #include #include @@ -88,18 +89,21 @@ } 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) +/* cfg_obj_t magic number */ +#define CFGOBJ_MAGIC ISC_MAGIC('c', 'f', 'g', 'o') + /* * Forward declarations of static functions. */ static void -free_tuple(cfg_parser_t *pctx, cfg_obj_t *obj); +free_tuple(cfg_obj_t *obj); static isc_result_t parse_list(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret); @@ -108,33 +112,35 @@ static void print_list(cfg_printer_t *pctx, const cfg_obj_t *obj); static void -free_list(cfg_parser_t *pctx, cfg_obj_t *obj); +free_list(cfg_obj_t *obj); -static isc_result_t -create_listelt(cfg_parser_t *pctx, cfg_listelt_t **eltp); +static void +create_list(isc_mem_t *mctx, cfg_obj_t *file, size_t line, + const cfg_type_t *type, cfg_obj_t **obj); +static void +create_listelt(cfg_obj_t *list, cfg_listelt_t **eltp); -static isc_result_t +static void create_string(cfg_parser_t *pctx, const char *contents, const cfg_type_t *type, cfg_obj_t **ret); +static void +free_string(cfg_obj_t *obj); static void -free_string(cfg_parser_t *pctx, cfg_obj_t *obj); +free_sockaddrtls(cfg_obj_t *obj); static void -free_sockaddrtls(cfg_parser_t *pctx, cfg_obj_t *obj); - -static isc_result_t create_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **objp); static void -free_map(cfg_parser_t *pctx, cfg_obj_t *obj); +free_map(cfg_obj_t *obj); static isc_result_t -parse_symtab_elt(cfg_parser_t *pctx, const char *name, cfg_type_t *elttype, - isc_symtab_t *symtab, bool callback); +parse_symtab_elt(cfg_parser_t *pctx, const cfg_clausedef_t *clause, + isc_symtab_t *symtab); static void -free_noop(cfg_parser_t *pctx, cfg_obj_t *obj); +free_noop(cfg_obj_t *obj); static isc_result_t cfg_getstringtoken(cfg_parser_t *pctx); @@ -236,6 +242,25 @@ print_close(cfg_printer_t *pctx) { cfg_print_cstr(pctx, "}"); } +cfg_obj_t * +cfg_parser_currentfile(cfg_parser_t *pctx) { + cfg_listelt_t *elt = NULL; + cfg_obj_t *fileobj = NULL; + + if (pctx->open_files == NULL) { + return NULL; + } + + elt = ISC_LIST_TAIL(pctx->open_files->value.list); + if (elt == NULL) { + return NULL; + } + + fileobj = elt->obj; + INSIST(fileobj->type == &cfg_type_qstring); + return fileobj; +} + isc_result_t cfg_parse_obj(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; @@ -280,9 +305,8 @@ cfg_printx(const cfg_obj_t *obj, unsigned int flags, /* Tuples. */ -isc_result_t -cfg_create_tuple(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { - isc_result_t result; +void +cfg_tuple_create(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { const cfg_tuplefielddef_t *fields; const cfg_tuplefielddef_t *f; cfg_obj_t *obj = NULL; @@ -299,20 +323,14 @@ cfg_create_tuple(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { nfields++; } - CHECK(cfg_create_obj(pctx, type, &obj)); + cfg_obj_create(pctx->mctx, cfg_parser_currentfile(pctx), pctx->line, + type, &obj); obj->value.tuple = isc_mem_cget(pctx->mctx, nfields, sizeof(cfg_obj_t *)); for (f = fields, i = 0; f->name != NULL; f++, i++) { obj->value.tuple[i] = NULL; } *ret = obj; - return ISC_R_SUCCESS; - -cleanup: - if (obj != NULL) { - isc_mem_put(pctx->mctx, obj, sizeof(*obj)); - } - return result; } isc_result_t @@ -329,7 +347,7 @@ cfg_parse_tuple(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { fields = type->of; - CHECK(cfg_create_tuple(pctx, type, &obj)); + cfg_tuple_create(pctx, type, &obj); for (f = fields, i = 0; f->name != NULL; f++, i++) { CHECK(cfg_parse_obj(pctx, f->type, &obj->value.tuple[i])); } @@ -386,7 +404,7 @@ cfg_doc_tuple(cfg_printer_t *pctx, const cfg_type_t *type) { } static void -free_tuple(cfg_parser_t *pctx, cfg_obj_t *obj) { +free_tuple(cfg_obj_t *obj) { unsigned int i; const cfg_tuplefielddef_t *fields = obj->type->of; const cfg_tuplefielddef_t *f; @@ -400,8 +418,7 @@ free_tuple(cfg_parser_t *pctx, cfg_obj_t *obj) { CLEANUP_OBJ(obj->value.tuple[i]); nfields++; } - isc_mem_cput(pctx->mctx, obj->value.tuple, nfields, - sizeof(cfg_obj_t *)); + isc_mem_cput(obj->mctx, obj->value.tuple, nfields, sizeof(cfg_obj_t *)); } bool @@ -496,9 +513,8 @@ static cfg_type_t cfg_type_filelist = { "filelist", NULL, print_list, NULL, &cfg_rep_list, &cfg_type_qstring }; -isc_result_t -cfg_parser_create(isc_mem_t *mctx, cfg_parser_t **ret) { - isc_result_t result; +static void +parser_create(isc_mem_t *mctx, cfg_parser_t **ret) { cfg_parser_t *pctx; isc_lexspecials_t specials; @@ -520,8 +536,6 @@ cfg_parser_create(isc_mem_t *mctx, cfg_parser_t **ret) { pctx->open_files = NULL; pctx->closed_files = NULL; pctx->line = 0; - pctx->callback = NULL; - pctx->callbackarg = NULL; pctx->token.type = isc_tokentype_unknown; pctx->flags = 0; pctx->buf_name = NULL; @@ -541,30 +555,32 @@ cfg_parser_create(isc_mem_t *mctx, cfg_parser_t **ret) { ISC_LEXCOMMENT_CPLUSPLUS | ISC_LEXCOMMENT_SHELL); - CHECK(cfg_create_list(pctx, &cfg_type_filelist, &pctx->open_files)); - CHECK(cfg_create_list(pctx, &cfg_type_filelist, &pctx->closed_files)); + create_list(pctx->mctx, cfg_parser_currentfile(pctx), pctx->line, + &cfg_type_filelist, &pctx->open_files); + create_list(pctx->mctx, cfg_parser_currentfile(pctx), pctx->line, + &cfg_type_filelist, &pctx->closed_files); *ret = pctx; - return ISC_R_SUCCESS; - -cleanup: - if (pctx->lexer != NULL) { - isc_lex_destroy(&pctx->lexer); - } - CLEANUP_OBJ(pctx->open_files); - CLEANUP_OBJ(pctx->closed_files); - isc_mem_putanddetach(&pctx->mctx, pctx, sizeof(*pctx)); - return result; } -void -cfg_parser_setflags(cfg_parser_t *pctx, unsigned int flags, bool turn_on) { - REQUIRE(pctx != NULL); +static void +parser_destroy(cfg_parser_t **pctxp) { + cfg_parser_t *pctx; - if (turn_on) { - pctx->flags |= flags; - } else { - pctx->flags &= ~flags; + REQUIRE(pctxp != NULL && *pctxp != NULL); + pctx = *pctxp; + *pctxp = NULL; + + if (isc_refcount_decrement(&pctx->references) == 1) { + isc_lex_destroy(&pctx->lexer); + /* + * Cleaning up open_files does not + * close the files; that was already done + * by closing the lexer. + */ + CLEANUP_OBJ(pctx->open_files); + CLEANUP_OBJ(pctx->closed_files); + isc_mem_putanddetach(&pctx->mctx, pctx, sizeof(*pctx)); } } @@ -581,8 +597,8 @@ parser_openfile(cfg_parser_t *pctx, const char *filename) { goto cleanup; } - CHECK(create_string(pctx, filename, &cfg_type_qstring, &stringobj)); - CHECK(create_listelt(pctx, &elt)); + create_string(pctx, filename, &cfg_type_qstring, &stringobj); + create_listelt(pctx->open_files, &elt); elt->obj = stringobj; ISC_LIST_APPEND(pctx->open_files->value.list, elt, link); @@ -592,30 +608,6 @@ cleanup: return result; } -void -cfg_parser_setcallback(cfg_parser_t *pctx, cfg_parsecallback_t callback, - void *arg) { - REQUIRE(pctx != NULL); - - pctx->callback = callback; - pctx->callbackarg = arg; -} - -void -cfg_parser_reset(cfg_parser_t *pctx) { - REQUIRE(pctx != NULL); - - if (pctx->lexer != NULL) { - isc_lex_close(pctx->lexer); - } - - pctx->seen_eof = false; - pctx->ungotten = false; - pctx->errors = 0; - pctx->warnings = 0; - pctx->line = 0; -} - /* * Parse a configuration using a pctx where a lexer has already * been set up with a source. @@ -652,16 +644,25 @@ cleanup: return result; } +#define REQUIRE_PCTX_FLAGS(flags) \ + REQUIRE((flags & ~(CFG_PCTX_NODEPRECATED | CFG_PCTX_NOOBSOLETE | \ + CFG_PCTX_NOEXPERIMENTAL)) == 0) + isc_result_t -cfg_parse_file(cfg_parser_t *pctx, const char *filename, const cfg_type_t *type, - cfg_obj_t **ret) { +cfg_parse_file(isc_mem_t *mctx, const char *filename, const cfg_type_t *type, + unsigned int flags, cfg_obj_t **ret) { isc_result_t result; cfg_listelt_t *elt; + cfg_parser_t *pctx = NULL; - REQUIRE(pctx != NULL); + REQUIRE(mctx != NULL); REQUIRE(filename != NULL); REQUIRE(type != NULL); REQUIRE(ret != NULL && *ret == NULL); + REQUIRE_PCTX_FLAGS(flags); + + parser_create(mctx, &pctx); + pctx->flags = flags; CHECK(parser_openfile(pctx, filename)); @@ -674,22 +675,27 @@ cfg_parse_file(cfg_parser_t *pctx, const char *filename, const cfg_type_t *type, ISC_LIST_APPEND(pctx->closed_files->value.list, elt, link); cleanup: + if (pctx != NULL) { + parser_destroy(&pctx); + } + return result; } 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) { isc_result_t result; + cfg_parser_t *pctx = NULL; - REQUIRE(pctx != NULL); + REQUIRE(mctx != NULL); REQUIRE(type != NULL); REQUIRE(buffer != NULL); REQUIRE(ret != NULL && *ret == NULL); - REQUIRE((flags & ~(CFG_PCTX_NODEPRECATED | CFG_PCTX_NOOBSOLETE | - CFG_PCTX_NOEXPERIMENTAL)) == 0); + REQUIRE_PCTX_FLAGS(flags); + parser_create(mctx, &pctx); CHECK(isc_lex_openbuffer(pctx->lexer, buffer)); pctx->buf_name = file; @@ -703,37 +709,11 @@ cfg_parse_buffer(cfg_parser_t *pctx, isc_buffer_t *buffer, const char *file, pctx->buf_name = NULL; cleanup: - return result; -} - -void -cfg_parser_attach(cfg_parser_t *src, cfg_parser_t **dest) { - REQUIRE(src != NULL); - REQUIRE(dest != NULL && *dest == NULL); - - isc_refcount_increment(&src->references); - *dest = src; -} - -void -cfg_parser_destroy(cfg_parser_t **pctxp) { - cfg_parser_t *pctx; - - REQUIRE(pctxp != NULL && *pctxp != NULL); - pctx = *pctxp; - *pctxp = NULL; - - if (isc_refcount_decrement(&pctx->references) == 1) { - isc_lex_destroy(&pctx->lexer); - /* - * Cleaning up open_files does not - * close the files; that was already done - * by closing the lexer. - */ - CLEANUP_OBJ(pctx->open_files); - CLEANUP_OBJ(pctx->closed_files); - isc_mem_putanddetach(&pctx->mctx, pctx, sizeof(*pctx)); + if (pctx != NULL) { + parser_destroy(&pctx); } + + return result; } /* @@ -746,7 +726,9 @@ cfg_parse_void(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { UNUSED(type); - return cfg_create_obj(pctx, &cfg_type_void, ret); + cfg_obj_create(pctx->mctx, cfg_parser_currentfile(pctx), pctx->line, + &cfg_type_void, ret); + return ISC_R_SUCCESS; } void @@ -804,7 +786,8 @@ cfg_parse_percentage(cfg_parser_t *pctx, const cfg_type_t *type, return ISC_R_UNEXPECTEDTOKEN; } - 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; @@ -877,7 +860,8 @@ cfg_parse_fixedpoint(cfg_parser_t *pctx, const cfg_type_t *type, return ISC_R_UNEXPECTEDTOKEN; } - CHECK(cfg_create_obj(pctx, &cfg_type_fixedpoint, &obj)); + cfg_obj_create(pctx->mctx, cfg_parser_currentfile(pctx), pctx->line, + &cfg_type_fixedpoint, &obj); obj->value.uint32 = strtoul(p, NULL, 10) * 100; switch (n3) { @@ -943,7 +927,8 @@ cfg_parse_uint32(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { return ISC_R_UNEXPECTEDTOKEN; } - CHECK(cfg_create_obj(pctx, &cfg_type_uint32, &obj)); + cfg_obj_create(pctx->mctx, cfg_parser_currentfile(pctx), pctx->line, + &cfg_type_uint32, &obj); obj->value.uint32 = pctx->token.value.as_ulong; *ret = obj; @@ -1164,7 +1149,8 @@ parse_duration(cfg_parser_t *pctx, cfg_obj_t **ret) { goto cleanup; } - CHECK(cfg_create_obj(pctx, &cfg_type_duration, &obj)); + cfg_obj_create(pctx->mctx, cfg_parser_currentfile(pctx), pctx->line, + &cfg_type_duration, &obj); obj->value.duration = duration; *ret = obj; @@ -1219,7 +1205,8 @@ cfg_parse_duration_or_unlimited(cfg_parser_t *pctx, const cfg_type_t *type, duration.iso8601 = false; duration.unlimited = true; - CHECK(cfg_create_obj(pctx, &cfg_type_duration, &obj)); + cfg_obj_create(pctx->mctx, cfg_parser_currentfile(pctx), + pctx->line, &cfg_type_duration, &obj); obj->value.duration = duration; *ret = obj; return ISC_R_SUCCESS; @@ -1264,27 +1251,21 @@ cfg_type_t cfg_type_duration_or_unlimited = { "duration_or_unlimited", */ /* Create a string object from a null-terminated C string. */ -static isc_result_t +static void create_string(cfg_parser_t *pctx, const char *contents, const cfg_type_t *type, cfg_obj_t **ret) { - isc_result_t result; cfg_obj_t *obj = NULL; int len; - CHECK(cfg_create_obj(pctx, type, &obj)); + cfg_obj_create(pctx->mctx, cfg_parser_currentfile(pctx), pctx->line, + type, &obj); len = strlen(contents); obj->value.string.length = len; obj->value.string.base = isc_mem_get(pctx->mctx, len + 1); - if (obj->value.string.base == 0) { - isc_mem_put(pctx->mctx, obj, sizeof(*obj)); - return ISC_R_NOMEMORY; - } memmove(obj->value.string.base, contents, len); obj->value.string.base[len] = '\0'; *ret = obj; -cleanup: - return result; } isc_result_t @@ -1301,7 +1282,9 @@ cfg_parse_qstring(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { cfg_parser_error(pctx, CFG_LOG_NEAR, "expected quoted string"); return ISC_R_UNEXPECTEDTOKEN; } - return create_string(pctx, TOKEN_STRING(pctx), &cfg_type_qstring, ret); + create_string(pctx, TOKEN_STRING(pctx), &cfg_type_qstring, ret); + return ISC_R_SUCCESS; + cleanup: return result; } @@ -1318,7 +1301,9 @@ parse_ustring(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { "expected unquoted string"); return ISC_R_UNEXPECTEDTOKEN; } - return create_string(pctx, TOKEN_STRING(pctx), &cfg_type_ustring, ret); + create_string(pctx, TOKEN_STRING(pctx), &cfg_type_ustring, ret); + return ISC_R_SUCCESS; + cleanup: return result; } @@ -1333,7 +1318,9 @@ cfg_parse_astring(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { UNUSED(type); CHECK(cfg_getstringtoken(pctx)); - return create_string(pctx, TOKEN_STRING(pctx), &cfg_type_qstring, ret); + create_string(pctx, TOKEN_STRING(pctx), &cfg_type_qstring, ret); + return ISC_R_SUCCESS; + cleanup: return result; } @@ -1348,7 +1335,9 @@ cfg_parse_sstring(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { UNUSED(type); CHECK(cfg_getstringtoken(pctx)); - return create_string(pctx, TOKEN_STRING(pctx), &cfg_type_sstring, ret); + create_string(pctx, TOKEN_STRING(pctx), &cfg_type_sstring, ret); + return ISC_R_SUCCESS; + cleanup: return result; } @@ -1364,8 +1353,9 @@ parse_btext(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { cfg_parser_error(pctx, CFG_LOG_NEAR, "expected bracketed text"); return ISC_R_UNEXPECTEDTOKEN; } - return create_string(pctx, TOKEN_STRING(pctx), &cfg_type_bracketed_text, - ret); + create_string(pctx, TOKEN_STRING(pctx), &cfg_type_bracketed_text, ret); + return ISC_R_SUCCESS; + cleanup: return result; } @@ -1543,16 +1533,16 @@ print_sstring(cfg_printer_t *pctx, const cfg_obj_t *obj) { } static void -free_string(cfg_parser_t *pctx, cfg_obj_t *obj) { - isc_mem_put(pctx->mctx, obj->value.string.base, +free_string(cfg_obj_t *obj) { + isc_mem_put(obj->mctx, obj->value.string.base, obj->value.string.length + 1); } static void -free_sockaddrtls(cfg_parser_t *pctx, cfg_obj_t *obj) { +free_sockaddrtls(cfg_obj_t *obj) { if (obj->value.sockaddrtls.tls.base != NULL) { INSIST(obj->value.sockaddrtls.tls.length != 0); - isc_mem_put(pctx->mctx, obj->value.sockaddrtls.tls.base, + isc_mem_put(obj->mctx, obj->value.sockaddrtls.tls.base, obj->value.sockaddrtls.tls.length + 1); } } @@ -1634,7 +1624,7 @@ parse_geoip(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); CHECK(cfg_parse_void(pctx, NULL, &obj->value.tuple[0])); /* Parse the optional "db" field. */ @@ -1881,17 +1871,15 @@ cfg_parse_boolean(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { goto bad_boolean; } - CHECK(cfg_create_obj(pctx, &cfg_type_boolean, &obj)); + cfg_obj_create(pctx->mctx, cfg_parser_currentfile(pctx), pctx->line, + &cfg_type_boolean, &obj); obj->value.boolean = value; *ret = obj; - return result; + return ISC_R_SUCCESS; bad_boolean: cfg_parser_error(pctx, CFG_LOG_NEAR, "boolean expected"); return ISC_R_UNEXPECTEDTOKEN; - -cleanup: - return result; } void @@ -1914,72 +1902,64 @@ cfg_type_t cfg_type_boolean = { "boolean", cfg_parse_boolean, * Lists. */ -isc_result_t -cfg_create_list(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **obj) { - isc_result_t result; - - REQUIRE(pctx != NULL); +static void +create_list(isc_mem_t *mctx, cfg_obj_t *file, size_t line, + const cfg_type_t *type, cfg_obj_t **obj) { + REQUIRE(mctx != NULL); REQUIRE(type != NULL); REQUIRE(obj != NULL && *obj == NULL); - CHECK(cfg_create_obj(pctx, type, obj)); + cfg_obj_create(mctx, file, line, type, obj); ISC_LIST_INIT((*obj)->value.list); -cleanup: - return result; } -static isc_result_t -create_listelt(cfg_parser_t *pctx, cfg_listelt_t **eltp) { - cfg_listelt_t *elt; - - elt = isc_mem_get(pctx->mctx, sizeof(*elt)); - elt->obj = NULL; - ISC_LINK_INIT(elt, link); +static void +create_listelt(cfg_obj_t *list, cfg_listelt_t **eltp) { + cfg_listelt_t *elt = isc_mem_get(list->mctx, sizeof(*elt)); + *elt = (cfg_listelt_t){ .link = ISC_LINK_INITIALIZER }; *eltp = elt; - return ISC_R_SUCCESS; } static void -free_listelt(cfg_parser_t *pctx, cfg_listelt_t *elt) { +free_listelt(cfg_obj_t *list, cfg_listelt_t **eltp) { + cfg_listelt_t *elt = *eltp; + *eltp = NULL; + if (elt->obj != NULL) { - cfg_obj_destroy(pctx, &elt->obj); + cfg_obj_detach(&elt->obj); } - isc_mem_put(pctx->mctx, elt, sizeof(*elt)); + isc_mem_put(list->mctx, elt, sizeof(*elt)); } static void -free_list(cfg_parser_t *pctx, cfg_obj_t *obj) { +free_list(cfg_obj_t *obj) { ISC_LIST_FOREACH(obj->value.list, elt, link) { - free_listelt(pctx, elt); + free_listelt(obj, &elt); } } 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 result; cfg_listelt_t *elt = NULL; cfg_obj_t *value = NULL; REQUIRE(pctx != NULL); + REQUIRE(list != NULL); REQUIRE(elttype != NULL); REQUIRE(ret != NULL && *ret == NULL); - CHECK(create_listelt(pctx, &elt)); - result = cfg_parse_obj(pctx, elttype, &value); if (result != ISC_R_SUCCESS) { - goto cleanup; + return result; } + create_listelt(list, &elt); elt->obj = value; - *ret = elt; - return ISC_R_SUCCESS; -cleanup: - isc_mem_put(pctx->mctx, elt, sizeof(*elt)); - return result; + return ISC_R_SUCCESS; } /* @@ -1993,7 +1973,8 @@ parse_list(cfg_parser_t *pctx, const cfg_type_t *listtype, cfg_obj_t **ret) { isc_result_t result; cfg_listelt_t *elt = NULL; - CHECK(cfg_create_list(pctx, listtype, &listobj)); + create_list(pctx->mctx, cfg_parser_currentfile(pctx), pctx->line, + listtype, &listobj); for (;;) { CHECK(cfg_peektoken(pctx, 0)); @@ -2002,7 +1983,7 @@ parse_list(cfg_parser_t *pctx, const cfg_type_t *listtype, cfg_obj_t **ret) { { break; } - CHECK(cfg_parse_listelt(pctx, listof, &elt)); + CHECK(cfg_parse_listelt(pctx, listobj, listof, &elt)); CHECK(parse_semicolon(pctx)); ISC_LIST_APPEND(listobj->value.list, elt, link); elt = NULL; @@ -2012,7 +1993,7 @@ parse_list(cfg_parser_t *pctx, const cfg_type_t *listtype, cfg_obj_t **ret) { cleanup: if (elt != NULL) { - free_listelt(pctx, elt); + free_listelt(listobj, &elt); } CLEANUP_OBJ(listobj); return result; @@ -2088,7 +2069,8 @@ cfg_parse_spacelist(cfg_parser_t *pctx, const cfg_type_t *listtype, listof = listtype->of; - CHECK(cfg_create_list(pctx, listtype, &listobj)); + create_list(pctx->mctx, cfg_parser_currentfile(pctx), pctx->line, + listtype, &listobj); for (;;) { cfg_listelt_t *elt = NULL; @@ -2099,7 +2081,7 @@ cfg_parse_spacelist(cfg_parser_t *pctx, const cfg_type_t *listtype, { break; } - CHECK(cfg_parse_listelt(pctx, listof, &elt)); + CHECK(cfg_parse_listelt(pctx, listobj, listof, &elt)); ISC_LIST_APPEND(listobj->value.list, elt, link); } *ret = listobj; @@ -2148,6 +2130,12 @@ cfg_list_next(const cfg_listelt_t *elt) { return ISC_LIST_NEXT(elt, link); } +void +cfg_list_unlink(cfg_obj_t *list, cfg_listelt_t *elt) { + ISC_LIST_UNLINK(list->value.list, elt, link); + free_listelt(list, &elt); +} + /* * Return the length of a list object. If obj is NULL or is not * a list, return 0. @@ -2208,14 +2196,11 @@ cfg_parse_mapbody(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { clausesets = type->of; - CHECK(create_map(pctx, type, &obj)); + create_map(pctx, type, &obj); obj->value.map.clausesets = clausesets; for (;;) { - cfg_listelt_t *elt; - - redo: /* * Parse the option name and see if it is known. */ @@ -2274,10 +2259,10 @@ cfg_parse_mapbody(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { CHECK(parser_openfile(pctx, g.gl_pathv[i])); } - cfg_obj_destroy(pctx, &includename); + cfg_obj_detach(&includename); globfree(&g); - goto redo; + continue; } clause = NULL; @@ -2302,7 +2287,7 @@ cfg_parse_mapbody(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { */ CHECK(cfg_parse_obj(pctx, &cfg_type_unsupported, &eltobj)); - cfg_obj_destroy(pctx, &eltobj); + cfg_obj_detach(&eltobj); CHECK(parse_semicolon(pctx)); continue; } @@ -2354,33 +2339,29 @@ cfg_parse_mapbody(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { if ((clause->flags & CFG_CLAUSEFLAG_MULTI) != 0) { /* Multivalued clause */ cfg_obj_t *listobj = NULL; + cfg_listelt_t *elt = NULL; - CHECK(cfg_create_list(pctx, &cfg_type_implicitlist, - &listobj)); + create_list(pctx->mctx, cfg_parser_currentfile(pctx), + pctx->line, &cfg_type_implicitlist, + &listobj); symval.as_pointer = listobj; result = isc_symtab_define_and_return( obj->value.map.symtab, clause->name, SYMTAB_DUMMY_TYPE, symval, isc_symexists_reject, &symval); - if (result == ISC_R_EXISTS) { CLEANUP_OBJ(listobj); listobj = symval.as_pointer; } - elt = NULL; - CHECK(cfg_parse_listelt(pctx, clause->type, &elt)); - CHECK(parse_semicolon(pctx)); - + CHECK(cfg_parse_listelt(pctx, listobj, clause->type, + &elt)); ISC_LIST_APPEND(listobj->value.list, elt, link); + CHECK(parse_semicolon(pctx)); } else { /* Single-valued clause */ - bool callback = ((clause->flags & - CFG_CLAUSEFLAG_CALLBACK) != 0); - - result = parse_symtab_elt( - pctx, clause->name, clause->type, - obj->value.map.symtab, callback); + result = parse_symtab_elt(pctx, clause, + obj->value.map.symtab); if (result == ISC_R_EXISTS) { cfg_parser_error(pctx, CFG_LOG_NEAR, "'%s' redefined", @@ -2407,20 +2388,51 @@ cleanup: } static isc_result_t -parse_symtab_elt(cfg_parser_t *pctx, const char *name, cfg_type_t *elttype, - isc_symtab_t *symtab, bool callback) { +change_directory(const cfg_obj_t *obj) { + isc_result_t result; + const char *directory = cfg_obj_asstring(obj); + + /* + * Change directory. + */ + if (!isc_file_ischdiridempotent(directory)) { + cfg_obj_log(obj, ISC_LOG_WARNING, + "option 'directory' contains relative path '%s'", + directory); + } + + if (!isc_file_isdirwritable(directory)) { + cfg_obj_log(obj, 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; + } + + return ISC_R_SUCCESS; +} + +static isc_result_t +parse_symtab_elt(cfg_parser_t *pctx, const cfg_clausedef_t *clause, + isc_symtab_t *symtab) { isc_result_t result; cfg_obj_t *obj = NULL; isc_symvalue_t symval; - CHECK(cfg_parse_obj(pctx, elttype, &obj)); + CHECK(cfg_parse_obj(pctx, clause->type, &obj)); - if (callback && pctx->callback != NULL) { - CHECK(pctx->callback(name, obj, pctx->callbackarg)); + if ((clause->flags & CFG_CLAUSEFLAG_CHDIR) != 0) { + CHECK(change_directory(obj)); } symval.as_pointer = obj; - CHECK(isc_symtab_define(symtab, name, SYMTAB_DUMMY_TYPE, symval, + CHECK(isc_symtab_define(symtab, clause->name, SYMTAB_DUMMY_TYPE, symval, isc_symexists_reject)); return ISC_R_SUCCESS; @@ -2786,7 +2798,8 @@ parse_token(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { UNUSED(type); - CHECK(cfg_create_obj(pctx, &cfg_type_token, &obj)); + cfg_obj_create(pctx->mctx, cfg_parser_currentfile(pctx), pctx->line, + &cfg_type_token, &obj); CHECK(cfg_gettoken(pctx, CFG_LEXOPT_QSTRING)); if (pctx->token.type == isc_tokentype_eof) { cfg_ungettoken(pctx); @@ -2825,7 +2838,8 @@ parse_unsupported(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; int braces = 0; - CHECK(cfg_create_list(pctx, type, &listobj)); + create_list(pctx->mctx, cfg_parser_currentfile(pctx), pctx->line, type, + &listobj); for (;;) { cfg_listelt_t *elt = NULL; @@ -2849,7 +2863,7 @@ parse_unsupported(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { goto cleanup; } - CHECK(cfg_parse_listelt(pctx, &cfg_type_token, &elt)); + CHECK(cfg_parse_listelt(pctx, listobj, &cfg_type_token, &elt)); ISC_LIST_APPEND(listobj->value.list, elt, link); } INSIST(braces == 0); @@ -3056,7 +3070,8 @@ parse_netaddr(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { isc_netaddr_t netaddr; unsigned int flags = *(const unsigned int *)type->of; - CHECK(cfg_create_obj(pctx, type, &obj)); + cfg_obj_create(pctx->mctx, cfg_parser_currentfile(pctx), pctx->line, + type, &obj); CHECK(cfg_parse_rawaddr(pctx, flags, &netaddr)); isc_sockaddr_fromnetaddr(&obj->value.sockaddr, &netaddr, 0); *ret = obj; @@ -3185,7 +3200,8 @@ cfg_parse_netprefix(cfg_parser_t *pctx, const cfg_type_t *type, } prefixlen = addrlen; } - CHECK(cfg_create_obj(pctx, &cfg_type_netprefix, &obj)); + cfg_obj_create(pctx->mctx, cfg_parser_currentfile(pctx), pctx->line, + &cfg_type_netprefix, &obj); obj->value.netprefix.address = netaddr; obj->value.netprefix.prefixlen = prefixlen; *ret = obj; @@ -3313,7 +3329,8 @@ parse_sockaddrsub(cfg_parser_t *pctx, const cfg_type_t *type, int flags, goto cleanup; } - CHECK(cfg_create_obj(pctx, type, &obj)); + cfg_obj_create(pctx->mctx, cfg_parser_currentfile(pctx), pctx->line, + type, &obj); if (have_tls == 1) { obj->value.sockaddrtls.tls = tls; } @@ -3595,41 +3612,6 @@ cfg_parser_warning(cfg_parser_t *pctx, unsigned int flags, const char *fmt, #define MAX_LOG_TOKEN 30 /* How much of a token to quote in log messages. */ -static bool -have_current_file(cfg_parser_t *pctx) { - cfg_listelt_t *elt; - if (pctx->open_files == NULL) { - return false; - } - - elt = ISC_LIST_TAIL(pctx->open_files->value.list); - if (elt == NULL) { - return false; - } - - return true; -} - -static char * -current_file(cfg_parser_t *pctx) { - static char none[] = "none"; - cfg_listelt_t *elt; - cfg_obj_t *fileobj; - - if (!have_current_file(pctx)) { - return none; - } - - elt = ISC_LIST_TAIL(pctx->open_files->value.list); - if (elt == NULL) { /* shouldn't be possible, but... */ - return none; - } - - fileobj = elt->obj; - INSIST(fileobj->type == &cfg_type_qstring); - return fileobj->value.string.base; -} - static void parser_complain(cfg_parser_t *pctx, bool is_warning, unsigned int flags, const char *format, va_list args) { @@ -3638,6 +3620,7 @@ parser_complain(cfg_parser_t *pctx, bool is_warning, unsigned int flags, static char message[2048]; int level = ISC_LOG_ERROR; const char *prep = ""; + const cfg_obj_t *file = NULL; size_t len; if (is_warning) { @@ -3645,11 +3628,14 @@ parser_complain(cfg_parser_t *pctx, bool is_warning, unsigned int flags, } where[0] = '\0'; - if (have_current_file(pctx)) { - snprintf(where, sizeof(where), "%s:%u: ", current_file(pctx), + file = cfg_parser_currentfile(pctx); + if (file != NULL) { + snprintf(where, sizeof(where), + "%s:%u: ", cfg_obj_asstring(file), pctx->line); + } else { + snprintf(where, sizeof(where), "%s:%u: ", + pctx->buf_name == NULL ? "none" : pctx->buf_name, pctx->line); - } else if (pctx->buf_name != NULL) { - snprintf(where, sizeof(where), "%s: ", pctx->buf_name); } len = vsnprintf(message, sizeof(message), format, args); @@ -3714,10 +3700,10 @@ cfg_obj_log(const cfg_obj_t *obj, int level, const char *fmt, ...) { va_end(ap); if (obj->file != NULL) { - isc_log_write(CAT, MOD, level, "%s:%u: %s", obj->file, - obj->line, msgbuf); + isc_log_write(CAT, MOD, level, "%s:%u: %s", + cfg_obj_asstring(obj->file), obj->line, msgbuf); } else { - isc_log_write(CAT, MOD, level, "%s", msgbuf); + isc_log_write(CAT, MOD, level, "%u: %s", obj->line, msgbuf); } } @@ -3725,7 +3711,7 @@ const char * cfg_obj_file(const cfg_obj_t *obj) { REQUIRE(obj != NULL); - return obj->file; + return cfg_obj_asstring(obj->file); } unsigned int @@ -3735,62 +3721,56 @@ cfg_obj_line(const cfg_obj_t *obj) { return obj->line; } -isc_result_t -cfg_create_obj(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { +void +cfg_obj_create(isc_mem_t *mctx, cfg_obj_t *file, size_t line, + const cfg_type_t *type, cfg_obj_t **ret) { cfg_obj_t *obj; - REQUIRE(pctx != NULL); + REQUIRE(mctx != NULL); REQUIRE(type != NULL); REQUIRE(ret != NULL && *ret == NULL); - obj = isc_mem_get(pctx->mctx, sizeof(cfg_obj_t)); - *obj = (cfg_obj_t){ .type = type, - .file = current_file(pctx), - .line = pctx->line, - .pctx = pctx }; + obj = isc_mem_get(mctx, sizeof(cfg_obj_t)); + *obj = (cfg_obj_t){ .magic = CFGOBJ_MAGIC, .type = type, .line = line }; + isc_refcount_init(&obj->references, 1); + isc_mem_attach(mctx, &obj->mctx); + if (file != NULL) { + cfg_obj_attach(file, &obj->file); + } *ret = obj; - - return ISC_R_SUCCESS; } static void map_symtabitem_destroy(char *key, unsigned int type, isc_symvalue_t symval, void *userarg) { cfg_obj_t *obj = symval.as_pointer; - cfg_parser_t *pctx = (cfg_parser_t *)userarg; UNUSED(key); UNUSED(type); + UNUSED(userarg); - cfg_obj_destroy(pctx, &obj); + cfg_obj_detach(&obj); } -static isc_result_t +static void create_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { - isc_result_t result; isc_symtab_t *symtab = NULL; cfg_obj_t *obj = NULL; - CHECK(cfg_create_obj(pctx, type, &obj)); + cfg_obj_create(pctx->mctx, cfg_parser_currentfile(pctx), pctx->line, + type, &obj); isc_symtab_create(pctx->mctx, map_symtabitem_destroy, pctx, false, &symtab); obj->value.map.symtab = symtab; obj->value.map.id = NULL; *ret = obj; - return ISC_R_SUCCESS; - -cleanup: - if (obj != NULL) { - isc_mem_put(pctx->mctx, obj, sizeof(*obj)); - } - return result; } static void -free_map(cfg_parser_t *pctx, cfg_obj_t *obj) { +free_map(cfg_obj_t *obj) { CLEANUP_OBJ(obj->value.map.id); isc_symtab_destroy(&obj->value.map.symtab); } @@ -3804,35 +3784,29 @@ cfg_obj_istype(const cfg_obj_t *obj, const cfg_type_t *type) { } /* - * Destroy 'obj', a configuration object created in 'pctx'. + * Destroy 'obj'. */ -void -cfg_obj_destroy(cfg_parser_t *pctx, cfg_obj_t **objp) { - REQUIRE(objp != NULL && *objp != NULL); - REQUIRE(pctx != NULL); +static void +cfg__obj_destroy(cfg_obj_t *obj) { + REQUIRE(obj != NULL); + REQUIRE(obj->magic == CFGOBJ_MAGIC); - cfg_obj_t *obj = *objp; - *objp = NULL; + obj->magic = 0; - if (isc_refcount_decrement(&obj->references) == 1) { - obj->type->rep->free(pctx, obj); - isc_refcount_destroy(&obj->references); - isc_mem_put(pctx->mctx, obj, sizeof(cfg_obj_t)); + if (obj->file != NULL) { + cfg_obj_detach(&obj->file); } + + obj->type->rep->free(obj); + + isc_refcount_destroy(&obj->references); + isc_mem_putanddetach(&obj->mctx, obj, sizeof(cfg_obj_t)); } -void -cfg_obj_attach(cfg_obj_t *src, cfg_obj_t **dest) { - REQUIRE(src != NULL); - REQUIRE(dest != NULL && *dest == NULL); - - isc_refcount_increment(&src->references); - *dest = src; -} +ISC_REFCOUNT_IMPL(cfg_obj, cfg__obj_destroy); static void -free_noop(cfg_parser_t *pctx, cfg_obj_t *obj) { - UNUSED(pctx); +free_noop(cfg_obj_t *obj) { UNUSED(obj); } @@ -3868,17 +3842,13 @@ cfg_print_grammar(const cfg_type_t *type, unsigned int flags, } isc_result_t -cfg_parser_mapadd(cfg_parser_t *pctx, cfg_obj_t *mapobj, cfg_obj_t *obj, - const char *clausename) { +cfg_map_add(cfg_obj_t *mapobj, cfg_obj_t *obj, const char *clausename) { isc_result_t result = ISC_R_SUCCESS; - const cfg_map_t *map; + const cfg_map_t *map = NULL; isc_symvalue_t symval; - cfg_obj_t *destobj = NULL; - cfg_listelt_t *elt = NULL; - const cfg_clausedef_t *const *clauseset; - const cfg_clausedef_t *clause; + const cfg_clausedef_t *const *clauseset = NULL; + const cfg_clausedef_t *clause = NULL; - REQUIRE(pctx != NULL); REQUIRE(mapobj != NULL && mapobj->type->rep == &cfg_rep_map); REQUIRE(obj != NULL); REQUIRE(clausename != NULL); @@ -3903,9 +3873,12 @@ breakout: &symval); if (result == ISC_R_NOTFOUND) { if ((clause->flags & CFG_CLAUSEFLAG_MULTI) != 0) { - CHECK(cfg_create_list(pctx, &cfg_type_implicitlist, - &destobj)); - CHECK(create_listelt(pctx, &elt)); + cfg_obj_t *destobj = NULL; + cfg_listelt_t *elt = NULL; + + create_list(mapobj->mctx, obj->file, obj->line, + &cfg_type_implicitlist, &destobj); + create_listelt(destobj, &elt); cfg_obj_attach(obj, &elt->obj); ISC_LIST_APPEND(destobj->value.list, elt, link); symval.as_pointer = destobj; @@ -3918,28 +3891,20 @@ breakout: isc_symexists_reject); INSIST(result == ISC_R_SUCCESS); } else { - cfg_obj_t *destobj2 = symval.as_pointer; + cfg_obj_t *destobj = symval.as_pointer; + cfg_listelt_t *elt = NULL; INSIST(result == ISC_R_SUCCESS); - if (destobj2->type == &cfg_type_implicitlist) { - CHECK(create_listelt(pctx, &elt)); + if (destobj->type == &cfg_type_implicitlist) { + create_listelt(destobj, &elt); cfg_obj_attach(obj, &elt->obj); - ISC_LIST_APPEND(destobj2->value.list, elt, link); + ISC_LIST_APPEND(destobj->value.list, elt, link); } else { result = ISC_R_EXISTS; } } - destobj = NULL; - elt = NULL; - -cleanup: - if (elt != NULL) { - free_listelt(pctx, elt); - } - CLEANUP_OBJ(destobj); - return result; } diff --git a/tests/isccfg/duration_test.c b/tests/isccfg/duration_test.c index 8d39ef5939..a9cb1fd021 100644 --- a/tests/isccfg/duration_test.c +++ b/tests/isccfg/duration_test.c @@ -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); } } diff --git a/tests/isccfg/grammar_test.c b/tests/isccfg/grammar_test.c index d2424b2afe..88e4f00160 100644 --- a/tests/isccfg/grammar_test.c +++ b/tests/isccfg/grammar_test.c @@ -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) { diff --git a/tests/isccfg/meson.build b/tests/isccfg/meson.build index 16ca023f86..419986f595 100644 --- a/tests/isccfg/meson.build +++ b/tests/isccfg/meson.build @@ -11,6 +11,7 @@ foreach unit : [ 'duration', + 'grammar', 'parser', ] test_bin = executable( diff --git a/tests/isccfg/parser_test.c b/tests/isccfg/parser_test.c index da95ddded0..a08bf2abe6 100644 --- a/tests/isccfg/parser_test.c +++ b/tests/isccfg/parser_test.c @@ -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() */