From: Alan T. DeKok Date: Sat, 18 Jan 2025 21:40:44 +0000 (-0500) Subject: Without &, bare words are more often attribute references. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=21670ec4bec85e8eb476d8cc7e8565f0c2d44936;p=thirdparty%2Ffreeradius-server.git Without &, bare words are more often attribute references. Add a flag to the call_env API which says that this thing might be an attribute reference, but only if it's a bare word. And it's not _required_ to be an attribute reference. Update rlm_linelog to use the new flag. Now that we can't key off of '&' to say "bare word is an attribute", we must instead use a slightly more complex method. --- diff --git a/src/lib/unlang/call_env.c b/src/lib/unlang/call_env.c index 9d9047b9f70..5fbd32d7b8a 100644 --- a/src/lib/unlang/call_env.c +++ b/src/lib/unlang/call_env.c @@ -373,16 +373,23 @@ int call_env_parsed_valid(call_env_parsed_t const *parsed, CONF_ITEM const *ci, * - -1 on failure. */ int call_env_parse_pair(TALLOC_CTX *ctx, void *out, tmpl_rules_t const *t_rules, CONF_ITEM *ci, - UNUSED call_env_ctx_t const *cec, UNUSED call_env_parser_t const *rule) + UNUSED call_env_ctx_t const *cec, call_env_parser_t const *rule) { CONF_PAIR const *to_parse = cf_item_to_pair(ci); tmpl_t *parsed_tmpl; + fr_token_t quote = cf_pair_value_quote(to_parse); - if (tmpl_afrom_substr(ctx, &parsed_tmpl, - &FR_SBUFF_IN(cf_pair_value(to_parse), talloc_strlen(cf_pair_value(to_parse))), - cf_pair_value_quote(to_parse), value_parse_rules_quoted[cf_pair_value_quote(to_parse)], - t_rules) < 0) { - return -1; + if ((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; + } + } else { + if (tmpl_afrom_substr(ctx, &parsed_tmpl, + &FR_SBUFF_IN(cf_pair_value(to_parse), talloc_strlen(cf_pair_value(to_parse))), + quote, value_parse_rules_quoted[cf_pair_value_quote(to_parse)], + t_rules) < 0) { + return -1; + } } *(void **)out = parsed_tmpl; diff --git a/src/lib/unlang/call_env.h b/src/lib/unlang/call_env.h index 750c4895146..fcf4ae2e8c2 100644 --- a/src/lib/unlang/call_env.h +++ b/src/lib/unlang/call_env.h @@ -89,6 +89,7 @@ typedef enum CC_HINT(flag_enum) { ///< 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_flags_t; DIAG_ON(attributes) @@ -129,6 +130,8 @@ DIAG_ON(attributes) #define call_env_parse_missing(_flags) ((_flags) & CALL_ENV_FLAG_PARSE_MISSING) #define call_env_secret(_flags) ((_flags) & CALL_ENV_FLAG_SECRET) + +#define call_env_bare_word_attribute(_flags) ((_flags) & CALL_ENV_FLAG_BARE_WORD_ATTRIBUTE) /** @} */ /** Callback for performing custom parsing of a #CONF_PAIR diff --git a/src/modules/rlm_linelog/rlm_linelog.c b/src/modules/rlm_linelog/rlm_linelog.c index 78edc856ed1..98fe75933ea 100644 --- a/src/modules/rlm_linelog/rlm_linelog.c +++ b/src/modules/rlm_linelog/rlm_linelog.c @@ -212,8 +212,8 @@ typedef struct { static const call_env_method_t linelog_method_env = { FR_CALL_ENV_METHOD_OUT(linelog_call_env_t), .env = (call_env_parser_t[]) { - { FR_CALL_ENV_PARSE_ONLY_OFFSET("format", FR_TYPE_STRING, CALL_ENV_FLAG_CONCAT | CALL_ENV_FLAG_PARSE_ONLY, linelog_call_env_t, log_src), .pair.escape.func = linelog_escape_func }, - { FR_CALL_ENV_OFFSET("reference",FR_TYPE_STRING, CALL_ENV_FLAG_CONCAT, linelog_call_env_t, log_ref), .pair.escape.func = linelog_escape_func }, + { FR_CALL_ENV_PARSE_ONLY_OFFSET("format", FR_TYPE_STRING, CALL_ENV_FLAG_CONCAT | CALL_ENV_FLAG_PARSE_ONLY| CALL_ENV_FLAG_BARE_WORD_ATTRIBUTE, linelog_call_env_t, log_src), .pair.escape.func = linelog_escape_func }, + { FR_CALL_ENV_OFFSET("reference",FR_TYPE_STRING, CALL_ENV_FLAG_CONCAT | CALL_ENV_FLAG_BARE_WORD_ATTRIBUTE, linelog_call_env_t, log_ref), .pair.escape.func = linelog_escape_func }, { FR_CALL_ENV_OFFSET("header", FR_TYPE_STRING, CALL_ENV_FLAG_CONCAT, linelog_call_env_t, log_head), .pair.escape.func = linelog_escape_func }, { FR_CALL_ENV_SUBSECTION("file", NULL, CALL_ENV_FLAG_NONE, ((call_env_parser_t[]) {