From: Alan T. DeKok Date: Sun, 19 Jan 2025 11:24:31 +0000 (-0500) Subject: more debugging, and parse RHS as attribute for new code X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ee093de6df928d0ff4b3a39a05fac1a53f499794;p=thirdparty%2Ffreeradius-server.git more debugging, and parse RHS as attribute for new code debugging lets us see exactly which stage of parsing failed. when tmpl_require_enum_prefix=yes, AND we can't parse the RHS as an enum, or other data type, then try to parse it as an attribute. This means that if the RHS string is unquoted, and is accidentally the same as an attribute name, then it will get parsed as an attribute reference. It's not clear what the best solution is here. In order to differentiate the two types of data, either have to: a) forbid bare words except for attribute names which means requiring that all strings including passwords are quoted. This seems unfriendly. b) allow '&' on the RHS, in order to separate it from bare word strings. But then if a password begins with '&', it will be treated as an attribute reference c) change the operator to one which explicitly signals that the RHS is an attribute. Perhaps by tacking on '&' after the operator? Which seems fugly. --- diff --git a/src/lib/server/map.c b/src/lib/server/map.c index 13092ec41f7..c47ede16861 100644 --- a/src/lib/server/map.c +++ b/src/lib/server/map.c @@ -47,6 +47,8 @@ RCSID("$Id$") #include +extern bool tmpl_require_enum_prefix; + static fr_table_num_sorted_t const cond_quote_table[] = { { L("\""), T_DOUBLE_QUOTED_STRING }, /* Don't re-order, backslash throws off ordering */ { L("'"), T_SINGLE_QUOTED_STRING }, @@ -2626,7 +2628,12 @@ int map_afrom_fields(TALLOC_CTX *ctx, map_t **out, map_t **parent_p, request_t * slen = tmpl_afrom_substr(map, &map->rhs, &FR_SBUFF_IN(rhs + 1, len - 1), quote, value_parse_rules_quoted[quote], &my_rules); - if (slen < 0) goto error; + if (slen < 0) { + REDEBUG3("Failed parsing right-hand side as quoted string."); + fail_rhs: + fr_strerror_printf("Failed parsing right-hand side: %s", fr_strerror()); + goto error; + } if (slen == 0) { rhs = ""; @@ -2642,13 +2649,14 @@ int map_afrom_fields(TALLOC_CTX *ctx, map_t **out, map_t **parent_p, request_t * * These operators require a hard-coded string on the RHS. */ if (strcmp(rhs, "ANY") != 0) { - fr_strerror_printf("Invalid value for %s", fr_tokens[map->op]); + fr_strerror_printf("Invalid value %s for operator %s", rhs, fr_tokens[map->op]); goto error; } if (tmpl_afrom_value_box(map, &map->rhs, fr_box_strvalue("ANY"), false) < 0) goto error; } else if (rhs[0] == '&') { + parse_as_attr: /* * No enums here. */ @@ -2658,7 +2666,10 @@ int map_afrom_fields(TALLOC_CTX *ctx, map_t **out, map_t **parent_p, request_t * my_rules.enumv = NULL; slen = tmpl_afrom_attr_str(map, NULL, &map->rhs, rhs, &my_rules); - if (slen <= 0) goto error; + if (slen <= 0) { + REDEBUG3("Failed parsing right-hand side as attribute."); + goto fail_rhs; + } } else if (!rhs[0] || !my_rules.enumv || (my_rules.enumv->type == FR_TYPE_STRING)) { quote = T_BARE_WORD; @@ -2681,7 +2692,12 @@ int map_afrom_fields(TALLOC_CTX *ctx, map_t **out, map_t **parent_p, request_t * */ slen = tmpl_afrom_substr(map, &map->rhs, &FR_SBUFF_IN(rhs, strlen(rhs)), T_BARE_WORD, value_parse_rules_unquoted[T_BARE_WORD], &my_rules); - if (slen <= 0) goto error; + if (slen <= 0) { + if (tmpl_require_enum_prefix) goto parse_as_attr; + + REDEBUG3("Failed parsing right-hand side as generic data type."); + goto fail_rhs; + } /* * Xlat expansions are cast to strings for structural data types. @@ -2699,7 +2715,10 @@ int map_afrom_fields(TALLOC_CTX *ctx, map_t **out, map_t **parent_p, request_t * fr_assert(tmpl_is_data_unresolved(map->rhs)); - if (tmpl_resolve(map->rhs, &tr_rules) < 0) goto error; + if (tmpl_resolve(map->rhs, &tr_rules) < 0) { + REDEBUG3("Failed resolving right-hand side."); + goto fail_rhs; + } } /*