From: Nick Porter Date: Wed, 29 Jan 2025 15:34:28 +0000 (+0000) Subject: Add check attribute processing to rlm_ldap profile handling X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8edf5b79129f6cd79e454d1f68d5ecdf69f3e797;p=thirdparty%2Ffreeradius-server.git Add check attribute processing to rlm_ldap profile handling Comparable to check items in rlm_files and check entries in rlm_sql with comparison operators. --- diff --git a/src/lib/ldap/base.h b/src/lib/ldap/base.h index 2998637ea58..0a2b34b12ac 100644 --- a/src/lib/ldap/base.h +++ b/src/lib/ldap/base.h @@ -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); /* diff --git a/src/lib/ldap/map.c b/src/lib/ldap/map.c index 4fed0e90519..78d81e44f82 100644 --- a/src/lib/ldap/map.c +++ b/src/lib/ldap/map.c @@ -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; diff --git a/src/modules/rlm_ldap/profile.c b/src/modules/rlm_ldap/profile.c index 944718f8bd5..ab864210739 100644 --- a/src/modules/rlm_ldap/profile.c +++ b/src/modules/rlm_ldap/profile.c @@ -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; } diff --git a/src/modules/rlm_ldap/rlm_ldap.c b/src/modules/rlm_ldap/rlm_ldap.c index d7d546669ee..b7d48c3575a 100644 --- a/src/modules/rlm_ldap/rlm_ldap.c +++ b/src/modules/rlm_ldap/rlm_ldap.c @@ -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);