The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
profile.c
Go to the documentation of this file.
1 /*
2  * This program is is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 2 of the License, or (at
5  * your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15  */
16 
17 /**
18  * $Id: 1ddbddd14042f3cf4d39b53aad88e2ded228dc7f $
19  * @file rlm_ldap.c
20  * @brief LDAP authorization and authentication module.
21  *
22  * @author Arran Cudbard-Bell (a.cudbardb@freeradius.org)
23  * @author Alan DeKok (aland@freeradius.org)
24  *
25  * @copyright 2012,2015 Arran Cudbard-Bell (a.cudbardb@freeradius.org)
26  * @copyright 2013,2015 Network RADIUS SAS (legal@networkradius.com)
27  * @copyright 2012 Alan DeKok (aland@freeradius.org)
28  * @copyright 1999-2013 The FreeRADIUS Server Project.
29  */
30 RCSID("$Id: 1ddbddd14042f3cf4d39b53aad88e2ded228dc7f $")
31 
33 
34 #include "rlm_ldap.h"
35 #include <freeradius-devel/ldap/conf.h>
36 
37 #include <freeradius-devel/server/map_proc.h>
38 #include <freeradius-devel/server/module_rlm.h>
39 
40 /** Holds state of in progress async profile lookups
41  *
42  */
43 typedef struct {
44  fr_ldap_result_code_t *ret; //!< Result of the query and applying the map.
46  char const *dn;
47  rlm_ldap_t const *inst;
50 
51 /** Process the results of a profile lookup
52  *
53  */
54 static unlang_action_t ldap_map_profile_resume(UNUSED rlm_rcode_t *p_result, UNUSED int *priority, request_t *request,
55  void *uctx)
56 {
57  ldap_profile_ctx_t *profile_ctx = talloc_get_type_abort(uctx, ldap_profile_ctx_t);
58  fr_ldap_query_t *query = profile_ctx->query;
59  LDAP *handle;
60  LDAPMessage *entry = NULL;
61  int ldap_errno;
62 
63  /*
64  * Tell the caller what happened
65  */
66  if (profile_ctx->ret) *profile_ctx->ret = query->ret;
67 
68  switch (query->ret) {
70  break;
71 
73  case LDAP_RESULT_BAD_DN:
74  RDEBUG2("Profile object \"%s\" not found", profile_ctx->dn);
75  goto finish;
76 
77  default:
78  goto finish;
79  }
80 
81  fr_assert(query->result);
82  handle = query->ldap_conn->handle;
83 
84  entry = ldap_first_entry(handle, query->result);
85  if (!entry) {
86  ldap_get_option(handle, LDAP_OPT_RESULT_CODE, &ldap_errno);
87  REDEBUG("Failed retrieving entry: %s", ldap_err2string(ldap_errno));
88  if (profile_ctx->ret) *profile_ctx->ret = LDAP_RESULT_NO_RESULT;
89  goto finish;
90  }
91 
92  RDEBUG2("Processing profile attributes");
93  RINDENT();
94  if (fr_ldap_map_do(request, profile_ctx->inst->valuepair_attr,
95  profile_ctx->expanded, entry) < 0) {
96  if (profile_ctx->ret) *profile_ctx->ret = LDAP_RESULT_ERROR;
97  }
98 
99  REXDENT();
100 
101 finish:
102  talloc_free(profile_ctx);
104 }
105 
106 /** Cancel an in progress profile lookup
107  *
108  */
109 static void ldap_map_profile_cancel(UNUSED request_t *request, UNUSED fr_signal_t action, void *uctx)
110 {
111  ldap_profile_ctx_t *profile_ctx = talloc_get_type_abort(uctx, ldap_profile_ctx_t);
112 
113  if (!profile_ctx->query || !profile_ctx->query->treq) return;
114 
116 }
117 
118 /** Search for and apply an LDAP profile
119  *
120  * LDAP profiles are mapped using the same attribute map as user objects, they're used to add common
121  * sets of attributes to the request.
122  *
123  * @param[out] ret Where to write the result of the query.
124  * @param[in] inst LDAP module instance.
125  * @param[in] request Current request.
126  * @param[in] ttrunk Trunk connection on which to run LDAP queries.
127  * @param[in] dn of profile object to apply.
128  * @param[in] scope to apply when looking up profiles.
129  * @param[in] filter to apply when looking up profiles.
130  * @param[in] expanded Structure containing a list of xlat
131  * expanded attribute names and mapping information.
132  * @return One of the RLM_MODULE_* values.
133  */
135  rlm_ldap_t const *inst, request_t *request, fr_ldap_thread_trunk_t *ttrunk,
136  char const *dn, int scope, char const *filter, fr_ldap_map_exp_t const *expanded)
137 {
138  ldap_profile_ctx_t *profile_ctx;
139 
140  if (!dn || !*dn) return UNLANG_ACTION_CALCULATE_RESULT;
141 
142  MEM(profile_ctx = talloc(unlang_interpret_frame_talloc_ctx(request), ldap_profile_ctx_t));
143  *profile_ctx = (ldap_profile_ctx_t) {
144  .ret = ret,
145  .dn = dn,
146  .expanded = expanded,
147  .inst = inst
148  };
149  if (ret) *ret = LDAP_RESULT_ERROR;
150 
152  ~FR_SIGNAL_CANCEL, UNLANG_SUB_FRAME, profile_ctx) < 0) {
153  talloc_free(profile_ctx);
154  return UNLANG_ACTION_FAIL;
155  }
156 
157  return fr_ldap_trunk_search(profile_ctx, &profile_ctx->query, request, ttrunk, dn,
158  scope, filter,
159  expanded->attrs, NULL, NULL);
160 }
161 
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
Definition: action.h:35
@ UNLANG_ACTION_FAIL
Encountered an unexpected error.
Definition: action.h:36
@ UNLANG_ACTION_CALCULATE_RESULT
Calculate a new section rlm_rcode_t value.
Definition: action.h:37
#define USES_APPLE_DEPRECATED_API
Definition: build.h:431
#define RCSID(id)
Definition: build.h:444
#define UNUSED
Definition: build.h:313
#define unlang_function_push(_request, _func, _repeat, _signal, _sigmask, _top_frame, _uctx)
Push a generic function onto the unlang stack.
Definition: function.h:111
TALLOC_CTX * unlang_interpret_frame_talloc_ctx(request_t *request)
Get a talloc_ctx which is valid only for this frame.
Definition: interpret.c:1384
#define UNLANG_SUB_FRAME
Definition: interpret.h:36
fr_trunk_request_t * treq
Trunk request this query is associated with.
Definition: base.h:451
LDAP * handle
libldap handle.
Definition: base.h:331
fr_ldap_result_code_t ret
Result code.
Definition: base.h:465
fr_ldap_connection_t * ldap_conn
LDAP connection this query is running on.
Definition: base.h:452
fr_ldap_result_code_t
LDAP query result codes.
Definition: base.h:186
@ LDAP_RESULT_ERROR
A general error occurred.
Definition: base.h:189
@ LDAP_RESULT_SUCCESS
Successfully got LDAP results.
Definition: base.h:188
@ LDAP_RESULT_NO_RESULT
No results returned.
Definition: base.h:192
@ LDAP_RESULT_BAD_DN
The requested DN does not exist.
Definition: base.h:191
LDAPMessage * result
Head of LDAP results list.
Definition: base.h:463
int fr_ldap_map_do(request_t *request, char const *valuepair_attr, fr_ldap_map_exp_t const *expanded, LDAPMessage *entry)
Convert attribute map into valuepairs.
Definition: map.c:323
char const * attrs[LDAP_MAX_ATTRMAP+LDAP_MAP_RESERVED+1]
Reserve some space for access attributes.
Definition: base.h:370
Result of expanding the RHS of a set of maps.
Definition: base.h:368
LDAP query structure.
Definition: base.h:420
Thread LDAP trunk structure.
Definition: base.h:397
unlang_action_t fr_ldap_trunk_search(TALLOC_CTX *ctx, fr_ldap_query_t **out, request_t *request, fr_ldap_thread_trunk_t *ttrunk, char const *base_dn, int scope, char const *filter, char const *const *attrs, LDAPControl **serverctrls, LDAPControl **clientctrls)
Run an async search LDAP query on a trunk connection.
Definition: base.c:694
#define REXDENT()
Exdent (unindent) R* messages by one level.
Definition: log.h:443
#define RINDENT()
Indent R* messages by one level.
Definition: log.h:430
talloc_free(reap)
static unlang_action_t ldap_map_profile_resume(UNUSED rlm_rcode_t *p_result, UNUSED int *priority, request_t *request, void *uctx)
Process the results of a profile lookup.
Definition: profile.c:54
unlang_action_t rlm_ldap_map_profile(fr_ldap_result_code_t *ret, 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)
Search for and apply an LDAP profile.
Definition: profile.c:134
static void ldap_map_profile_cancel(UNUSED request_t *request, UNUSED fr_signal_t action, void *uctx)
Cancel an in progress profile lookup.
Definition: profile.c:109
fr_ldap_result_code_t * ret
Result of the query and applying the map.
Definition: profile.c:44
rlm_ldap_t const * inst
Definition: profile.c:47
char const * dn
Definition: profile.c:46
fr_ldap_map_exp_t const * expanded
Definition: profile.c:48
fr_ldap_query_t * query
Definition: profile.c:45
Holds state of in progress async profile lookups.
Definition: profile.c:43
#define REDEBUG(fmt,...)
Definition: radclient.h:52
#define RDEBUG2(fmt,...)
Definition: radclient.h:54
rlm_rcode_t
Return codes indicating the result of the module call.
Definition: rcode.h:40
char const * valuepair_attr
Generic dynamic mapping attribute, contains a RADIUS attribute and value.
Definition: rlm_ldap.h:99
fr_signal_t
Definition: signal.h:48
fr_assert(0)
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
eap_aka_sim_process_conf_t * inst
void fr_trunk_request_signal_cancel(fr_trunk_request_t *treq)
Cancel a trunk request.
Definition: trunk.c:2047