* 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);
* 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.
/* 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);
*
* 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;
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;
}
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"},
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 */
}
/** 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;
config->name = NULL;
}
if (name) config->name = talloc_typed_strdup(config, name);
+
+ config->overwrite_config_name = overwrite_config;
}
/** Set the global radius config directory.
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.
*/
*/
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;
break;
case 'n':
- main_config_name_set(config, optarg);
+ main_config_name_set_default(config, optarg, true);
break;
case 'M':
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) {
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);
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.
*/
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();
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);
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: