From: Nick Porter Date: Tue, 4 Feb 2025 20:21:09 +0000 (+0000) Subject: Use expression evaluation in place of map for LDAP profile condition X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=af7bdcfb997c519404c25aa3c407ccdc6e50360e;p=thirdparty%2Ffreeradius-server.git Use expression evaluation in place of map for LDAP profile condition --- diff --git a/src/lib/ldap/map.c b/src/lib/ldap/map.c index b4d340519dc..95b77b350bd 100644 --- a/src/lib/ldap/map.c +++ b/src/lib/ldap/map.c @@ -354,39 +354,42 @@ int fr_ldap_map_do(request_t *request, char const *check_attr, count = ldap_count_values_len(values); for (i = 0; i < count; i++) { - map_t *check = NULL; - char *value = fr_ldap_berval_to_string(request, values[i]); + char *value = fr_ldap_berval_to_string(request, values[i]); + xlat_exp_head_t *cond_expr = NULL; + fr_value_box_list_t res; RDEBUG3("Parsing condition %s", value); - if (map_afrom_attr_str(request, &check, value, &parse_rules, &parse_rules) < 0) { + + if (xlat_tokenize_expression(request, &cond_expr, + &FR_SBUFF_IN(value, talloc_array_length(value) - 1), + NULL, &parse_rules) < 0) { RPEDEBUG("Failed parsing '%s' value \"%s\"", check_attr, value); fail: applied = -1; free: - talloc_free(check); + talloc_free(cond_expr); talloc_free(value); ldap_value_free_len(values); return applied; } - if (!fr_comparison_op[check->op]) { - REDEBUG("Invalid operator '%s'", fr_tokens[check->op]); + if (xlat_impure_func(cond_expr)) { + fr_strerror_const("Condition expression cannot depend on functions which call external databases"); goto fail; } - if (fr_type_is_structural(tmpl_attr_tail_da(check->lhs)->type) && - (check->op != T_OP_CMP_TRUE) && (check->op != T_OP_CMP_FALSE)) { - REDEBUG("Invalid comparison for structural type"); + RDEBUG2("Checking condition %s", value); + fr_value_box_list_init(&res); + if (unlang_xlat_eval(request, &res, request, cond_expr) < 0) { + RPEDEBUG("Failed evaluating condition"); goto fail; } - - RDEBUG2("Checking condition %s %s %s", check->lhs->name, fr_tokens[check->op], check->rhs->name); - if (radius_legacy_map_cmp(request, check) != 1) { + if (!fr_value_box_list_head(&res) || !fr_value_box_is_truthy(fr_value_box_list_head(&res))) { RDEBUG2("Failed match: skipping this profile"); goto free; } talloc_free(value); - talloc_free(check); + talloc_free(cond_expr); } ldap_value_free_len(values); }