The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Macros | Functions | Variables
connection.c File Reference

Asynchronous connection management functions for LDAP. More...

#include <freeradius-devel/ldap/base.h>
#include <freeradius-devel/util/debug.h>
+ Include dependency graph for connection.c:

Go to the source code of this file.

Macros

#define do_ldap_option(_option, _name, _value)
 
#define maybe_ldap_option(_option, _name, _value)    if (_value) do_ldap_option(_option, _name, _value)
 
#define POPULATE_LDAP_CONTROLS(_dest, _src)
 

Functions

static void _ldap_connection_close (fr_event_list_t *el, void *h, UNUSED void *uctx)
 Free the handle, closing the connection to ldap. More...
 
static void _ldap_connection_close_watch (connection_t *conn, UNUSED connection_state_t prev, UNUSED connection_state_t state, void *uctx)
 Watcher for LDAP connections being closed. More...
 
static int _ldap_connection_free (fr_ldap_connection_t *c)
 Close and delete a connection. More...
 
static void _ldap_trunk_idle_timeout (fr_event_list_t *el, UNUSED fr_time_t now, void *uctx)
 Callback for closing idle LDAP trunk. More...
 
static int _thread_ldap_trunk_free (fr_ldap_thread_trunk_t *ttrunk)
 
 CC_NO_UBSAN (function)
 (Re-)Initialises the libldap side of the connection handle More...
 
fr_ldap_connection_tfr_ldap_connection_alloc (TALLOC_CTX *ctx)
 Allocate our ldap connection handle layer. More...
 
int fr_ldap_connection_configure (fr_ldap_connection_t *c, fr_ldap_config_t const *config)
 Allocate and configure a new connection. More...
 
connection_tfr_ldap_connection_state_alloc (TALLOC_CTX *ctx, fr_event_list_t *el, fr_ldap_config_t const *config, char const *log_prefix)
 Alloc a self re-establishing connection to an LDAP server. More...
 
int fr_ldap_connection_timeout_reset (fr_ldap_connection_t const *c)
 
int fr_ldap_connection_timeout_set (fr_ldap_connection_t const *c, fr_time_delta_t timeout)
 
fr_ldap_thread_trunk_tfr_thread_ldap_bind_trunk_get (fr_ldap_thread_t *thread)
 Find the thread specific trunk to use for LDAP bind auths. More...
 
fr_ldap_thread_trunk_tfr_thread_ldap_trunk_get (fr_ldap_thread_t *thread, char const *uri, char const *bind_dn, char const *bind_password, request_t *request, fr_ldap_config_t const *config)
 Find a thread specific LDAP connection for a specific URI / bind DN. More...
 
trunk_state_t fr_thread_ldap_trunk_state (fr_ldap_thread_t *thread, char const *uri, char const *bind_dn)
 Lookup the state of a thread specific LDAP connection trunk for a specific URI / bind DN. More...
 
static void ldap_request_cancel (UNUSED connection_t *conn, void *preq, UNUSED trunk_cancel_reason_t reason, UNUSED void *uctx)
 Callback when an LDAP trunk request is cancelled. More...
 
static void ldap_request_fail (request_t *request, void *preq, UNUSED void *rctx, UNUSED trunk_request_state_t state, UNUSED void *uctx)
 Callback to tidy up when a trunk request fails. More...
 
static void ldap_trunk_bind_auth_fail (request_t *request, void *preq, UNUSED void *rctx, UNUSED trunk_request_state_t state, UNUSED void *uctx)
 Callback to tidy up when a bind auth trunk request fails. More...
 

Variables

static USES_APPLE_DEPRECATED_API char const * ldap_msg_types [UINT8_MAX]
 

Detailed Description

Asynchronous connection management functions for LDAP.

Id
0e481afde1a5c9d991a0adc44bf02d5e9139e083

Definition in file connection.c.

Macro Definition Documentation

◆ do_ldap_option

#define do_ldap_option (   _option,
  _name,
  _value 
)
Value:
if (ldap_set_option(c->handle, _option, _value) != LDAP_OPT_SUCCESS) do { \
ldap_get_option(c->handle, LDAP_OPT_ERROR_NUMBER, &ldap_errno); \
ERROR("Failed setting connection option %s: %s", _name, \
(ldap_errno != LDAP_SUCCESS) ? ldap_err2string(ldap_errno) : "Unknown error"); \
goto error;\
} while (0)

◆ maybe_ldap_option

#define maybe_ldap_option (   _option,
  _name,
  _value 
)     if (_value) do_ldap_option(_option, _name, _value)

◆ POPULATE_LDAP_CONTROLS

#define POPULATE_LDAP_CONTROLS (   _dest,
  _src 
)
Value:
do { \
int i; \
for (i = 0; (i < LDAP_MAX_CONTROLS) && (_src[i].control); i++) { \
_dest[i] = _src[i].control; \
} \
_dest[i] = NULL; \
} while (0)
static fr_control_t * control
Definition: control_test.c:50
#define LDAP_MAX_CONTROLS
Maximum number of client/server controls.
Definition: base.h:94

Definition at line 552 of file connection.c.

Function Documentation

◆ _ldap_connection_close()

static void _ldap_connection_close ( fr_event_list_t el,
void *  h,
UNUSED void *  uctx 
)
static

Free the handle, closing the connection to ldap.

Parameters
[in]elUNUSED.
[in]hto close.
[in]uctxConnection config and handle.

Definition at line 195 of file connection.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ _ldap_connection_close_watch()

static void _ldap_connection_close_watch ( connection_t conn,
UNUSED connection_state_t  prev,
UNUSED connection_state_t  state,
void *  uctx 
)
static

Watcher for LDAP connections being closed.

If there are any outstanding queries on the connection then re-parent the connection to the NULL ctx so that it remains until all the queries have been dealt with.

Definition at line 286 of file connection.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ _ldap_connection_free()

static int _ldap_connection_free ( fr_ldap_connection_t c)
static

Close and delete a connection.

Unbinds the LDAP connection, informing the server and freeing any memory, then releases the memory used by the connection handle.

Parameters
[in]cto destroy.
Returns
always indicates success.

Definition at line 221 of file connection.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ _ldap_trunk_idle_timeout()

static void _ldap_trunk_idle_timeout ( fr_event_list_t el,
UNUSED fr_time_t  now,
void *  uctx 
)
static

Callback for closing idle LDAP trunk.

Definition at line 456 of file connection.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ _thread_ldap_trunk_free()

static int _thread_ldap_trunk_free ( fr_ldap_thread_trunk_t ttrunk)
static

Definition at line 897 of file connection.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ CC_NO_UBSAN()

CC_NO_UBSAN ( function  )

(Re-)Initialises the libldap side of the connection handle

A special version of the trunk/event loop glue function which always discards incoming data.

Return how many nodes there are in a trie.

Remove an entry, without freeing the data.

Insert data into a trie.

Match an element exactly in the trie, returning the data.

Return how many nodes there are in a tree.

Remove node and free data (if a free function was specified)

Remove an entry from the tree, without freeing the data.

Insert data into a tree.

Remove and free data (if a free function was specified)

Remove an entry from the hash table, without freeing the data.

Replace old data with new data, OR insert if there is no old.

Insert data into a hash table.

Return the next item, starting with the current item, that satisfies an evaluation function.

Return the first item that satisfies an evaluation function.

Return the next item, skipping the current item, that satisfies an evaluation function.

Callback to cancel LDAP bind auth.

Read LDAP bind auth responses.

Take pending LDAP bind auths from the queue and send them.

Read LDAP responses.

Take LDAP pending queries from the queue and send them.

Allocate an LDAP trunk connection.

Callback to cancel LDAP queries.

The first ldap state transition is either:

init -> start tls or init -> bind

Either way libldap will try an open the connection so when fr_ldap_state_next returns we should have the file descriptor to pass back.

The complete order of operations is:

  • Initialise the libldap handle with fr_ldap_connection_configure (calls ldap_init)
  • Initiate the connection with fr_ldap_state_next, which either binds or calls start_tls.
  • Either operation calls ldap_send_server_request.
    • Which calls ldap_new_connection.
    • Which calls ldap_int_open_connection.
    • Which calls ldap_connect_to_(host|path) and adds socket buffers, and possibly calls ldap_int_tls_start (for ldaps://).
    • When ldap_new_connection returns, because LDAP_OPT_CONNECT_ASYNC is set to LDAP_OPT_ON, lc->lconn_status is set to LDAP_CONNST_CONNECTING.
    • ldap_send_server_request checks for lconn_stats == LDAP_CONNST_CONNECTING, and calls ldap_int_poll, which checks the fd for error conditions and immediately returns due to the network timeout value.
    • If the socket is not yet connected:
      • As network timeout on the LDAP handle is 0, ld->ld_errno is set to LDAP_X_CONNECTING. ldap_send_server_request returns -1.
      • bind or start_tls errors with LDAP_X_CONNECTING without sending the request.
      • We install a write I/O handler, and wait to be called again, then we retry the operation.
    • else
      • the bind or start_tls operation succeeds, our ldap state machine advances, the connection callback is called and our socket state machine transitions to connected.
  • Continue running the state machine
Parameters
[out]hUnderlying file descriptor from libldap handle.
[in]connBeing initialised.
[in]uctxOur LDAP connection handle (a fr_ldap_connection_t).
Returns
  • CONNECTION_STATE_CONNECTING on success.
  • CONNECTION_STATE_FAILED on failure.

Inform the remote LDAP server that we no longer want responses to specific queries.

Parameters
[in]elFor timer management.
[in]tconnThe trunk connection handle
[in]connThe specific connection queries will be cancelled on
[in]uctxContext provided to trunk_alloc
[in]tconnTrunk handle.
[in]elEvent list which will be used for I/O and timer events.
[in]conn_confConfiguration of the connection.
[in]log_prefixWhat to prefix log messages with.
[in]uctxUser context passed to trunk_alloc.
[in]elEvent list for timers.
[in]tconnTrunk handle.
[in]connon which to send the queries
[in]uctxUser context passed to trunk_alloc

Responses from the LDAP server will cause the fd to become readable and trigger this callback. Most LDAP search responses have multiple messages in their response - we only gather those which are complete before either following a referral or passing the head of the resulting chain of messages back.

Parameters
[in]elTo insert timers into.
[in]tconnTrunk connection associated with these results.
[in]connConnection handle for these results.
[in]uctxThread specific trunk structure - contains tree of pending queries.
[in]elTo insert timers into.
[in]tconnTrunk connection associated with these results.
[in]connConnection handle for these results.
[in]uctxThread specific trunk structure - contains tree of pending queries.

Inform the remote LDAP server that we no longer want responses to specific bind.

Parameters
[in]elFor timer management.
[in]tconnThe trunk connection handle
[in]connThe specific connection binds will be cancelled on
[in]uctxContext provided to trunk_alloc
[in]cursorto operate on
[in]evalevaluation function
[in]uctxcontext for the evaluation function
Returns
the next item satisfying eval, or NULL if no such item exists
Parameters
[in]cursorto operate on
[in]evalevaluation function
[in]uctxcontext for the evaluation function
Returns
the first item satisfying eval, or NULL if no such item exists
Parameters
[in]htto insert data into.
[in]datato insert. Will be passed to the hashing function.
Returns
  • true if data was inserted.
  • false if data already existed and was not inserted.
Parameters
[out]olddata that was replaced. If this argument is not NULL, then the old data will not be freed, even if a free function is configured.
[in]htto insert data into.
[in]datato replace. Will be passed to the hashing function.
Returns
  • 1 if data was replaced.
  • 0 if data was inserted.
  • -1 if we failed to replace data
Parameters
[in]htto remove data from.
[in]datato remove. Will be passed to the hashing function.
Returns
  • The user data we removed.
  • NULL if we couldn't find any matching data.
Parameters
[in]htto remove data from.
[in]datato remove/free.
Returns
  • true if we removed data.
  • false if we couldn't find any matching data.
Parameters
[in]treeto insert data into.
[in]datato insert.
Returns
  • true if data was inserted.
  • false if data already existed and was not inserted.
Parameters
[out]olddata that was replaced. If this argument is not NULL, then the old data will not be freed, even if a free function is configured.
[in]treeto insert data into.
[in]datato replace.
Returns
  • 1 if data was replaced.
  • 0 if data was inserted.
  • -1 if we failed to replace data
Parameters
[in]treeto remove data from.
[in]datato remove.
Returns
  • The user data we removed.
  • NULL if we couldn't find any matching data.
Parameters
[in]treeto remove data from.
[in]datato remove/free.
Returns
  • true if we removed data.
  • false if we couldn't find any matching data.
Parameters
[in]treeto return node count for.
[in]ftto search in.
[in]datato find.
Returns
  • User data matching the data passed in.
  • NULL if nothing matched passed data.
Parameters
[in]ftto insert data into.
[in]datato insert.
Returns
  • true if data was inserted.
  • false if data already existed and was not inserted.
Parameters
[out]olddata that was replaced. If this argument is not NULL, then the old data will not be freed, even if a free function is configured.
[in]ftto insert data into.
[in]datato replace.
Returns
  • 1 if data was replaced.
  • 0 if data was inserted.
  • -1 if we failed to replace data
Parameters
[in]ftto remove data from.
[in]datato remove.
Returns
  • The user data we removed.
  • NULL if we couldn't find any matching data.
Parameters
[in]ftto remove data from.
[in]datato remove/free.
Returns
  • true if we removed data.
  • false if we couldn't find any matching data.
Parameters
[in]ftto return node count for.

Definition at line 341 of file connection.c.

+ Here is the call graph for this function:

◆ fr_ldap_connection_alloc()

fr_ldap_connection_t* fr_ldap_connection_alloc ( TALLOC_CTX *  ctx)

Allocate our ldap connection handle layer.

This is using handles outside of the connection state machine.

Parameters
[in]ctxto allocate connection handle in.
Returns
  • A new unbound/unconfigured connection handle on success. Call f::r_ldap_connection_configure next.
  • NULL on OOM.

Definition at line 258 of file connection.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_ldap_connection_configure()

int fr_ldap_connection_configure ( fr_ldap_connection_t c,
fr_ldap_config_t const *  config 
)

Allocate and configure a new connection.

Configures both our ldap handle, and libldap's handle.

This can be used by async code and async code as no attempt is made to connect to the LDAP server. An attempt will only be made if ldap_start_tls* or ldap_bind* functions are called.

If called on an fr_ldap_connection_t which has already been initialised, will clear any memory allocated to the connection, unbind the ldap handle, and reinitialise everything.

Parameters
[in]cto configure.
[in]configto apply.
Returns
  • 0 on success.
  • -1 on error.

Definition at line 67 of file connection.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_ldap_connection_state_alloc()

connection_t* fr_ldap_connection_state_alloc ( TALLOC_CTX *  ctx,
fr_event_list_t el,
fr_ldap_config_t const *  config,
char const *  log_prefix 
)

Alloc a self re-establishing connection to an LDAP server.

Parameters
[in]ctxto allocate any memory in, and to bind the lifetime of the connection to.
[in]elto insert I/O and timer callbacks into.
[in]configto use to bind the connection to an LDAP server.
[in]log_prefixto prepend to connection state messages.

Definition at line 386 of file connection.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_ldap_connection_timeout_reset()

int fr_ldap_connection_timeout_reset ( fr_ldap_connection_t const *  c)

Definition at line 431 of file connection.c.

+ Here is the caller graph for this function:

◆ fr_ldap_connection_timeout_set()

int fr_ldap_connection_timeout_set ( fr_ldap_connection_t const *  c,
fr_time_delta_t  timeout 
)

Definition at line 409 of file connection.c.

+ Here is the caller graph for this function:

◆ fr_thread_ldap_bind_trunk_get()

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.

If there is no current trunk then a new one is created.

Parameters
[in]threadto which the connection belongs
Returns
  • an existing or new trunk.
  • NULL on failure

Definition at line 1295 of file connection.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_thread_ldap_trunk_get()

fr_ldap_thread_trunk_t* fr_thread_ldap_trunk_get ( fr_ldap_thread_t thread,
char const *  uri,
char const *  bind_dn,
char const *  bind_password,
request_t request,
fr_ldap_config_t const *  config 
)

Find a thread specific LDAP connection for a specific URI / bind DN.

If no existing connection exists for that combination then create a new one

Parameters
[in]threadto which the connection belongs
[in]uriof the host to find / create a connection to
[in]bind_dnto make the connection as
[in]bind_passwordfor making connection
[in]requestcurrently being processed (only for debug messages)
[in]configLDAP config of the module requesting the connection.
Returns
  • an existing or new connection matching the URI and bind DN
  • NULL on failure

Definition at line 918 of file connection.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_thread_ldap_trunk_state()

trunk_state_t fr_thread_ldap_trunk_state ( fr_ldap_thread_t thread,
char const *  uri,
char const *  bind_dn 
)

Lookup the state of a thread specific LDAP connection trunk for a specific URI / bind DN.

Parameters
[in]threadto which the connection belongs
[in]uriof the host to find / create a connection to
[in]bind_dnto make the connection as
Returns
  • State of a trunk matching the URI and bind DN
  • TRUNK_STATE_MAX if no matching trunk

Definition at line 996 of file connection.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ldap_request_cancel()

static void ldap_request_cancel ( UNUSED connection_t conn,
void *  preq,
UNUSED trunk_cancel_reason_t  reason,
UNUSED void *  uctx 
)
static

Callback when an LDAP trunk request is cancelled.

Ensure the request is removed from the list of outstanding requests

Definition at line 477 of file connection.c.

+ Here is the call graph for this function:

◆ ldap_request_fail()

static void ldap_request_fail ( request_t request,
void *  preq,
UNUSED void *  rctx,
UNUSED trunk_request_state_t  state,
UNUSED void *  uctx 
)
static

Callback to tidy up when a trunk request fails.

Definition at line 515 of file connection.c.

+ Here is the call graph for this function:

◆ ldap_trunk_bind_auth_fail()

static void ldap_trunk_bind_auth_fail ( request_t request,
void *  preq,
UNUSED void *  rctx,
UNUSED trunk_request_state_t  state,
UNUSED void *  uctx 
)
static

Callback to tidy up when a bind auth trunk request fails.

Definition at line 1267 of file connection.c.

+ Here is the call graph for this function:

Variable Documentation

◆ ldap_msg_types

USES_APPLE_DEPRECATED_API char const* ldap_msg_types[UINT8_MAX]
static
Initial value:
= {
[LDAP_RES_BIND] = "bind response",
[LDAP_RES_SEARCH_ENTRY] = "search entry",
[LDAP_RES_SEARCH_REFERENCE] = "search reference",
[LDAP_RES_SEARCH_RESULT] = "search result",
[LDAP_RES_MODIFY] = "modify response",
[LDAP_RES_ADD] = "add response",
[LDAP_RES_DELETE] = "delete response",
[LDAP_RES_MODDN] = "modify dn response",
[LDAP_RES_COMPARE] = "compare response",
[LDAP_RES_EXTENDED] = "extended response",
[LDAP_RES_INTERMEDIATE] = "intermediate response"
}

Definition at line 34 of file connection.c.