From fc1465c31e5fc794e864682b4156689c555e92d4 Mon Sep 17 00:00:00 2001 From: "Alan T. DeKok" Date: Mon, 20 Jan 2025 20:56:25 -0500 Subject: [PATCH] handle ATTRIBUTE flag better. If the flag is set, then the data _must_ be parsed as an attribute. In which case we just call the tmpl_afrom_attr_str() function, instead of calling the generic tmpl_afrom_substr() function. and then complaining if the parsed tmpl wasn't an attribute. --- src/lib/unlang/call_env.c | 21 ++++++++++++++------- src/lib/unlang/call_env.h | 6 ++++-- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/lib/unlang/call_env.c b/src/lib/unlang/call_env.c index 5fbd32d7b8..f417c40df6 100644 --- a/src/lib/unlang/call_env.c +++ b/src/lib/unlang/call_env.c @@ -335,16 +335,18 @@ int call_env_parsed_valid(call_env_parsed_t const *parsed, CONF_ITEM const *ci, tmpl = parsed->data.tmpl; switch (tmpl->type) { + /* + * These can't be created from a call_env flag which is marked as an attribute. + */ case TMPL_TYPE_DATA: case TMPL_TYPE_EXEC: case TMPL_TYPE_XLAT: - if (call_env_attribute(rule->flags)) { - cf_log_perr(ci, "'%s' expands to %s - attribute reference required", tmpl->name, - tmpl_type_to_str(tmpl->type)); - return -1; - } - FALL_THROUGH; + fr_assert(!call_env_attribute(rule->flags)); + break; + /* + * This can be created from multiple types of flags, not just an attribute one. + */ case TMPL_TYPE_ATTR: break; @@ -379,7 +381,12 @@ int call_env_parse_pair(TALLOC_CTX *ctx, void *out, tmpl_rules_t const *t_rules, tmpl_t *parsed_tmpl; fr_token_t quote = cf_pair_value_quote(to_parse); - if ((quote == T_BARE_WORD) && call_env_bare_word_attribute(rule->flags)) { + /* + * If it's marked as containing an attribute reference, + * then always parse it as an attribute reference. + */ + if (call_env_attribute(rule->flags) || + ((quote == T_BARE_WORD) && call_env_bare_word_attribute(rule->flags))) { if (tmpl_afrom_attr_str(ctx, NULL, &parsed_tmpl, cf_pair_value(to_parse), t_rules) <= 0) { return -1; } diff --git a/src/lib/unlang/call_env.h b/src/lib/unlang/call_env.h index fcf4ae2e8c..cf86e6f384 100644 --- a/src/lib/unlang/call_env.h +++ b/src/lib/unlang/call_env.h @@ -83,13 +83,15 @@ typedef enum CC_HINT(flag_enum) { ///< regardless of how they are in the config file. E.g. the `program` ///< option of `rlm_exec` should always be parsed as T_BACK_QUOTED_STRING. CALL_ENV_FLAG_PARSE_ONLY = (1 << 6), //!< The result of parsing will not be evaluated at runtime. - CALL_ENV_FLAG_ATTRIBUTE = (1 << 7), //!< Tmpl must contain an attribute reference. + CALL_ENV_FLAG_ATTRIBUTE = (1 << 7), //!< Tmpl MUST contain an attribute reference. CALL_ENV_FLAG_SUBSECTION = (1 << 8), //!< This is a subsection. CALL_ENV_FLAG_PARSE_MISSING = (1 << 9), //!< If this subsection is missing, still parse it. Useful for cases where ///< there is a callback which always needs to be run to set up required ///< data structures. CALL_ENV_FLAG_SECRET = (1 << 10), //!< The value is a secret, and should not be logged. - CALL_ENV_FLAG_BARE_WORD_ATTRIBUTE = (1 << 11), //!< bare words are treated as an attribute + CALL_ENV_FLAG_BARE_WORD_ATTRIBUTE = (1 << 11), //!< bare words are treated as an attribute, but strings may + ///< be xlats. Should not be used with CALL_ENV_FLAG_ATTRIBUTE. + ///< as that flag _always_ parses it as an attribute. } call_env_flags_t; DIAG_ON(attributes) -- 2.47.3