]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Use expression evaluation in place of map for LDAP profile condition
authorNick Porter <nick@portercomputing.co.uk>
Tue, 4 Feb 2025 20:21:09 +0000 (20:21 +0000)
committerNick Porter <nick@portercomputing.co.uk>
Tue, 4 Feb 2025 20:21:09 +0000 (20:21 +0000)
src/lib/ldap/map.c

index b4d340519dc6075fd0ab1fc18685120f968bf637..95b77b350bdcbc8a37e4018ca150beb6db433195 100644 (file)
@@ -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);
        }