The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
sasl.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: 59e57d7825882054d1fc8ec22fd83e04b8ce9bf3 $
19 * @file lib/ldap/bind.c
20 * @brief Asynchronous SASL bind functions for LDAP.
21 *
22 * @copyright 2017 Arran Cudbard-Bell (a.cudbardb@freeradius.org)
23 */
24RCSID("$Id: 59e57d7825882054d1fc8ec22fd83e04b8ce9bf3 $")
25
27
28#include <freeradius-devel/ldap/base.h>
29#include <freeradius-devel/util/debug.h>
30#include <sasl/sasl.h>
31
32static void _ldap_sasl_bind_io_write(fr_event_list_t *el, int fd, UNUSED int flags, void *uctx);
33
34/** Error reading from or writing to the file descriptor
35 *
36 * @param[in] el the event occurred in.
37 * @param[in] fd the event occurred on.
38 * @param[in] flags from kevent.
39 * @param[in] fd_errno The error that occurred.
40 * @param[in] uctx Connection config and handle.
41 */
43 UNUSED int flags, UNUSED int fd_errno, void *uctx)
44{
45 fr_ldap_sasl_ctx_t *sasl_ctx = talloc_get_type_abort(uctx, fr_ldap_sasl_ctx_t);
46 fr_ldap_connection_t *c = sasl_ctx->c;
47
48 talloc_free(sasl_ctx);
49 fr_ldap_state_error(c); /* Restart the connection state machine */
50}
51
52/** Callback for fr_ldap_sasl_interactive_bind
53 *
54 * @param[in] handle used for the SASL bind.
55 * @param[in] flags data as provided to fr_ldap_sasl_interactive_bind.
56 * @param[in] uctx Our context data, containing the identity, password, realm and various other things.
57 * @param[in] sasl_callbacks Array of challenges to provide responses for.
58 * @return SASL_OK.
59 */
60static int _sasl_interact(UNUSED LDAP *handle, UNUSED unsigned flags, void *uctx, void *sasl_callbacks)
61{
62 fr_ldap_sasl_ctx_t *sasl_ctx = talloc_get_type_abort(uctx, fr_ldap_sasl_ctx_t);
63 sasl_interact_t *cb = sasl_callbacks;
64 sasl_interact_t *cb_p;
65
66 for (cb_p = cb; cb_p->id != SASL_CB_LIST_END; cb_p++) {
67 DEBUG3("SASL challenge : %s", cb_p->challenge);
68 DEBUG3("SASL prompt : %s", cb_p->prompt);
69
70 switch (cb_p->id) {
71 case SASL_CB_AUTHNAME:
72 /*
73 * For mechs like -Y EXTERNAL we don't have
74 * any information to provide to SASL.
75 */
76 if (!sasl_ctx->identity) {
77 null_result:
78 cb_p->result = NULL;
79 cb_p->len = 0;
80 break;
81 }
82 cb_p->result = sasl_ctx->identity;
83 cb_p->len = strlen(sasl_ctx->identity);
84 break;
85
86 case SASL_CB_PASS:
87 if (!sasl_ctx->password) goto null_result;
88
89 cb_p->result = sasl_ctx->password;
90 cb_p->len = strlen(sasl_ctx->password);
91 break;
92
93 case SASL_CB_USER:
94 if (!sasl_ctx->proxy && !sasl_ctx->identity) goto null_result;
95
96 cb_p->result = sasl_ctx->proxy ? sasl_ctx->proxy : sasl_ctx->identity;
97 cb_p->len = sasl_ctx->proxy ? strlen(sasl_ctx->proxy) : strlen(sasl_ctx->identity);
98 break;
99
100 case SASL_CB_GETREALM:
101 if (!sasl_ctx->realm) goto null_result;
102
103 cb_p->result = sasl_ctx->realm;
104 cb_p->len = strlen(sasl_ctx->realm);
105 break;
106
107 default:
108 break;
109 }
110 DEBUG3("SASL result : %s", cb_p->result ? (char const *)cb_p->result : "");
111 }
112 return SASL_OK;
113}
114
115/** Parse a sasl bind response from a server
116 *
117 * @param[in] el the event occurred in.
118 * @param[in] fd the event occurred on.
119 * @param[in] flags from kevent.
120 * @param[in] uctx bind_ctx containing credentials, and connection config/handle.
121 */
122static void _ldap_sasl_bind_io_read(fr_event_list_t *el, int fd, UNUSED int flags, void *uctx)
123{
124 fr_ldap_sasl_ctx_t *sasl_ctx = talloc_get_type_abort(uctx, fr_ldap_sasl_ctx_t);
125 fr_ldap_connection_t *c = sasl_ctx->c;
126 fr_ldap_rcode_t status;
127
128 /*
129 * Free the old result (if there is one)
130 */
131 if (sasl_ctx->result) {
132 ldap_msgfree(sasl_ctx->result);
133 sasl_ctx->result = NULL;
134 }
135
136 /*
137 * If LDAP parse result indicates there was an error
138 * then we're done.
139 */
140 status = fr_ldap_result(&sasl_ctx->result, NULL, c, sasl_ctx->msgid, LDAP_MSG_ALL,
141 sasl_ctx->identity, fr_time_delta_wrap(0));
142 switch (status) {
145 {
146 struct berval *srv_cred;
147 int ret;
148
149 ret = ldap_parse_sasl_bind_result(c->handle, sasl_ctx->result, &srv_cred, 0);
150 if (ret != LDAP_SUCCESS) {
151 ERROR("SASL decode failed (bind failed): %s", ldap_err2string(ret));
152 error:
153 talloc_free(sasl_ctx);
154 fr_ldap_state_error(c); /* Restart the connection state machine */
155 return;
156 }
157
158 /*
159 * Observed as NULL when doing EXTERNAL
160 * authentication.
161 */
162 if (srv_cred) {
163 DEBUG3("SASL response : %pV",
164 fr_box_strvalue_len(srv_cred->bv_val, srv_cred->bv_len));
165 ber_bvfree(srv_cred);
166 }
167
168 /*
169 * If we need to continue, wait until the
170 * socket is writable, and then call
171 * ldap_sasl_interactive_bind again.
172 *
173 * sasl_ctx->rmech may be NULL if there's
174 * nothing else to do.
175 */
176 if (sasl_ctx->rmech) DEBUG3("Continuing SASL mech %s...", sasl_ctx->rmech);
177
178 ret = fr_event_fd_insert(sasl_ctx, NULL, el, fd,
179 NULL,
180 _ldap_sasl_bind_io_write, /* Need to write more SASL stuff */
182 sasl_ctx);
183 if (!fr_cond_assert(ret == 0)) goto error;
184 }
185 return;
186
187 default:
188 PERROR("SASL bind failed");
189 goto error;
190 }
191}
192
193/** Progress an interactive SASL bind
194 *
195 * @param[in] el the event occurred in.
196 * @param[in] fd the event occurred on.
197 * @param[in] flags from kevent.
198 * @param[in] uctx Connection config and handle.
199 */
200static void _ldap_sasl_bind_io_write(fr_event_list_t *el, int fd, UNUSED int flags, void *uctx)
201{
202 fr_ldap_sasl_ctx_t *sasl_ctx = talloc_get_type_abort(uctx, fr_ldap_sasl_ctx_t);
203 fr_ldap_connection_t *c = sasl_ctx->c;
204
205 int ret = 0;
206
207 LDAPControl *our_serverctrls[LDAP_MAX_CONTROLS];
208 LDAPControl *our_clientctrls[LDAP_MAX_CONTROLS];
209
210 fr_ldap_control_merge(our_serverctrls, our_clientctrls,
211 NUM_ELEMENTS(our_serverctrls),
212 NUM_ELEMENTS(our_clientctrls),
213 c, sasl_ctx->serverctrls, sasl_ctx->clientctrls);
214
215 DEBUG2("%s SASL mech(s): %s", (sasl_ctx->result == NULL ? "Starting" : "Continuing"), sasl_ctx->mechs);
216
217 ret = ldap_sasl_interactive_bind(c->handle, NULL, sasl_ctx->mechs,
218 our_serverctrls, our_clientctrls,
219 LDAP_SASL_AUTOMATIC,
220 _sasl_interact, sasl_ctx, sasl_ctx->result,
221 &sasl_ctx->rmech, &sasl_ctx->msgid);
223 switch (ret) {
224 /*
225 * If the handle was not connected, this operation
226 * can return either LDAP_X_CONNECTING or
227 * LDAP_SASL_BIND_IN_PROGRESS
228 * depending on how fast the connection came up
229 * and whether it was connectionless.
230 */
231 case LDAP_X_CONNECTING:
232 ret = ldap_get_option(c->handle, LDAP_OPT_DESC, &fd);
233 if (!fr_cond_assert(ret == LDAP_OPT_SUCCESS)) {
234 error:
235 talloc_free(sasl_ctx);
237 fr_ldap_state_error(c); /* Restart the connection state machine */
238 return;
239 }
240
241 ret = fr_event_fd_insert(sasl_ctx, NULL, el, fd,
242 NULL,
243 _ldap_sasl_bind_io_write, /* We'll be called again when the conn is open */
245 sasl_ctx);
246 if (!fr_cond_assert(ret == 0)) goto error;
247 break;
248
249 /*
250 * Want to read more SASL stuff...
251 */
252 case LDAP_SASL_BIND_IN_PROGRESS:
253 if (fd < 0) {
254 ret = ldap_get_option(c->handle, LDAP_OPT_DESC, &fd);
255 if ((ret != LDAP_OPT_SUCCESS) || (fd < 0)) goto error;
256 }
257 c->fd = fd;
258 ret = fr_event_fd_insert(sasl_ctx, NULL, el, fd,
260 NULL,
262 sasl_ctx);
263 if (!fr_cond_assert(ret == 0)) goto error;
264 break;
265
266 /*
267 * We're done, woohoo!
268 */
269 case LDAP_SUCCESS:
270 DEBUG2("SASL bind as \"%s\" to \"%s\" successful",
271 sasl_ctx->identity ? sasl_ctx->identity : "(anonymous)", c->config->server);
272 talloc_free(sasl_ctx);
274 break;
275
276 default:
277 ERROR("ldap sasl bind failed: %s", ldap_err2string(ret));
278 goto error;
279 }
280}
281
282/** Ensure any outstanding messages are freed
283 *
284 * @param[in] sasl_ctx to free.
285 * @return 0;
286 */
288{
289 if (sasl_ctx->result) ldap_msgfree(sasl_ctx->result);
290
291 return 0;
292}
293
294/** Install I/O handlers for the bind operation
295 *
296 * @param[in] c connection to StartTLS on.
297 * @param[in] mechs Space delimited list of sasl mechs to try.
298 * @param[in] identity SASL identity to bind with.
299 * @param[in] password Password credential to pass to SASL.
300 * @param[in] proxy identity. May be NULL.
301 * @param[in] realm SASL realm.
302 * @param[in] serverctrls Extra controls to pass to the server.
303 * @param[in] clientctrls Extra controls to pass to libldap.
304 * @return
305 * - 0 on success.
306 * - -1 on failure.
307 */
309 char const *mechs,
310 char const *identity,
311 char const *password,
312 char const *proxy,
313 char const *realm,
314 LDAPControl **serverctrls, LDAPControl **clientctrls)
315{
316 int fd = -1;
317 fr_ldap_sasl_ctx_t *sasl_ctx;
319
320 DEBUG2("Starting SASL bind operation");
321
322 MEM(sasl_ctx = talloc_zero(c, fr_ldap_sasl_ctx_t));
323 talloc_set_destructor(sasl_ctx, _sasl_ctx_free);
324
325 sasl_ctx->c = c;
326 sasl_ctx->mechs = mechs;
327 sasl_ctx->identity = identity;
328 sasl_ctx->password = password;
329 sasl_ctx->proxy = proxy;
330 sasl_ctx->realm = realm;
331 sasl_ctx->serverctrls = serverctrls;
332 sasl_ctx->clientctrls = clientctrls;
333
334 el = c->conn->el;
335
336 /*
337 * ldap_get_option can return LDAP_SUCCESS even if the fd is not yet available
338 * - hence the test for fd >= 0
339 */
340 if ((ldap_get_option(c->handle, LDAP_OPT_DESC, &fd) == LDAP_SUCCESS) && (fd >= 0)){
341 int ret;
342
343 ret = fr_event_fd_insert(sasl_ctx, NULL, el, fd,
344 NULL,
347 sasl_ctx);
348 if (!fr_cond_assert(ret == 0)) {
349 talloc_free(sasl_ctx);
350 return -1;
351 }
352 } else {
353 _ldap_sasl_bind_io_write(el, -1, 0, sasl_ctx);
354 }
355
356 return 0;
357}
358
359/** Send a SASL LDAP auth bind
360 *
361 * Shares the same callback as SASL admin binds
362 *
363 * @param[in] sasl_ctx containing SASL parameters / state for the bind.
364 * @param[out] msgid where to write the LDAP message ID.
365 * @param[in] ldap_conn on which the message should be sent.
366 */
368 fr_ldap_connection_t *ldap_conn)
369{
370 return ldap_sasl_interactive_bind(ldap_conn->handle, NULL, sasl_ctx->mechs,
371 NULL, NULL, LDAP_SASL_AUTOMATIC,
372 _sasl_interact, sasl_ctx, sasl_ctx->result,
373 &sasl_ctx->rmech, msgid);
374}
375
376/** Yield interpreter after enqueueing sasl auth bind
377 *
378 */
380 UNUSED request_t *request, UNUSED void *uctx)
381{
382 return UNLANG_ACTION_YIELD;
383}
384
385/** Signal an outstanding SASL LDAP bind to cancel
386 *
387 * @param[in] request being processed. Unused.
388 * @param[in] action Signal to handle.
389 * @param[in] uctx bind auth ctx.
390 */
391static void ldap_async_sasl_bind_auth_cancel(request_t *request, UNUSED fr_signal_t action, void *uctx)
392{
393 fr_ldap_bind_auth_ctx_t *bind_auth_ctx = talloc_get_type_abort(uctx, fr_ldap_bind_auth_ctx_t);
394
395 RWARN("Cancelling SASL bind auth");
396 if (bind_auth_ctx->msgid > 0) fr_rb_remove(bind_auth_ctx->thread->binds, bind_auth_ctx);
397 trunk_request_signal_cancel(bind_auth_ctx->treq);
398}
399
400/** Handle the return code from parsed LDAP results to set the module rcode
401 *
402 * @param[out] p_result Where to write return code.
403 * @param[in] priority Unused.
404 * @param[in] request being processed.
405 * @param[in] uctx bind auth ctx.
406 * @return unlang action.
407 */
408static unlang_action_t ldap_async_sasl_bind_auth_results(rlm_rcode_t *p_result, UNUSED int *priority, request_t *request, void *uctx)
409{
410 fr_ldap_bind_auth_ctx_t *bind_auth_ctx = talloc_get_type_abort(uctx, fr_ldap_bind_auth_ctx_t);
411 fr_ldap_sasl_ctx_t *sasl_ctx = bind_auth_ctx->sasl_ctx;
412 fr_ldap_rcode_t ret = bind_auth_ctx->ret;
413 fr_ldap_connection_t *ldap_conn = NULL;
414
415 switch (bind_auth_ctx->ret) {
417 RDEBUG2("Bind as user \"%s\" was successful", sasl_ctx->identity);
418 break;
419
421 RDEBUG2("Bind as user \"%s\" not permitted", sasl_ctx->identity);
422 break;
423
424 case LDAP_PROC_REJECT:
425 RDEBUG2("Bind as user \"%s\" rejected", sasl_ctx->identity);
426 break;
427
429 if (trunk_request_requeue(bind_auth_ctx->treq) != TRUNK_ENQUEUE_OK) {
430 ret = LDAP_PROC_ERROR;
431 break;
432 }
433
434 /*
435 * Once the next SASL exchange has completed repeat this function to
436 * process the results
437 */
439 /*
440 * Not strictly an LDAP error but if this happens we will want to reset
441 * the connection to get a known state.
442 */
443 ret = LDAP_PROC_ERROR;
444 break;
445 }
446 return UNLANG_ACTION_YIELD;
447
448 default:
449 break;
450 }
451
452 if (bind_auth_ctx->treq) {
453 if (bind_auth_ctx->treq->tconn) ldap_conn = talloc_get_type_abort(bind_auth_ctx->treq->tconn->conn->h,
455 /*
456 * Will free bind_auth_ctx
457 */
458 trunk_request_signal_complete(bind_auth_ctx->treq);
459 } else {
460 /*
461 * If there is no trunk request, the request failed, and we need to free the ctx
462 */
463 talloc_free(bind_auth_ctx);
464 }
465
466 switch (ret) {
469
472
473 case LDAP_PROC_REJECT:
475
476 case LDAP_PROC_BAD_DN:
478
481
482 default:
483 if (ldap_conn) {
484 RPERROR("LDAP connection returned an error - restarting the connection");
485 fr_ldap_state_error(ldap_conn);
486 }
488 }
489}
490
491/** Initiate an async SASL LDAP bind for authentication
492 *
493 * @param[in] request this bind relates to.
494 * @param[in] thread whose connection the bind should be performed on.
495 * @param[in] mechs SASL mechanisms to use.
496 * @param[in] identity Identity to bind with.
497 * @param[in] password Password to bind with.
498 * @param[in] proxy Identity to proxy.
499 * @param[in] realm SASL realm if applicable.
500 * @return
501 * - 0 on success.
502 * - -1 on failure.
503*/
505 char const *identity, char const *password, char const *proxy, char const *realm)
506{
507 fr_ldap_bind_auth_ctx_t *bind_auth_ctx;
508 trunk_request_t *treq;
510 trunk_enqueue_t ret;
511
512 if (!ttrunk) {
513 ERROR("Failed to get trunk connection for LDAP bind");
514 return UNLANG_ACTION_FAIL;
515 }
516
517 treq = trunk_request_alloc(ttrunk->trunk, request);
518 if (!treq) {
519 ERROR("Failed to allocate trunk request for LDAP bind");
520 return UNLANG_ACTION_FAIL;
521 }
522
523 MEM(bind_auth_ctx = talloc_zero(treq, fr_ldap_bind_auth_ctx_t));
524 *bind_auth_ctx = (fr_ldap_bind_auth_ctx_t) {
525 .treq = treq,
526 .request = request,
527 .thread = thread,
528 .ret = LDAP_PROC_NO_RESULT,
529 .type = LDAP_BIND_SASL
530 };
531
532 MEM(bind_auth_ctx->sasl_ctx = talloc(bind_auth_ctx, fr_ldap_sasl_ctx_t));
533 talloc_set_destructor(bind_auth_ctx->sasl_ctx, _sasl_ctx_free);
534 *bind_auth_ctx->sasl_ctx = (fr_ldap_sasl_ctx_t) {
535 .mechs = mechs,
536 .identity = identity,
537 .password = password,
538 .proxy = proxy,
539 .realm = realm,
540 };
541
542 ret = trunk_request_enqueue(&bind_auth_ctx->treq, ttrunk->trunk, request, bind_auth_ctx, NULL);
543
544 switch (ret) {
545 case TRUNK_ENQUEUE_OK:
547 break;
548
549 default:
550 ERROR("Failed to enqueue bind request");
551 trunk_request_free(&treq);
552 return UNLANG_ACTION_FAIL;
553 }
554
555 return unlang_function_push(request,
560 bind_auth_ctx);
561}
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_YIELD
Temporarily pause execution until an event occurs.
Definition action.h:42
#define USES_APPLE_DEPRECATED_API
Definition build.h:470
#define RCSID(id)
Definition build.h:483
#define UNUSED
Definition build.h:315
#define NUM_ELEMENTS(_t)
Definition build.h:337
#define fr_cond_assert(_x)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
Definition debug.h:139
#define MEM(x)
Definition debug.h:36
#define ERROR(fmt,...)
Definition dhcpclient.c:41
#define fr_event_fd_insert(...)
Definition event.h:232
#define unlang_function_repeat_set(_request, _repeat)
Set a new repeat function for an existing function frame.
Definition function.h:89
#define unlang_function_push(_request, _func, _repeat, _signal, _sigmask, _top_frame, _uctx)
Push a generic function onto the unlang stack.
Definition function.h:111
#define UNLANG_SUB_FRAME
Definition interpret.h:36
char const * proxy
Proxy identity, may be NULL in which case identity is used.
Definition base.h:511
fr_ldap_rcode_t ret
Return code of bind operation.
Definition base.h:624
int msgid
libldap msgid for this bind.
Definition base.h:617
char * server
Initial server to bind to.
Definition base.h:224
LDAP * handle
libldap handle.
Definition base.h:333
void fr_ldap_control_merge(LDAPControl *serverctrls_out[], LDAPControl *clientctrls_out[], size_t serverctrls_len, size_t clientctrls_len, fr_ldap_connection_t *conn, LDAPControl *serverctrls_in[], LDAPControl *clientctrls_in[])
Merge connection and call specific client and server controls.
Definition control.c:48
char const * identity
of the user.
Definition base.h:509
int fd
File descriptor for this connection.
Definition base.h:349
void fr_ldap_state_error(fr_ldap_connection_t *c)
Signal that there's been an error on the connection.
Definition state.c:134
LDAPMessage * result
Previous result.
Definition base.h:517
fr_ldap_config_t const * config
rlm_ldap connection configuration.
Definition base.h:344
fr_ldap_connection_t * c
to bind. Only used when binding as admin user.
Definition base.h:507
LDAPControl ** clientctrls
Controls to pass to the client (library).
Definition base.h:514
trunk_request_t * treq
Trunk request this bind is associated with.
Definition base.h:616
char const * realm
SASL realm (may be NULL).
Definition base.h:512
char const * mechs
SASL mechanisms to run.
Definition base.h:508
char const * password
of the user, may be NULL if no password is specified.
Definition base.h:510
fr_ldap_state_t fr_ldap_state_next(fr_ldap_connection_t *c)
Move between LDAP connection states.
Definition state.c:49
fr_ldap_thread_trunk_t * fr_thread_ldap_bind_trunk_get(fr_ldap_thread_t *thread)
Find the thread specific trunk to use for LDAP bind auths.
int msgid
Last msgid. Only used when binding as admin user.
Definition base.h:516
#define LDAP_MAX_CONTROLS
Maximum number of client/server controls.
Definition base.h:94
char const * rmech
Mech we're continuing with.
Definition base.h:518
LDAPControl ** serverctrls
Controls to pass to the server.
Definition base.h:513
int fr_ldap_connection_timeout_reset(fr_ldap_connection_t const *conn)
Definition connection.c:431
trunk_t * trunk
Connection trunk.
Definition base.h:405
fr_ldap_thread_t * thread
This bind is being run by.
Definition base.h:615
connection_t * conn
Connection state handle.
Definition base.h:345
fr_rb_tree_t * binds
Tree of outstanding bind auths.
Definition base.h:388
fr_ldap_rcode_t
Codes returned by fr_ldap internal functions.
Definition base.h:582
@ LDAP_PROC_CONTINUE
Operation is in progress.
Definition base.h:584
@ LDAP_PROC_SUCCESS
Operation was successful.
Definition base.h:585
@ LDAP_PROC_ERROR
Unrecoverable library/server error.
Definition base.h:587
@ LDAP_PROC_NOT_PERMITTED
Operation was not permitted, either current user was locked out in the case of binds,...
Definition base.h:592
@ LDAP_PROC_REJECT
Bind failed, user was rejected.
Definition base.h:596
@ LDAP_PROC_BAD_DN
Specified an invalid object in a bind or search DN.
Definition base.h:598
@ LDAP_PROC_NO_RESULT
Got no results.
Definition base.h:600
Holds arguments for async bind auth requests.
Definition base.h:613
Tracks the state of a libldap connection handle.
Definition base.h:332
Holds arguments for the async SASL bind operation.
Definition base.h:506
Thread specific structure to manage LDAP trunk connections.
Definition base.h:381
Thread LDAP trunk structure.
Definition base.h:399
fr_ldap_rcode_t fr_ldap_result(LDAPMessage **result, LDAPControl ***ctrls, fr_ldap_connection_t const *conn, int msgid, int all, char const *dn, fr_time_delta_t timeout)
Parse response from LDAP server dealing with any errors.
Definition base.c:450
#define PERROR(_fmt,...)
Definition log.h:228
#define DEBUG3(_fmt,...)
Definition log.h:266
#define RWARN(fmt,...)
Definition log.h:297
#define RPERROR(fmt,...)
Definition log.h:302
talloc_free(reap)
Stores all information relating to an event list.
Definition event.c:411
#define RDEBUG2(fmt,...)
Definition radclient.h:54
#define DEBUG2(fmt,...)
Definition radclient.h:43
void * fr_rb_remove(fr_rb_tree_t *tree, void const *data)
Remove an entry from the tree, without freeing the data.
Definition rb.c:695
#define RETURN_MODULE_REJECT
Definition rcode.h:55
#define RETURN_MODULE_INVALID
Definition rcode.h:59
#define RETURN_MODULE_OK
Definition rcode.h:57
#define RETURN_MODULE_FAIL
Definition rcode.h:56
#define RETURN_MODULE_DISALLOW
Definition rcode.h:60
rlm_rcode_t
Return codes indicating the result of the module call.
Definition rcode.h:40
#define RETURN_MODULE_NOTFOUND
Definition rcode.h:61
static USES_APPLE_DEPRECATED_API void _ldap_sasl_bind_io_write(fr_event_list_t *el, int fd, UNUSED int flags, void *uctx)
Progress an interactive SASL bind.
Definition sasl.c:200
static void ldap_async_sasl_bind_auth_cancel(request_t *request, UNUSED fr_signal_t action, void *uctx)
Signal an outstanding SASL LDAP bind to cancel.
Definition sasl.c:391
static void _ldap_sasl_bind_io_error(UNUSED fr_event_list_t *el, UNUSED int fd, UNUSED int flags, UNUSED int fd_errno, void *uctx)
Error reading from or writing to the file descriptor.
Definition sasl.c:42
static void _ldap_sasl_bind_io_read(fr_event_list_t *el, int fd, UNUSED int flags, void *uctx)
Parse a sasl bind response from a server.
Definition sasl.c:122
static int _sasl_interact(UNUSED LDAP *handle, UNUSED unsigned flags, void *uctx, void *sasl_callbacks)
Callback for fr_ldap_sasl_interactive_bind.
Definition sasl.c:60
unlang_action_t fr_ldap_sasl_bind_auth_async(request_t *request, fr_ldap_thread_t *thread, char const *mechs, char const *identity, char const *password, char const *proxy, char const *realm)
Initiate an async SASL LDAP bind for authentication.
Definition sasl.c:504
static unlang_action_t ldap_async_sasl_bind_auth_results(rlm_rcode_t *p_result, UNUSED int *priority, request_t *request, void *uctx)
Handle the return code from parsed LDAP results to set the module rcode.
Definition sasl.c:408
int fr_ldap_sasl_bind_async(fr_ldap_connection_t *c, char const *mechs, char const *identity, char const *password, char const *proxy, char const *realm, LDAPControl **serverctrls, LDAPControl **clientctrls)
Install I/O handlers for the bind operation.
Definition sasl.c:308
static int _sasl_ctx_free(fr_ldap_sasl_ctx_t *sasl_ctx)
Ensure any outstanding messages are freed.
Definition sasl.c:287
int fr_ldap_sasl_bind_auth_send(fr_ldap_sasl_ctx_t *sasl_ctx, int *msgid, fr_ldap_connection_t *ldap_conn)
Send a SASL LDAP auth bind.
Definition sasl.c:367
static unlang_action_t ldap_async_sasl_bind_auth_start(UNUSED rlm_rcode_t *p_result, UNUSED int *priority, UNUSED request_t *request, UNUSED void *uctx)
Yield interpreter after enqueueing sasl auth bind.
Definition sasl.c:379
fr_signal_t
Signals that can be generated/processed by request signal handlers.
Definition signal.h:38
@ FR_SIGNAL_CANCEL
Request has been cancelled.
Definition signal.h:40
#define fr_time_delta_wrap(_time)
Definition time.h:152
trunk_request_t * trunk_request_alloc(trunk_t *trunk, request_t *request)
(Pre-)Allocate a new trunk request
Definition trunk.c:2474
trunk_enqueue_t trunk_request_enqueue(trunk_request_t **treq_out, trunk_t *trunk, request_t *request, void *preq, void *rctx)
Enqueue a request that needs data written to the trunk.
Definition trunk.c:2587
trunk_enqueue_t trunk_request_requeue(trunk_request_t *treq)
Re-enqueue a request on the same connection.
Definition trunk.c:2676
void trunk_request_signal_cancel(trunk_request_t *treq)
Cancel a trunk request.
Definition trunk.c:2152
void trunk_request_free(trunk_request_t **treq_to_free)
If the trunk request is freed then update the target requests.
Definition trunk.c:2322
void trunk_request_signal_complete(trunk_request_t *treq)
Signal that a trunk request is complete.
Definition trunk.c:2094
Wraps a normal request.
Definition trunk.c:100
trunk_enqueue_t
Definition trunk.h:148
@ TRUNK_ENQUEUE_OK
Operation was successful.
Definition trunk.h:150
@ TRUNK_ENQUEUE_IN_BACKLOG
Request should be enqueued in backlog.
Definition trunk.h:149
static fr_event_list_t * el
#define fr_box_strvalue_len(_val, _len)
Definition value.h:286