24RCSID(
"$Id: af6a20e033e982214a89350cfe908f5c47474cab $")
 
   28#include <freeradius-devel/ldap/base.h> 
   29#include <freeradius-devel/util/debug.h> 
   63        sasl_interact_t                 *cb = sasl_callbacks;
 
   64        sasl_interact_t                 *cb_p;
 
   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);
 
   71                case SASL_CB_AUTHNAME:
 
   83                        cb_p->len = strlen(sasl_ctx->
identity);
 
   87                        if (!sasl_ctx->
password) 
goto null_result;
 
   90                        cb_p->len = strlen(sasl_ctx->
password);
 
   94                        if (!sasl_ctx->
proxy && !sasl_ctx->
identity) 
goto null_result;
 
  100                case SASL_CB_GETREALM:
 
  101                        if (!sasl_ctx->
realm) 
goto null_result;
 
  103                        cb_p->result = sasl_ctx->
realm;
 
  104                        cb_p->len = strlen(sasl_ctx->
realm);
 
  110                DEBUG3(
"SASL result    : %s", cb_p->result ? (
char const *)cb_p->result : 
"");
 
 
  132                ldap_msgfree(sasl_ctx->
result);
 
  146                struct berval                   *srv_cred;
 
  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));
 
  163                        DEBUG3(
"SASL response  : %pV",
 
  165                        ber_bvfree(srv_cred);
 
  188                PERROR(
"SASL bind failed");
 
 
  215        DEBUG2(
"%s SASL mech(s): %s", (sasl_ctx->
result == NULL ? 
"Starting" : 
"Continuing"), sasl_ctx->
mechs);
 
  217        ret = ldap_sasl_interactive_bind(c->
handle, NULL, sasl_ctx->
mechs,
 
  218                                         our_serverctrls, our_clientctrls,
 
  231        case LDAP_X_CONNECTING:
 
  232                ret = ldap_get_option(c->
handle, LDAP_OPT_DESC, &fd);
 
  252        case LDAP_SASL_BIND_IN_PROGRESS:
 
  254                        ret = ldap_get_option(c->
handle, LDAP_OPT_DESC, &fd);
 
  255                        if ((ret != LDAP_OPT_SUCCESS) || (fd < 0)) 
goto error;
 
  270                DEBUG2(
"SASL bind as \"%s\" to \"%s\" successful",
 
  277                ERROR(
"ldap sasl bind failed: %s", ldap_err2string(ret));
 
 
  310                            char const *identity,
 
  311                            char const *password,
 
  314                            LDAPControl **serverctrls, LDAPControl **clientctrls)
 
  320        DEBUG2(
"Starting SASL bind operation");
 
  326        sasl_ctx->
mechs = mechs;
 
  329        sasl_ctx->
proxy = proxy;
 
  330        sasl_ctx->
realm = realm;
 
  340        if ((ldap_get_option(c->
handle, LDAP_OPT_DESC, &fd) == LDAP_SUCCESS) && (fd >= 0)){
 
 
  370        return ldap_sasl_interactive_bind(ldap_conn->
handle, NULL, sasl_ctx->
mechs,
 
  371                                          NULL, NULL, LDAP_SASL_AUTOMATIC,
 
  373                                          &sasl_ctx->
rmech, msgid);
 
 
  395        RWARN(
"Cancelling SASL bind auth");
 
 
  414        switch (bind_auth_ctx->
ret) {
 
  451        if (bind_auth_ctx->
treq) {
 
  452                if (bind_auth_ctx->
treq->tconn) ldap_conn = talloc_get_type_abort(bind_auth_ctx->
treq->tconn->conn->h,
 
  483                        RPERROR(
"LDAP connection returned an error - restarting the connection");
 
 
  506                                             char const *identity, 
char const *password, 
char const *proxy, 
char const *realm)
 
  514                ERROR(
"Failed to get trunk connection for LDAP bind");
 
  520                ERROR(
"Failed to allocate trunk request for LDAP bind");
 
  530                .type = LDAP_BIND_SASL
 
  537                .identity = identity,
 
  538                .password = password,
 
  551                ERROR(
"Failed to enqueue bind request");
 
 
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
@ UNLANG_ACTION_FAIL
Encountered an unexpected error.
@ UNLANG_ACTION_YIELD
Temporarily pause execution until an event occurs.
#define USES_APPLE_DEPRECATED_API
#define fr_cond_assert(_x)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
#define fr_event_fd_insert(...)
#define unlang_function_push_with_result(_result_p, _request, _func, _repeat, _signal, _sigmask, _top_frame, _uctx)
Push a generic function onto the unlang stack that produces a result.
#define unlang_function_repeat_set(_request, _repeat)
Set a new repeat function for an existing function frame.
char const  * proxy
Proxy identity, may be NULL in which case identity is used.
fr_ldap_rcode_t ret
Return code of bind operation.
int msgid
libldap msgid for this bind.
char * server
Initial server to bind to.
LDAP * handle
libldap handle.
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.
char const  * identity
of the user.
int fd
File descriptor for this connection.
void fr_ldap_state_error(fr_ldap_connection_t *c)
Signal that there's been an error on the connection.
LDAPMessage * result
Previous result.
fr_ldap_config_t const  * config
rlm_ldap connection configuration.
fr_ldap_connection_t * c
to bind. Only used when binding as admin user.
LDAPControl ** clientctrls
Controls to pass to the client (library).
trunk_request_t * treq
Trunk request this bind is associated with.
char const  * realm
SASL realm (may be NULL).
char const  * mechs
SASL mechanisms to run.
char const  * password
of the user, may be NULL if no password is specified.
fr_ldap_state_t fr_ldap_state_next(fr_ldap_connection_t *c)
Move between LDAP connection states.
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.
#define LDAP_MAX_CONTROLS
Maximum number of client/server controls.
char const  * rmech
Mech we're continuing with.
LDAPControl ** serverctrls
Controls to pass to the server.
int fr_ldap_connection_timeout_reset(fr_ldap_connection_t const *conn)
trunk_t * trunk
Connection trunk.
fr_ldap_thread_t * thread
This bind is being run by.
connection_t * conn
Connection state handle.
fr_rb_tree_t * binds
Tree of outstanding bind auths.
fr_ldap_rcode_t
Codes returned by fr_ldap internal functions.
@ LDAP_PROC_CONTINUE
Operation is in progress.
@ LDAP_PROC_SUCCESS
Operation was successful.
@ LDAP_PROC_ERROR
Unrecoverable library/server error.
@ LDAP_PROC_NOT_PERMITTED
Operation was not permitted, either current user was locked out in the case of binds,...
@ LDAP_PROC_REJECT
Bind failed, user was rejected.
@ LDAP_PROC_BAD_DN
Specified an invalid object in a bind or search DN.
@ LDAP_PROC_NO_RESULT
Got no results.
Holds arguments for async bind auth requests.
Tracks the state of a libldap connection handle.
Holds arguments for the async SASL bind operation.
Thread specific structure to manage LDAP trunk connections.
Thread LDAP trunk structure.
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.
Stores all information relating to an event list.
void * fr_rb_remove(fr_rb_tree_t *tree, void const *data)
Remove an entry from the tree, without freeing the data.
#define RETURN_UNLANG_DISALLOW
#define RETURN_UNLANG_INVALID
#define RETURN_UNLANG_NOTFOUND
#define RETURN_UNLANG_FAIL
#define RETURN_UNLANG_REJECT
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.
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.
unlang_action_t fr_ldap_sasl_bind_auth_async(unlang_result_t *p_result, 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.
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.
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.
static int _sasl_interact(UNUSED LDAP *handle, UNUSED unsigned flags, void *uctx, void *sasl_callbacks)
Callback for fr_ldap_sasl_interactive_bind.
static unlang_action_t ldap_async_sasl_bind_auth_results(unlang_result_t *p_result, request_t *request, void *uctx)
Handle the return code from parsed LDAP results to set the module rcode.
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.
static int _sasl_ctx_free(fr_ldap_sasl_ctx_t *sasl_ctx)
Ensure any outstanding messages are freed.
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.
static unlang_action_t ldap_async_sasl_bind_auth_start(UNUSED unlang_result_t *p_result, UNUSED request_t *request, UNUSED void *uctx)
Yield interpreter after enqueueing sasl auth bind.
fr_signal_t
Signals that can be generated/processed by request signal handlers.
@ FR_SIGNAL_CANCEL
Request has been cancelled.
#define fr_time_delta_wrap(_time)
trunk_request_t * trunk_request_alloc(trunk_t *trunk, request_t *request)
(Pre-)Allocate a new trunk request
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.
trunk_enqueue_t trunk_request_requeue(trunk_request_t *treq)
Re-enqueue a request on the same connection.
void trunk_request_signal_cancel(trunk_request_t *treq)
Cancel a trunk request.
void trunk_request_free(trunk_request_t **treq_to_free)
If the trunk request is freed then update the target requests.
void trunk_request_signal_complete(trunk_request_t *treq)
Signal that a trunk request is complete.
@ TRUNK_ENQUEUE_OK
Operation was successful.
@ TRUNK_ENQUEUE_IN_BACKLOG
Request should be enqueued in backlog.
static fr_event_list_t * el
#define fr_box_strvalue_len(_val, _len)