]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Track number of LDAP profiles applied
authorNick Porter <nick@portercomputing.co.uk>
Tue, 25 Feb 2025 12:28:45 +0000 (12:28 +0000)
committerNick Porter <nick@portercomputing.co.uk>
Tue, 25 Feb 2025 12:28:45 +0000 (12:28 +0000)
So that %ldap.profile() only returns true if at least one is applied.

The use of check_attribute to control application of LDAP profiles can
mean that the query succeeds and returns objects, but none of them get
applied - which should be treated equivalent to the query not returning
any objects

src/modules/rlm_ldap/profile.c
src/modules/rlm_ldap/rlm_ldap.c
src/modules/rlm_ldap/rlm_ldap.h

index ab8642107398f97e3aa4021e6141942e647a0501..e6aab84030474aaaa32c179d31fa8a72b3b96456 100644 (file)
@@ -42,6 +42,7 @@ USES_APPLE_DEPRECATED_API
  */
 typedef struct {
        fr_ldap_result_code_t   *ret;                   //!< Result of the query and applying the map.
+       int                     *applied;               //!< Number of profiles applied.
        fr_ldap_query_t         *query;
        char const              *dn;
        rlm_ldap_t const        *inst;
@@ -60,6 +61,7 @@ static unlang_action_t ldap_map_profile_resume(UNUSED rlm_rcode_t *p_result, UNU
        LDAPMessage             *entry = NULL;
        int                     ldap_errno;
        char                    *dn = NULL;
+       int                     ret;
 
        /*
         *      Tell the caller what happened
@@ -99,9 +101,12 @@ 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->profile_check_attr, profile_ctx->inst->valuepair_attr,
-                                  profile_ctx->expanded, entry) < 0) {
+               ret = fr_ldap_map_do(request, profile_ctx->inst->profile_check_attr, profile_ctx->inst->valuepair_attr,
+                                  profile_ctx->expanded, entry);
+               if (ret < 0) {
                        if (profile_ctx->ret) *profile_ctx->ret = LDAP_RESULT_ERROR;
+               } else {
+                       if (profile_ctx->applied) *profile_ctx->applied += ret;
                }
                entry = ldap_next_entry(handle, entry);
                REXDENT();
@@ -131,6 +136,7 @@ static void ldap_map_profile_cancel(UNUSED request_t *request, UNUSED fr_signal_
  * sets of attributes to the request.
  *
  * @param[out] ret             Where to write the result of the query.
+ * @param[out] applied         Where to write the number of profiles applied.
  * @param[in] inst             LDAP module instance.
  * @param[in] request          Current request.
  * @param[in] ttrunk           Trunk connection on which to run LDAP queries.
@@ -141,7 +147,7 @@ static void ldap_map_profile_cancel(UNUSED request_t *request, UNUSED fr_signal_
  *                             expanded attribute names and mapping information.
  * @return One of the RLM_MODULE_* values.
  */
-unlang_action_t rlm_ldap_map_profile(fr_ldap_result_code_t *ret,
+unlang_action_t rlm_ldap_map_profile(fr_ldap_result_code_t *ret, int *applied,
                                     rlm_ldap_t const *inst, request_t *request, fr_ldap_thread_trunk_t *ttrunk,
                                     char const *dn, int scope, char const *filter, fr_ldap_map_exp_t const *expanded)
 {
@@ -153,6 +159,7 @@ unlang_action_t rlm_ldap_map_profile(fr_ldap_result_code_t *ret,
        MEM(profile_ctx = talloc(unlang_interpret_frame_talloc_ctx(request), ldap_profile_ctx_t));
        *profile_ctx = (ldap_profile_ctx_t) {
                .ret = ret,
+               .applied = applied,
                .dn = dn,
                .expanded = expanded,
                .inst = inst
index 3a4c9ec24e52ae7491cae897b5b76e2024d92aac..173f1e52d98d1a753968d9d6ae4a94d6a9794b48 100644 (file)
@@ -1030,6 +1030,7 @@ static xlat_action_t ldap_group_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_ct
 
 typedef struct {
        fr_ldap_result_code_t   ret;
+       int                     applied;
        LDAPURLDesc             *url;
        fr_ldap_map_exp_t       expanded;
 } ldap_xlat_profile_ctx_t;
@@ -1044,7 +1045,7 @@ static xlat_action_t ldap_profile_xlat_resume(TALLOC_CTX *ctx, fr_dcursor_t *out
        fr_value_box_t                  *vb;
 
        MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_BOOL, attr_expr_bool_enum));
-       vb->vb_bool = xlat_ctx->ret == LDAP_RESULT_SUCCESS;
+       vb->vb_bool = (xlat_ctx->ret == LDAP_RESULT_SUCCESS) && (xlat_ctx->applied > 0);
        fr_dcursor_append(out, vb);
 
        return XLAT_ACTION_DONE;
@@ -1185,7 +1186,8 @@ static xlat_action_t ldap_profile_xlat(UNUSED TALLOC_CTX *ctx, UNUSED fr_dcursor
        /*
         *      Pushes a frame onto the stack to retrieve and evaluate a profile
         */
-       if (rlm_ldap_map_profile(&xlat_ctx->ret, inst, request, ttrunk, dn, scope, filter, &xlat_ctx->expanded) < 0) goto error;
+       if (rlm_ldap_map_profile(&xlat_ctx->ret, &xlat_ctx->applied, inst, request, ttrunk, dn,
+                                scope, filter, &xlat_ctx->expanded) < 0) goto error;
 
        return XLAT_ACTION_PUSH_UNLANG;
 }
@@ -1696,7 +1698,7 @@ static unlang_action_t mod_authorize_resume(rlm_rcode_t *p_result, UNUSED int *p
                        unlang_action_t ret;
 
                        REPEAT_MOD_AUTHORIZE_RESUME;
-                       ret = rlm_ldap_map_profile(NULL, inst, request, autz_ctx->ttrunk, autz_ctx->profile_value,
+                       ret = rlm_ldap_map_profile(NULL, NULL, inst, request, autz_ctx->ttrunk, autz_ctx->profile_value,
                                                   inst->profile_scope, call_env->default_profile.vb_strvalue, &autz_ctx->expanded);
                        switch (ret) {
                        case UNLANG_ACTION_FAIL:
@@ -1784,7 +1786,7 @@ static unlang_action_t mod_authorize_resume(rlm_rcode_t *p_result, UNUSED int *p
 
                        autz_ctx->profile_value = fr_ldap_berval_to_string(autz_ctx, autz_ctx->profile_values[autz_ctx->value_idx++]);
                        REPEAT_MOD_AUTHORIZE_RESUME;
-                       ret = rlm_ldap_map_profile(NULL, inst, request, autz_ctx->ttrunk, autz_ctx->profile_value,
+                       ret = rlm_ldap_map_profile(NULL, NULL, inst, request, autz_ctx->ttrunk, autz_ctx->profile_value,
                                                   inst->profile_scope, autz_ctx->call_env->profile_filter.vb_strvalue, &autz_ctx->expanded);
                        switch (ret) {
                        case UNLANG_ACTION_FAIL:
index 74e8097292507127776c80ae5abb9d19cda03bd3..a1d84140f08ad5dc6815b25569781012d45f734c 100644 (file)
@@ -274,6 +274,6 @@ unlang_action_t rlm_ldap_check_userobj_dynamic(rlm_rcode_t *p_result, request_t
 unlang_action_t rlm_ldap_check_cached(rlm_rcode_t *p_result,
                                      rlm_ldap_t const *inst, request_t *request, fr_value_box_t const *check);
 
-unlang_action_t rlm_ldap_map_profile(fr_ldap_result_code_t *ret,
+unlang_action_t rlm_ldap_map_profile(fr_ldap_result_code_t *ret, int *applied,
                                     rlm_ldap_t const *inst, request_t *request, fr_ldap_thread_trunk_t *ttrunk,
                                     char const *dn, int scope, char const *filter, fr_ldap_map_exp_t const *expanded);