From cad0063d4406456ae4ee5ad8a7ed2ae7bfd26df6 Mon Sep 17 00:00:00 2001 From: "Alan T. DeKok" Date: Mon, 22 Sep 2014 18:17:13 -0400 Subject: [PATCH] Added cf_section_parse_pass2() for pass2 checks of config items and PW_TYPE_XLAT, too. Modules can now tell the server core that config items will be dynamically expanded. For now, this means that the server can parse them in pass2, and complain at compile time about syntax errors. We will later expand this to allowing CONF_PAIRs to have compiled xlat's, which should be faster at run time --- src/include/conffile.h | 3 ++ src/main/conffile.c | 76 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/src/include/conffile.h b/src/include/conffile.h index 2fd5caff490a..dff8b76095f9 100644 --- a/src/include/conffile.h +++ b/src/include/conffile.h @@ -119,6 +119,8 @@ typedef struct timeval _timeval_t; #define PW_TYPE_FILE_INPUT ((1 << 14) | PW_TYPE_STRING) #define PW_TYPE_FILE_OUTPUT ((1 << 15) | PW_TYPE_STRING) +#define PW_TYPE_XLAT (1 << 16) //!< string will be dynamically expanded + #define FR_INTEGER_COND_CHECK(_name, _var, _cond, _new)\ do {\ if (!(_cond)) {\ @@ -153,6 +155,7 @@ void cf_section_add(CONF_SECTION *parent, CONF_SECTION *cs); int cf_pair_replace(CONF_SECTION *cs, CONF_PAIR *cp, char const *value); int cf_item_parse(CONF_SECTION *cs, char const *name, int type, void *data, char const *dflt); int cf_section_parse(CONF_SECTION *, void *base, CONF_PARSER const *variables); +int cf_section_parse_pass2(CONF_SECTION *, void *base, CONF_PARSER const *variables); const CONF_PARSER *cf_section_parse_table(CONF_SECTION *cs); CONF_SECTION *cf_file_read(char const *file); void cf_file_free(CONF_SECTION *cs); diff --git a/src/main/conffile.c b/src/main/conffile.c index 73cb22078547..4c1d9adcd78a 100644 --- a/src/main/conffile.c +++ b/src/main/conffile.c @@ -1440,6 +1440,82 @@ int cf_section_parse(CONF_SECTION *cs, void *base, } +/* + * Check XLAT things in pass 2. But don't cache the xlat stuff anywhere. + */ +int cf_section_parse_pass2(CONF_SECTION *cs, UNUSED void *base, + CONF_PARSER const *variables) +{ + int i; + ssize_t slen; + char const *error; + char *value = NULL; + xlat_exp_t *xlat; + + /* + * Handle the known configuration parameters. + */ + for (i = 0; variables[i].name != NULL; i++) { + CONF_PAIR *cp; + + /* + * Handle subsections specially + */ + if (variables[i].type == PW_TYPE_SUBSECTION) { + CONF_SECTION *subcs; + subcs = cf_section_sub_find(cs, variables[i].name); + + if (cf_section_parse_pass2(subcs, base, + (CONF_PARSER const *) variables[i].dflt) < 0) { + goto error; + } + continue; + } /* else it's a CONF_PAIR */ + + /* + * Ignore everything but xlat expansions. + */ + if ((variables[i].type & PW_TYPE_XLAT) == 0) continue; + + cp = cf_pair_find(cs, variables[i].name); + if (!cp || !cp->value) continue; + + if ((cp->value_type != T_DOUBLE_QUOTED_STRING) && + (cp->value_type != T_BARE_WORD)) continue; + + value = talloc_strdup(cs, cp->value); /* modified by xlat_tokenize */ + xlat = NULL; + + slen = xlat_tokenize(cs, value, &xlat, &error); + if (slen < 0) { + char const *prefix = ""; + char const *p = cp->value; + size_t indent = -slen; + + if (indent >= sizeof(parse_spaces)) { + size_t offset = (indent - (sizeof(parse_spaces) - 1)) + (sizeof(parse_spaces) * 0.75); + indent -= offset; + p += offset; + + prefix = "..."; + } + + cf_log_err(&cp->item, "Failed parsing expanded string:"); + cf_log_err(&cp->item, "%s%s", prefix, p); + cf_log_err(&cp->item, "%s%.*s^ %s", prefix, (int) indent, parse_spaces, error); + error: + talloc_free(value); + talloc_free(xlat); + return -1; + } + + talloc_free(value); + talloc_free(xlat); + } /* for all variables in the configuration section */ + + return 0; +} + static CONF_SECTION *cf_template_copy(CONF_SECTION *parent, CONF_SECTION const *template) { CONF_ITEM *ci;