]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Split out and abstract ldap profile code
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Tue, 5 Sep 2023 22:08:42 +0000 (16:08 -0600)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Wed, 6 Sep 2023 04:02:58 +0000 (22:02 -0600)
src/modules/rlm_ldap/all.mk
src/modules/rlm_ldap/profile.c [new file with mode: 0644]
src/modules/rlm_ldap/rlm_ldap.c
src/modules/rlm_ldap/rlm_ldap.h

index e513142e0f7b506107f0243f98c91fa5c103de77..ea93145320e09529d918823d68f4a1f9ea8c0bd0 100644 (file)
@@ -9,7 +9,7 @@ ifneq "${TARGETNAME}" ""
   TARGET       := $(TARGETNAME)$(L)
 endif
 
-SOURCES                := $(TARGETNAME).c groups.c user.c
+SOURCES                := $(TARGETNAME).c groups.c user.c profile.c
 
 SRC_CFLAGS     += -I$(top_builddir)/src/modules/rlm_ldap
 TGT_PREREQS    := libfreeradius-ldap$(L)
diff --git a/src/modules/rlm_ldap/profile.c b/src/modules/rlm_ldap/profile.c
new file mode 100644 (file)
index 0000000..5da03ac
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ *   This program is is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or (at
+ *   your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * $Id$
+ * @file rlm_ldap.c
+ * @brief LDAP authorization and authentication module.
+ *
+ * @author Arran Cudbard-Bell (a.cudbardb@freeradius.org)
+ * @author Alan DeKok (aland@freeradius.org)
+ *
+ * @copyright 2012,2015 Arran Cudbard-Bell (a.cudbardb@freeradius.org)
+ * @copyright 2013,2015 Network RADIUS SAS (legal@networkradius.com)
+ * @copyright 2012 Alan DeKok (aland@freeradius.org)
+ * @copyright 1999-2013 The FreeRADIUS Server Project.
+ */
+RCSID("$Id$")
+
+USES_APPLE_DEPRECATED_API
+
+#include "rlm_ldap.h"
+#include <freeradius-devel/ldap/conf.h>
+
+#include <freeradius-devel/server/map_proc.h>
+#include <freeradius-devel/server/module_rlm.h>
+
+/** Holds state of in progress async profile lookups
+ *
+ */
+typedef struct {
+       fr_ldap_query_t         *query;
+       char const              *dn;
+       rlm_ldap_t const        *inst;
+       fr_ldap_map_exp_t       const *expanded;
+} ldap_profile_ctx_t;
+
+/** Process the results of a profile lookup
+ *
+ */
+static unlang_action_t ldap_map_profile_resume(rlm_rcode_t *p_result, UNUSED int *priority, request_t *request,
+                                              void *uctx)
+{
+       ldap_profile_ctx_t      *profile_ctx = talloc_get_type_abort(uctx, ldap_profile_ctx_t);
+       fr_ldap_query_t         *query = profile_ctx->query;
+       LDAP                    *handle;
+       LDAPMessage             *entry = NULL;
+       int                     ldap_errno;
+       rlm_rcode_t             rcode = RLM_MODULE_OK;
+
+       switch (query->ret) {
+       case LDAP_RESULT_SUCCESS:
+               break;
+
+       case LDAP_RESULT_NO_RESULT:
+       case LDAP_RESULT_BAD_DN:
+               RDEBUG2("Profile object \"%s\" not found", profile_ctx->dn);
+               rcode = RLM_MODULE_NOTFOUND;
+               goto finish;
+
+       default:
+               rcode = RLM_MODULE_FAIL;
+               goto finish;
+       }
+
+       fr_assert(query->result);
+       handle = query->ldap_conn->handle;
+
+       entry = ldap_first_entry(handle, query->result);
+       if (!entry) {
+               ldap_get_option(handle, LDAP_OPT_RESULT_CODE, &ldap_errno);
+               REDEBUG("Failed retrieving entry: %s", ldap_err2string(ldap_errno));
+               rcode = RLM_MODULE_NOTFOUND;
+               goto finish;
+       }
+
+       RDEBUG2("Processing profile attributes");
+       RINDENT();
+       if (fr_ldap_map_do(request, profile_ctx->inst->valuepair_attr,
+                          profile_ctx->expanded, entry) > 0) rcode = RLM_MODULE_UPDATED;
+       REXDENT();
+
+finish:
+       talloc_free(profile_ctx);
+       RETURN_MODULE_RCODE(rcode);
+}
+
+/** Cancel an in progress profile lookup
+ *
+ */
+static void ldap_map_profile_cancel(UNUSED request_t *request, UNUSED fr_signal_t action, void *uctx)
+{
+       ldap_profile_ctx_t      *profile_ctx = talloc_get_type_abort(uctx, ldap_profile_ctx_t);
+
+       if (!profile_ctx->query || !profile_ctx->query->treq) return;
+
+       fr_trunk_request_signal_cancel(profile_ctx->query->treq);
+}
+
+/** Search for and apply an LDAP profile
+ *
+ * LDAP profiles are mapped using the same attribute map as user objects, they're used to add common
+ * sets of attributes to the request.
+ *
+ * @param[in] request          Current request.
+ * @param[in] dn               of profile object to apply.
+ * @param[in] scope            to apply when looking up profiles.
+ * @param[in] filter           to apply when looking up profiles.
+ * @param[in] expanded         Structure containing a list of xlat
+ *                             expanded attribute names and mapping information.
+ * @return One of the RLM_MODULE_* values.
+ */
+unlang_action_t rlm_ldap_map_profile(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)
+{
+       ldap_profile_ctx_t      *profile_ctx;
+
+       if (!dn || !*dn) return UNLANG_ACTION_CALCULATE_RESULT;
+
+       MEM(profile_ctx = talloc(unlang_interpret_frame_talloc_ctx(request), ldap_profile_ctx_t));
+       *profile_ctx = (ldap_profile_ctx_t) {
+               .dn = dn,
+               .expanded = expanded,
+               .inst = inst
+       };
+
+       if (unlang_function_push(request, NULL, ldap_map_profile_resume, ldap_map_profile_cancel,
+                                ~FR_SIGNAL_CANCEL, UNLANG_SUB_FRAME, profile_ctx) < 0) {
+               talloc_free(profile_ctx);
+               return UNLANG_ACTION_FAIL;
+       }
+
+       return fr_ldap_trunk_search(NULL, profile_ctx, &profile_ctx->query, request, ttrunk, dn,
+                                   scope, filter,
+                                   expanded->attrs, NULL, NULL);
+}
index ac360c385922dcc534450ec3252bec101dca9d4b..999520e14f4c00a3790789a8e5c7a92cce4f7d5a 100644 (file)
@@ -298,16 +298,6 @@ typedef struct {
        ldap_auth_call_env_t    *call_env;
 } ldap_auth_ctx_t;
 
-/** Holds state of in progress async profile lookups
- *
- */
-typedef struct {
-       fr_ldap_query_t         *query;
-       char const              *dn;
-       rlm_ldap_t const        *inst;
-       fr_ldap_map_exp_t       const *expanded;
-} ldap_profile_ctx_t;
-
 /** Holds state of in progress ldap user modifications
  *
  */
@@ -1235,108 +1225,6 @@ static unlang_action_t CC_HINT(nonnull) mod_authenticate(rlm_rcode_t *p_result,
        return UNLANG_ACTION_PUSHED_CHILD;
 }
 
-/** Process the results of a profile lookup
- *
- */
-static unlang_action_t ldap_map_profile_resume(rlm_rcode_t *p_result, UNUSED int *priority, request_t *request,
-                                              void *uctx)
-{
-       ldap_profile_ctx_t      *profile_ctx = talloc_get_type_abort(uctx, ldap_profile_ctx_t);
-       fr_ldap_query_t         *query = profile_ctx->query;
-       LDAP                    *handle;
-       LDAPMessage             *entry = NULL;
-       int                     ldap_errno;
-       rlm_rcode_t             rcode = RLM_MODULE_OK;
-
-       switch (query->ret) {
-       case LDAP_RESULT_SUCCESS:
-               break;
-
-       case LDAP_RESULT_NO_RESULT:
-       case LDAP_RESULT_BAD_DN:
-               RDEBUG2("Profile object \"%s\" not found", profile_ctx->dn);
-               rcode = RLM_MODULE_NOTFOUND;
-               goto finish;
-
-       default:
-               rcode = RLM_MODULE_FAIL;
-               goto finish;
-       }
-
-       fr_assert(query->result);
-       handle = query->ldap_conn->handle;
-
-       entry = ldap_first_entry(handle, query->result);
-       if (!entry) {
-               ldap_get_option(handle, LDAP_OPT_RESULT_CODE, &ldap_errno);
-               REDEBUG("Failed retrieving entry: %s", ldap_err2string(ldap_errno));
-               rcode = RLM_MODULE_NOTFOUND;
-               goto finish;
-       }
-
-       RDEBUG2("Processing profile attributes");
-       RINDENT();
-       if (fr_ldap_map_do(request, profile_ctx->inst->valuepair_attr,
-                          profile_ctx->expanded, entry) > 0) rcode = RLM_MODULE_UPDATED;
-       REXDENT();
-
-finish:
-       talloc_free(profile_ctx);
-       RETURN_MODULE_RCODE(rcode);
-}
-
-/** Cancel an in progress profile lookup
- *
- */
-static void ldap_map_profile_cancel(UNUSED request_t *request, UNUSED fr_signal_t action, void *uctx)
-{
-       ldap_profile_ctx_t      *profile_ctx = talloc_get_type_abort(uctx, ldap_profile_ctx_t);
-
-       if (!profile_ctx->query || !profile_ctx->query->treq) return;
-
-       fr_trunk_request_signal_cancel(profile_ctx->query->treq);
-}
-
-/** Search for and apply an LDAP profile
- *
- * LDAP profiles are mapped using the same attribute map as user objects, they're used to add common
- * sets of attributes to the request.
- *
- * @param[in] request          Current request.
- * @param[in] autz_ctx         Authorization context being processed.
- * @param[in] dn               of profile object to apply.
- * @param[in] expanded         Structure containing a list of xlat
- *                             expanded attribute names and mapping information.
- * @return One of the RLM_MODULE_* values.
- */
-static unlang_action_t rlm_ldap_map_profile(request_t *request, ldap_autz_ctx_t *autz_ctx,
-                                           char const *dn, fr_ldap_map_exp_t const *expanded)
-{
-       rlm_ldap_t const        *inst = autz_ctx->inst;
-       fr_ldap_thread_trunk_t  *ttrunk = autz_ctx->ttrunk;
-       ldap_profile_ctx_t      *profile_ctx;
-       rlm_rcode_t             ret;
-
-       if (!dn || !*dn) return UNLANG_ACTION_CALCULATE_RESULT;
-
-       MEM(profile_ctx = talloc(unlang_interpret_frame_talloc_ctx(request), ldap_profile_ctx_t));
-       *profile_ctx = (ldap_profile_ctx_t) {
-               .dn = dn,
-               .expanded = expanded,
-               .inst = inst
-       };
-
-       if (unlang_function_push(request, NULL, ldap_map_profile_resume, ldap_map_profile_cancel,
-                                ~FR_SIGNAL_CANCEL, UNLANG_SUB_FRAME, profile_ctx) < 0) {
-               talloc_free(profile_ctx);
-               return UNLANG_ACTION_FAIL;
-       }
-
-       return fr_ldap_trunk_search(&ret, profile_ctx, &profile_ctx->query, request, ttrunk, dn,
-                                   inst->profile_scope, autz_ctx->call_env->profile_filter.vb_strvalue,
-                                   expanded->attrs, NULL, NULL);
-}
-
 /** Start LDAP authorization with async lookup of user DN
  *
  */
@@ -1507,8 +1395,8 @@ 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(request, autz_ctx, call_env->default_profile.vb_strvalue,
-                                                  &autz_ctx->expanded);
+                       ret = rlm_ldap_map_profile(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:
                                rcode = RLM_MODULE_FAIL;
@@ -1571,7 +1459,8 @@ 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(request, autz_ctx, autz_ctx->profile_value, &autz_ctx->expanded);
+                       ret = rlm_ldap_map_profile(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:
                                rcode = RLM_MODULE_FAIL;
index 360d14208dbf41c210d61fb7c893b7c5344ab8fa..81944e7b7f1e21fa5567887622e0adfd69287f69 100644 (file)
@@ -270,3 +270,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(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);