return buffer;
}
-static bool invalid_location(CONF_SECTION *parent, char const *name, char const *filename, int lineno)
-{
- bool modules;
-
- /*
- * if / elsif MUST be inside of a
- * processing section, which MUST in turn
- * be inside of a "server" directive.
- */
- if (!parent || !parent->item.parent) goto invalid_location;
-
- modules = (strcmp(name, "map") == 0);
-
- /*
- * Can only have if / elseif / map in a few named sections.
- */
- for (parent = cf_item_to_section(parent->item.parent);
- parent != NULL;
- parent = cf_item_to_section(parent->item.parent)) {
- if (strcmp(parent->name1, "instantiate") == 0) return false;
- if (strcmp(parent->name1, "policy") == 0) return false;
- if (strcmp(parent->name1, "server") == 0) return false;
-
- if (!modules) continue;
- if (strcmp(parent->name1, "modules") == 0) return false;
- }
-
-invalid_location:
- ERROR("%s[%d]: Invalid location for '%s'", filename, lineno, name);
- return true;
-}
-
-
/*
* Like gettoken(), but uses the new API which seems better for a
* host of reasons.
buff[1] = stack->buff[1];
buff[2] = stack->buff[2];
- /*
- * if / elsif
- */
- if (invalid_location(parent, buff[1], frame->filename, frame->lineno)) return NULL;
-
cd = cf_data_find_in_parent(parent, fr_dict_t **, "dictionary");
if (!cd) {
dict = fr_dict_internal(); /* HACK - To fix policy sections */
*/
cf_data_add(cs, cond, NULL, false);
stack->ptr = ptr;
+
+ cs->allow_unlang = true;
return cf_section_to_item(cs);
}
buff[1] = stack->buff[1];
buff[2] = stack->buff[2];
- if (invalid_location(frame->current, "map", frame->filename, frame->lineno)) {
- invalid_syntax:
- ERROR("%s[%d]: Invalid syntax for 'map'", frame->filename, frame->lineno);
- return NULL;
- }
-
- /*
- * map { ... } is allowed inside of a module configuration.
- */
- if (*ptr == '{') {
- CONF_SECTION *modules;
-
- modules = cf_item_to_section(parent->item.parent);
- if (!modules || (strcmp(modules->name1, "modules") != 0)) goto invalid_syntax;
-
- ptr++;
- goto alloc_section;
- }
-
if (cf_get_token(parent, &ptr, &token, buff[1], stack->bufsize,
frame->filename, frame->lineno) < 0) {
return NULL;
}
mod = buff[1];
- /*
- * Maps without an expansion string are allowed, tho I
- * don't know why.
- */
- if (*ptr == '{') {
- ptr++;
- goto alloc_section;
- }
-
/*
* Now get the expansion string.
*/
ptr++;
value = buff[2];
-alloc_section:
/*
* Allocate the section
*/
if (parent == frame->special) frame->special = NULL;
frame->current = cf_item_to_section(parent->item.parent);
+
ptr++;
stack->ptr = ptr;
return 1;
/*
* See which unlang keywords are allowed
- */
- process = (cf_process_func_t) fr_table_value_by_str(unlang_keywords, buff[1], NULL);
- if (process) {
- CONF_ITEM *ci;
-
- stack->ptr = ptr;
- ci = process(stack);
- ptr = stack->ptr;
- if (!ci) return -1;
- if (cf_item_is_section(ci)) {
- css = cf_item_to_section(ci);
- goto add_section;
+ *
+ * 0 - no unlang keywords are allowed.
+ * 1 - unlang keywords are allowed
+ * 2 - unlang keywords are allowed only in sub-sections
+ * i.e. policy { ... } doesn't allow "if". But the "if"
+ * keyword is allowed in children of "policy".
+ */
+ if (parent->allow_unlang != 1) {
+ if ((strcmp(buff[1], "if") == 0) ||
+ (strcmp(buff[1], "elsif") == 0)) {
+ ERROR("%s[%d]: Invalid location for '%s'",
+ frame->filename, frame->lineno, buff[1]);
+ return -1;
}
+ } else {
+ process = (cf_process_func_t) fr_table_value_by_str(unlang_keywords, buff[1], NULL);
+ if (process) {
+ CONF_ITEM *ci;
- /*
- * Else the item is a pair, and it's already added to the section.
- */
- goto added_pair;
+ stack->ptr = ptr;
+ ci = process(stack);
+ ptr = stack->ptr;
+ if (!ci) return -1;
+ if (cf_item_is_section(ci)) {
+ css = cf_item_to_section(ci);
+ goto add_section;
+ }
+
+ /*
+ * Else the item is a pair, and it's already added to the section.
+ */
+ goto added_pair;
+ }
}
/*
frame->special = css;
}
+ /*
+ * Only a few top-level sections allow "unlang"
+ * statements. And for those, "unlang"
+ * statements are only allowed in child
+ * subsection.
+ *
+ * This isn't _strictly_ true for "instantiate",
+ * as we allow "group", "redundant", and a few
+ * more things there. But only allow "if" as a
+ * keyword when it's inside of another grouping
+ * section.
+ */
+ if (!parent->allow_unlang && !parent->item.parent) {
+ if (strcmp(css->name1, "instantiate") == 0) css->allow_unlang = 2;
+ if (strcmp(css->name1, "server") == 0) css->allow_unlang = 2;
+ if (strcmp(css->name1, "policy") == 0) css->allow_unlang = 2;
+
+ } else if (parent->allow_unlang) {
+ css->allow_unlang = 1;
+ }
+
add_section:
cf_item_add(parent, &(css->item));