]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Add check attribute processing to rlm_ldap profile handling
authorNick Porter <nick@portercomputing.co.uk>
Wed, 29 Jan 2025 15:34:28 +0000 (15:34 +0000)
committerNick Porter <nick@portercomputing.co.uk>
Wed, 29 Jan 2025 15:37:57 +0000 (15:37 +0000)
Comparable to check items in rlm_files and check entries in rlm_sql with
comparison operators.

src/lib/ldap/base.h
src/lib/ldap/map.c
src/modules/rlm_ldap/profile.c
src/modules/rlm_ldap/rlm_ldap.c

index 2998637ea58630268915c7b72506b7d225fdc887..0a2b34b12acd631ab6157864f8d85f6d9c57dcad 100644 (file)
@@ -857,7 +857,7 @@ int         fr_ldap_map_verify(map_t *map, void *instance);
 int            fr_ldap_map_expand(TALLOC_CTX *ctx, fr_ldap_map_exp_t *expanded, request_t *request,
                                   map_list_t const *maps, char const *generic_attr, char const *check_attr);
 
-int            fr_ldap_map_do(request_t *request,
+int            fr_ldap_map_do(request_t *request, char const *check_attr,
                               char const *valuepair_attr, fr_ldap_map_exp_t const *expanded, LDAPMessage *entry);
 
 /*
index 4fed0e90519aeb8a5e4697193e84d28fed939d55..78d81e44f82e5c61cad51d7a28fffc5e66134910 100644 (file)
@@ -322,7 +322,7 @@ int fr_ldap_map_expand(TALLOC_CTX *ctx, fr_ldap_map_exp_t *expanded, request_t *
  *     - Number of maps successfully applied.
  *     - -1 on failure.
  */
-int fr_ldap_map_do(request_t *request,
+int fr_ldap_map_do(request_t *request, char const *check_attr,
                   char const *valuepair_attr, fr_ldap_map_exp_t const *expanded, LDAPMessage *entry)
 {
        map_t const             *map = NULL;
@@ -333,6 +333,62 @@ int fr_ldap_map_do(request_t *request,
        char const              *name;
        LDAP                    *handle = fr_ldap_handle_thread_local();
 
+       if (check_attr) {
+               struct berval   **values;
+               int             count, i;
+               tmpl_rules_t const parse_rules = {
+                       .attr = {
+                               .dict_def = request->dict,
+                               .list_def = request_attr_request,
+                               .prefix = TMPL_ATTR_REF_PREFIX_AUTO
+                       },
+                       .xlat = {
+                               .runtime_el = unlang_interpret_event_list(request),
+                       },
+                       .at_runtime = true,
+               };
+
+               values = ldap_get_values_len(handle, entry, 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]);
+
+                       RDEBUG3("Parsing condition %s", value);
+                       if (map_afrom_attr_str(request, &check, value, &parse_rules, &parse_rules) < 0) {
+                               RPEDEBUG("Failed parsing '%s' value \"%s\"", check_attr, value);
+                       fail:
+                               applied = -1;
+                       free:
+                               talloc_free(check);
+                               talloc_free(value);
+                               ldap_value_free_len(values);
+                               return applied;
+                       }
+
+                       if (!fr_comparison_op[check->op]) {
+                               REDEBUG("Invalid operator '%s'", fr_tokens[check->op]);
+                               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");
+                               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) {
+                               RDEBUG2("Failed match: skipping this profile");
+                               goto free;
+                       }
+                       talloc_free(value);
+                       talloc_free(check);
+               }
+               ldap_value_free_len(values);
+       }
+
        while ((map = map_list_next(expanded->maps, map))) {
                int ret;
 
index 944718f8bd507653c3d58b708159545678e96244..ab8642107398f97e3aa4021e6141942e647a0501 100644 (file)
@@ -99,7 +99,7 @@ static unlang_action_t ldap_map_profile_resume(UNUSED rlm_rcode_t *p_result, UNU
                        ldap_memfree(dn);
                }
                RINDENT();
-               if (fr_ldap_map_do(request, profile_ctx->inst->valuepair_attr,
+               if (fr_ldap_map_do(request, profile_ctx->inst->profile_check_attr, profile_ctx->inst->valuepair_attr,
                                   profile_ctx->expanded, entry) < 0) {
                        if (profile_ctx->ret) *profile_ctx->ret = LDAP_RESULT_ERROR;
                }
index d7d546669ee2f108f9e0dc77794ff2f65903fb0c..b7d48c3575ac3dde38b4f8c53ba84cd66a8d78a2 100644 (file)
@@ -1705,7 +1705,7 @@ static unlang_action_t mod_authorize_resume(rlm_rcode_t *p_result, UNUSED int *p
                if (!map_list_empty(call_env->user_map) || inst->valuepair_attr) {
                        RDEBUG2("Processing user attributes");
                        RINDENT();
-                       if (fr_ldap_map_do(request, inst->valuepair_attr,
+                       if (fr_ldap_map_do(request, NULL, inst->valuepair_attr,
                                           &autz_ctx->expanded, autz_ctx->entry) > 0) rcode = RLM_MODULE_UPDATED;
                        REXDENT();
                        rlm_ldap_check_reply(request, inst, autz_ctx->dlinst->name, call_env->expect_password->vb_bool, autz_ctx->ttrunk);