From: Arran Cudbard-Bell Date: Thu, 28 Jun 2018 00:47:20 +0000 (-0400) Subject: Fix for ${name} reference expansion X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=08a8de1780d6b6d8cfdc05967a03ff2e9e1af77e;p=thirdparty%2Ffreeradius-server.git Fix for ${name} reference expansion --- diff --git a/src/include/cf_file.h b/src/include/cf_file.h index 3985c87516b..b7a61726f78 100644 --- a/src/include/cf_file.h +++ b/src/include/cf_file.h @@ -44,6 +44,7 @@ extern "C" { * Config file parsing */ int cf_file_read(CONF_SECTION *cs, char const *file); +int cf_section_pass2(CONF_SECTION *cs); void cf_file_free(CONF_SECTION *cs); bool cf_file_check(CONF_SECTION *cs, char const *filename, bool check_perms); diff --git a/src/include/radiusd.h b/src/include/radiusd.h index 84bec457145..060a83951e6 100644 --- a/src/include/radiusd.h +++ b/src/include/radiusd.h @@ -102,8 +102,9 @@ typedef rlm_rcode_t (*RAD_REQUEST_FUNP)(REQUEST *); * The parsed version of the main server config. */ typedef struct { - char const *my_name; char const *name; //!< Name of the daemon, usually 'radiusd'. + bool overwrite_config_name; //!< Overwrite the configured name, as this + ///< was specified by the user on the command line. CONF_SECTION *root_cs; //!< Root of the server config. bool daemonize; //!< Should the server daemonize on startup. @@ -614,7 +615,7 @@ int request_receive(TALLOC_CTX *ctx, rad_listen_t *listener, RADIUS_PACKET *pack /* Define a global config structure */ extern main_config_t const *main_config; -void main_config_name_set(main_config_t *config, char const *name); +void main_config_name_set_default(main_config_t *config, char const *name, bool overwrite_config); void main_config_raddb_dir_set(main_config_t *config, char const *path); void main_config_dict_dir_set(main_config_t *config, char const *path); diff --git a/src/main/cf_file.c b/src/main/cf_file.c index 6252558cafa..08eb8665a4a 100644 --- a/src/main/cf_file.c +++ b/src/main/cf_file.c @@ -634,7 +634,7 @@ static int _file_callback(void *ctx, void *data) * * This is a breadth-first expansion. "deep */ -static int cf_section_pass2(CONF_SECTION *cs) +int cf_section_pass2(CONF_SECTION *cs) { CONF_ITEM *ci; diff --git a/src/main/client.c b/src/main/client.c index d63e4fea275..18b2474f999 100644 --- a/src/main/client.c +++ b/src/main/client.c @@ -1012,7 +1012,7 @@ RADCLIENT *client_read(char const *filename, CONF_SECTION *server_cs, bool check cs = cf_section_alloc(NULL, NULL, "main", NULL); if (!cs) return NULL; - if (cf_file_read(cs, filename) < 0) { + if ((cf_file_read(cs, filename) < 0) || (cf_section_pass2(cs) < 0)) { talloc_free(cs); return NULL; } diff --git a/src/main/mainconfig.c b/src/main/mainconfig.c index afe589d98b1..1df9ef9c7e9 100644 --- a/src/main/mainconfig.c +++ b/src/main/mainconfig.c @@ -218,7 +218,7 @@ static const CONF_PARSER security_config[] = { static const CONF_PARSER switch_users_config[] = { { FR_CONF_POINTER("security", FR_TYPE_SUBSECTION, NULL), .subcs = (void const *) security_config }, - { FR_CONF_OFFSET("name", FR_TYPE_STRING, main_config_t, my_name), .func = name_parse }, /* DO NOT SET DEFAULT */ + { FR_CONF_OFFSET("name", FR_TYPE_STRING, main_config_t, name), .func = name_parse }, /* DO NOT SET DEFAULT */ { FR_CONF_OFFSET("prefix", FR_TYPE_STRING, main_config_t, prefix), .dflt = "/usr/local" }, { FR_CONF_OFFSET("local_state_dir", FR_TYPE_STRING, main_config_t, local_state_dir), .dflt = "${prefix}/var"}, @@ -361,7 +361,13 @@ static int num_workers_parse(TALLOC_CTX *ctx, void *out, void *parent, static int name_parse(TALLOC_CTX *ctx, void *out, void *parent, CONF_ITEM *ci, CONF_PARSER const *rule) { - if (*((char **)out)) talloc_free(*((char **)out)); /* Free existing buffer */ + main_config_t *config = parent; + + if (*((char **)out)) { + if (config->overwrite_config_name) return 0; /* Don't change */ + + talloc_free(*((char **)out)); /* Free existing buffer */ + } return cf_pair_parse_value(ctx, out, parent, ci, rule); /* Set new value */ } @@ -783,10 +789,13 @@ static int switch_users(main_config_t *config, CONF_SECTION *cs) /** Set the server name * - * @param[in] config to alter. - * @param[in] name to set e.g. "radiusd". + * @note Will only add pair if one does not already exist + * + * @param[in] config to alter. + * @param[in] name to set e.g. "radiusd". + * @param[in] overwrite_config replace any CONF_PAIRs with this value. */ -void main_config_name_set(main_config_t *config, char const *name) +void main_config_name_set_default(main_config_t *config, char const *name, bool overwrite_config) { if (config->name) { char *p; @@ -796,6 +805,8 @@ void main_config_name_set(main_config_t *config, char const *name) config->name = NULL; } if (name) config->name = talloc_typed_strdup(config, name); + + config->overwrite_config_name = overwrite_config; } /** Set the global radius config directory. @@ -982,6 +993,30 @@ do {\ return -1; } + /* + * Do any fixups here that might be used in references + */ + if (config->name) { + CONF_PAIR *cp; + + cp = cf_pair_find(cs, "name"); + if (cp){ + if (config->overwrite_config_name && (cf_pair_replace(cs, cp, config->name) < 0)) { + ERROR("Failed adding/replacing \"name\" config item"); + talloc_free(cs); + return -1; + } + } else { + MEM(cp = cf_pair_alloc(cs, "name", config->name, T_OP_EQ, T_BARE_WORD, T_DOUBLE_QUOTED_STRING)); + cf_pair_add(cs, cp); + } + } + + if (cf_section_pass2(cs) < 0) { + talloc_free(cs); + return -1; + } + /* * Parse environment variables first. */ diff --git a/src/main/radiusd.c b/src/main/radiusd.c index 166e1000bc1..b8cc3ad109d 100644 --- a/src/main/radiusd.c +++ b/src/main/radiusd.c @@ -182,9 +182,9 @@ int main(int argc, char *argv[]) */ p = strrchr(argv[0], FR_DIR_SEP); if (!p) { - main_config_name_set(config, argv[0]); + main_config_name_set_default(config, argv[0], false); } else { - main_config_name_set(config, p + 1); + main_config_name_set_default(config, p + 1, false); } config->daemonize = true; @@ -281,7 +281,7 @@ int main(int argc, char *argv[]) break; case 'n': - main_config_name_set(config, optarg); + main_config_name_set_default(config, optarg, true); break; case 'M': diff --git a/src/main/radwho.c b/src/main/radwho.c index 78e8b019f85..ba7092b952f 100644 --- a/src/main/radwho.c +++ b/src/main/radwho.c @@ -216,9 +216,9 @@ int main(int argc, char **argv) p = strrchr(argv[0], FR_DIR_SEP); if (!p) { - main_config_name_set(config, argv[0]); + main_config_name_set_default(config, argv[0], false); } else { - main_config_name_set(config, p + 1); + main_config_name_set_default(config, p + 1, false); } while((c = getopt(argc, argv, "d:D:fF:nN:sSipP:crRu:U:Z")) != EOF) switch (c) { @@ -336,7 +336,7 @@ int main(int argc, char **argv) if (!maincs) exit(EXIT_FAILURE); snprintf(buffer, sizeof(buffer), "%.200s/radiusd.conf", config->raddb_dir); - if (cf_file_read(maincs, buffer) < 0) { + if ((cf_file_read(maincs, buffer) < 0) || (cf_section_pass2(maincs) < 0)) { fr_perror("%s: Error reading or parsing radiusd.conf\n", argv[0]); talloc_free(maincs); exit(EXIT_FAILURE); diff --git a/src/main/unit_test_map.c b/src/main/unit_test_map.c index bcdc73a74fb..e145ce99116 100644 --- a/src/main/unit_test_map.c +++ b/src/main/unit_test_map.c @@ -82,14 +82,14 @@ static int process_file(char const *filename) fprintf(stderr, "Failed allocating main config"); exit(EXIT_FAILURE); } - main_config_name_set(config, "unit_test_map"); - config->root_cs = cf_section_alloc(config, NULL, "main", NULL); - if (cf_file_read(config->root_cs, filename) < 0) { + if ((cf_file_read(config->root_cs, filename) < 0) || (cf_section_pass2(config->root_cs) < 0)) { fprintf(stderr, "unit_test_map: Failed parsing %s\n", filename); exit(EXIT_FAILURE); } + main_config_name_set_default(config, "unit_test_map", false); + /* * Always has to be an "update" section. */ diff --git a/src/main/unit_test_module.c b/src/main/unit_test_module.c index cc4538f96a9..814dc2e274e 100644 --- a/src/main/unit_test_module.c +++ b/src/main/unit_test_module.c @@ -709,9 +709,9 @@ int main(int argc, char *argv[]) p = strrchr(argv[0], FR_DIR_SEP); if (!p) { - main_config_name_set(config, argv[0]); + main_config_name_set_default(config, argv[0], false); } else { - main_config_name_set(config, p + 1); + main_config_name_set_default(config, p + 1, false); } fr_talloc_fault_setup(); diff --git a/src/modules/proto_control/radmin.c b/src/modules/proto_control/radmin.c index 8322064e2b3..b12dbcf2db7 100644 --- a/src/modules/proto_control/radmin.c +++ b/src/modules/proto_control/radmin.c @@ -545,7 +545,7 @@ int main(int argc, char **argv) cs = cf_section_alloc(NULL, NULL, "main", NULL); if (!cs) exit(EXIT_FAILURE); - if (cf_file_read(cs, buffer) < 0) { + if ((cf_file_read(cs, buffer) < 0) || (cf_section_pass2(cs) < 0)) { fprintf(stderr, "%s: Errors reading or parsing %s\n", progname, buffer); talloc_free(cs); usage(1); diff --git a/src/modules/rlm_redis_ippool/rlm_redis_ippool_tool.c b/src/modules/rlm_redis_ippool/rlm_redis_ippool_tool.c index 0c3ebca8153..a27a6928752 100644 --- a/src/modules/rlm_redis_ippool/rlm_redis_ippool_tool.c +++ b/src/modules/rlm_redis_ippool/rlm_redis_ippool_tool.c @@ -1450,7 +1450,7 @@ do { \ break; case 'f': - if (cf_file_read(conf->cs, optarg) < 0) exit(EXIT_FAILURE); + if (cf_file_read(conf->cs, optarg) < 0 || (cf_section_pass2(conf->cs) < 0)) exit(EXIT_FAILURE); break; default: