All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
Macros | Functions | Variables
ldap.c File Reference

Functions for mapping between LDAP and FreeRADIUS attributes. More...

#include <freeradius-devel/radiusd.h>
#include <freeradius-devel/modules.h>
#include <freeradius-devel/rad_assert.h>
#include <stdarg.h>
#include <ctype.h>
#include "ldap.h"
+ Include dependency graph for ldap.c:

Go to the source code of this file.

Macros

#define do_ldap_global_option(_option, _name, _value)
 
#define do_ldap_option(_option, _name, _value)
 

Functions

static int _mod_conn_free (ldap_handle_t *conn)
 Close and delete a connection. More...
 
void * mod_conn_create (TALLOC_CTX *ctx, void *instance, struct timeval const *timeout)
 Create and return a new connection. More...
 
ldap_handle_tmod_conn_get (rlm_ldap_t const *inst, UNUSED REQUEST *request)
 Gets an LDAP socket from the connection pool. More...
 
void mod_conn_release (rlm_ldap_t const *inst, ldap_handle_t *conn)
 Frees an LDAP socket back to the connection pool. More...
 
char * rlm_ldap_berval_to_string (TALLOC_CTX *ctx, struct berval const *in)
 Convert a berval to a talloced string. More...
 
ldap_rcode_t rlm_ldap_bind (rlm_ldap_t const *inst, REQUEST *request, ldap_handle_t **pconn, char const *dn, char const *password, ldap_sasl *sasl, bool retry, LDAPControl **serverctrls, LDAPControl **clientctrls)
 Bind to the LDAP directory as a user. More...
 
rlm_rcode_t rlm_ldap_check_access (rlm_ldap_t const *inst, REQUEST *request, ldap_handle_t const *conn, LDAPMessage *entry)
 Check for presence of access attribute in result. More...
 
void rlm_ldap_check_reply (rlm_ldap_t const *inst, REQUEST *request)
 Verify we got a password from the search. More...
 
static size_t rlm_ldap_common_dn (char const *full, char const *part)
 Find the place at which the two DN strings diverge. More...
 
char const * rlm_ldap_error_str (ldap_handle_t const *conn)
 Return the error string associated with a handle. More...
 
size_t rlm_ldap_escape_func (UNUSED REQUEST *request, char *out, size_t outlen, char const *in, UNUSED void *arg)
 Converts "bad" strings into ones which are safe for LDAP. More...
 
char const * rlm_ldap_find_user (rlm_ldap_t const *inst, REQUEST *request, ldap_handle_t **pconn, char const *attrs[], bool force, LDAPMessage **result, rlm_rcode_t *rcode)
 Retrieve the DN of a user object. More...
 
bool rlm_ldap_is_dn (char const *in, size_t inlen)
 Check whether a string looks like a DN. More...
 
ldap_rcode_t rlm_ldap_modify (rlm_ldap_t const *inst, REQUEST *request, ldap_handle_t **pconn, char const *dn, LDAPMod *mods[], LDAPControl **serverctrls, LDAPControl **clientctrls)
 Modify something in the LDAP directory. More...
 
size_t rlm_ldap_normalise_dn (char *out, char const *in)
 Normalise escape sequences in a DN. More...
 
ldap_rcode_t rlm_ldap_result (rlm_ldap_t const *inst, ldap_handle_t const *conn, int msgid, char const *dn, LDAPMessage **result, char const **error, char **extra)
 Parse response from LDAP server dealing with any errors. More...
 
ldap_rcode_t rlm_ldap_search (LDAPMessage **result, rlm_ldap_t const *inst, REQUEST *request, ldap_handle_t **pconn, char const *dn, int scope, char const *filter, char const *const *attrs, LDAPControl **serverctrls, LDAPControl **clientctrls)
 Search for something in the LDAP directory. More...
 
size_t rlm_ldap_unescape_func (UNUSED REQUEST *request, char *out, size_t outlen, char const *in, UNUSED void *arg)
 Converts escaped DNs and filter strings into normal. More...
 
ssize_t rlm_ldap_xlat_filter (REQUEST *request, char const **sub, size_t sublen, char *out, size_t outlen)
 Combine and expand filters. More...
 

Variables

static const char hextab [] = "0123456789abcdef"
 
FR_NAME_NUMBER const ldap_supported_extensions []
 
static const char specials [] = ",+\"\<>;*=()"
 

Detailed Description

Functions for mapping between LDAP and FreeRADIUS attributes.

LDAP module library functions.

Id:
d4bb7cdc2965969c32f5cbbd6cdb40800db1fc70
Author
Arran Cudbard-Bell a.cud.nosp@m.bard.nosp@m.b@fre.nosp@m.erad.nosp@m.ius.o.nosp@m.rg
Id:
8e3cd3f371984d0626890e7420f574f95688596c
Author
Arran Cudbard-Bell a.cud.nosp@m.bard.nosp@m.b@fre.nosp@m.erad.nosp@m.ius.o.nosp@m.rg

Definition in file ldap.c.

Macro Definition Documentation

#define do_ldap_global_option (   _option,
  _name,
  _value 
)
Value:
if (ldap_set_option(NULL, _option, _value) != LDAP_OPT_SUCCESS) { \
ldap_get_option(conn->handle, LDAP_OPT_ERROR_NUMBER, &ldap_errno); \
LDAP_ERR("Failed setting global option %s: %s", _name, \
(ldap_errno != LDAP_SUCCESS) ? ldap_err2string(ldap_errno) : "Unknown error"); \
goto error;\
}
#define LDAP_ERR(fmt,...)
Definition: ldap.h:435
#define do_ldap_option (   _option,
  _name,
  _value 
)
Value:
if (ldap_set_option(conn->handle, _option, _value) != LDAP_OPT_SUCCESS) { \
ldap_get_option(conn->handle, LDAP_OPT_ERROR_NUMBER, &ldap_errno); \
LDAP_ERR("Failed setting connection option %s: %s", _name, \
(ldap_errno != LDAP_SUCCESS) ? ldap_err2string(ldap_errno) : "Unknown error"); \
goto error;\
}
#define LDAP_ERR(fmt,...)
Definition: ldap.h:435

Function Documentation

static int _mod_conn_free ( ldap_handle_t conn)
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
connto destroy.
Returns
always indicates success.

Definition at line 1507 of file ldap.c.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void* mod_conn_create ( TALLOC_CTX *  ctx,
void *  instance,
struct timeval const *  timeout 
)

Create and return a new connection.

Create a new connection pool handle.

Create a new ldap connection and allocate memory for a new rlm_handle_t

Definition at line 1535 of file ldap.c.

+ Here is the call graph for this function:

ldap_handle_t* mod_conn_get ( rlm_ldap_t const *  inst,
UNUSED REQUEST request 
)

Gets an LDAP socket from the connection pool.

Retrieve a socket from the connection pool, or NULL on error (of if no sockets are available).

Parameters
instrlm_ldap configuration.
requestCurrent request (may be NULL).

Definition at line 1722 of file ldap.c.

+ Here is the call graph for this function:

void mod_conn_release ( rlm_ldap_t const *  inst,
ldap_handle_t conn 
)

Frees an LDAP socket back to the connection pool.

If the socket was rebound chasing a referral onto another server then we destroy it. If the socket was rebound to another user on the same server, we let the next caller rebind it.

Parameters
instrlm_ldap configuration.
connto release.

Definition at line 1758 of file ldap.c.

+ Here is the call graph for this function:

char* rlm_ldap_berval_to_string ( TALLOC_CTX *  ctx,
struct berval const *  in 
)

Convert a berval to a talloced string.

The ldap_get_values function is deprecated, and ldap_get_values_len does not guarantee the berval buffers it returns are \0 terminated.

For some cases this is fine, for others we require a \0 terminated buffer (feeding DNs back into libldap for example).

Parameters
ctxto allocate in.
inBerval to copy.
Returns
\0 terminated buffer containing in->bv_val.

Definition at line 281 of file ldap.c.

+ Here is the caller graph for this function:

ldap_rcode_t rlm_ldap_bind ( rlm_ldap_t const *  inst,
REQUEST request,
ldap_handle_t **  pconn,
char const *  dn,
char const *  password,
ldap_sasl sasl,
bool  retry,
LDAPControl **  serverctrls,
LDAPControl **  clientctrls 
)

Bind to the LDAP directory as a user.

Performs a simple bind to the LDAP directory, and handles any errors that occur.

Parameters
[in]instrlm_ldap configuration.
[in]requestCurrent request, this may be NULL, in which case all debug logging is done with radlog.
[in,out]pconnto use. May change as this function calls functions which auto re-connect.
[in]dnof the user, may be NULL to bind anonymously.
[in]passwordof the user, may be NULL if no password is specified.
[in]saslmechanism to use for bind, and additional parameters.
[in]retryif the server is down.
[in]serverctrlsSearch controls to pass to the server. Only used for SASL binds. May be NULL.
[in]clientctrlsSearch controls for sasl_bind. Only used for SASL binds. May be NULL.
Returns
One of the LDAP_PROC_* (ldap_rcode_t) values.

Definition at line 751 of file ldap.c.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

rlm_rcode_t rlm_ldap_check_access ( rlm_ldap_t const *  inst,
REQUEST request,
ldap_handle_t const *  conn,
LDAPMessage *  entry 
)

Check for presence of access attribute in result.

Parameters
[in]instrlm_ldap configuration.
[in]requestCurrent request.
[in]connused to retrieve access attributes.
[in]entryretrieved by rlm_ldap_find_user or rlm_ldap_search.
Returns

Definition at line 1327 of file ldap.c.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void rlm_ldap_check_reply ( rlm_ldap_t const *  inst,
REQUEST request 
)

Verify we got a password from the search.

Checks to see if after the LDAP to RADIUS mapping has been completed that a reference password.

Parameters
instrlm_ldap configuration.
requestCurrent request.

Definition at line 1362 of file ldap.c.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static size_t rlm_ldap_common_dn ( char const *  full,
char const *  part 
)
static

Find the place at which the two DN strings diverge.

Returns the length of the non matching string in full.

Parameters
fullDN.
partPartial DN as returned by ldap_parse_result.
Returns
  • Length of the portion of full which wasn't matched
  • -1 on failure.

Definition at line 375 of file ldap.c.

+ Here is the caller graph for this function:

char const* rlm_ldap_error_str ( ldap_handle_t const *  conn)

Return the error string associated with a handle.

Parameters
connto retrieve error from.
Returns
error string.

Definition at line 488 of file ldap.c.

+ Here is the caller graph for this function:

size_t rlm_ldap_escape_func ( UNUSED REQUEST request,
char *  out,
size_t  outlen,
char const *  in,
UNUSED void *  arg 
)

Converts "bad" strings into ones which are safe for LDAP.

Note
RFC 4515 says filter strings can only use the
\<hex><hex> 
format, whereas RFC 4514 indicates that some chars in DNs, may be escaped simply with a backslash. For simplicity, we always use the hex escape sequences. In other areas where we're doing DN comparison, the DNs need to be normalised first so that they both use only hex escape sequences.
This is a callback for xlat operations.

Will escape any characters in input strings that would cause the string to be interpreted as part of a DN and or filter. Escape sequence is

\<hex><hex> 

.

Parameters
requestThe current request.
outPointer to output buffer.
outlenSize of the output buffer.
inRaw unescaped string.
argAny additional arguments (unused).

Definition at line 65 of file ldap.c.

+ Here is the caller graph for this function:

char const* rlm_ldap_find_user ( rlm_ldap_t const *  inst,
REQUEST request,
ldap_handle_t **  pconn,
char const *  attrs[],
bool  force,
LDAPMessage **  result,
rlm_rcode_t rcode 
)

Retrieve the DN of a user object.

Retrieves the DN of a user and adds it to the control list as LDAP-UserDN. Will also retrieve any attributes passed and return the result in *result.

This potentially allows for all authorization and authentication checks to be performed in one ldap search operation, which is a big bonus given the number of crappy, slow cough*AD*cough LDAP directory servers out there.

Parameters
[in]instrlm_ldap configuration.
[in]requestCurrent request.
[in,out]pconnto use. May change as this function calls functions which auto re-connect.
[in]attrsAdditional attributes to retrieve, may be NULL.
[in]forceQuery even if the User-DN already exists.
[out]resultWhere to write the result, may be NULL in which case result is discarded.
[out]rcodeThe status of the operation, one of the RLM_MODULE_* codes.
Returns
The user's DN or NULL on error.

< Whether the message should be freed after being processed.

Definition at line 1152 of file ldap.c.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool rlm_ldap_is_dn ( char const *  in,
size_t  inlen 
)

Check whether a string looks like a DN.

Parameters
[in]inStr to check.
[in]inlenLength of string to check.
Returns
  • true if string looks like a DN.
  • false if string does not look like DN.

Definition at line 168 of file ldap.c.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

ldap_rcode_t rlm_ldap_modify ( rlm_ldap_t const *  inst,
REQUEST request,
ldap_handle_t **  pconn,
char const *  dn,
LDAPMod *  mods[],
LDAPControl **  serverctrls,
LDAPControl **  clientctrls 
)

Modify something in the LDAP directory.

Binds as the administrative user and attempts to modify an LDAP object.

Parameters
[in]instrlm_ldap configuration.
[in]requestCurrent request.
[in,out]pconnto use. May change as this function calls functions which auto re-connect.
[in]dnof the object to modify.
[in]modsto make, see 'man ldap_modify' for more information.
[in]serverctrlsSearch controls to pass to the server. May be NULL.
[in]clientctrlsSearch controls for ldap_modify. May be NULL.
Returns
One of the LDAP_PROC_* (ldap_rcode_t) values.

Definition at line 1048 of file ldap.c.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

size_t rlm_ldap_normalise_dn ( char *  out,
char const *  in 
)

Normalise escape sequences in a DN.

Characters in a DN can either be escaped as

\<hex><hex> 

or

\<special> 

The LDAP directory chooses how characters are escaped, which can make local comparisons of DNs difficult.

Here we search for hex sequences that match special chars, and convert them to the

\<special> 

form.

Note
the resulting output string will only ever be shorter than the input, so it's fine to use the same buffer for both out and in.
Parameters
outWhere to write the normalised DN.
inThe input DN.
Returns
The number of bytes written to out.

Definition at line 312 of file ldap.c.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

ldap_rcode_t rlm_ldap_result ( rlm_ldap_t const *  inst,
ldap_handle_t const *  conn,
int  msgid,
char const *  dn,
LDAPMessage **  result,
char const **  error,
char **  extra 
)

Parse response from LDAP server dealing with any errors.

Should be called after an LDAP operation. Will check result of operation and if it was successful, then attempt to retrieve and parse the result.

Will also produce extended error output including any messages the server sent, and information about partial DN matches.

Parameters
[in]instof LDAP module.
[in]connCurrent connection.
[in]msgidreturned from last operation. May be -1 if no result processing is required.
[in]dnLast search or bind DN.
[out]resultWhere to write result, if NULL result will be freed.
[out]errorWhere to write the error string, may be NULL, must not be freed.
[out]extraWhere to write additional error string to, may be NULL (faster) or must be freed (with talloc_free).
Returns
One of the LDAP_PROC_* (ldap_rcode_t) values.

Definition at line 517 of file ldap.c.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

ldap_rcode_t rlm_ldap_search ( LDAPMessage **  result,
rlm_ldap_t const *  inst,
REQUEST request,
ldap_handle_t **  pconn,
char const *  dn,
int  scope,
char const *  filter,
char const *const *  attrs,
LDAPControl **  serverctrls,
LDAPControl **  clientctrls 
)

Search for something in the LDAP directory.

Binds as the administrative user and performs a search, dealing with any errors.

Parameters
[out]resultWhere to store the result. Must be freed with ldap_msgfree if LDAP_PROC_SUCCESS is returned. May be NULL in which case result will be automatically freed after use.
[in]instrlm_ldap configuration.
[in]requestCurrent request.
[in,out]pconnto use. May change as this function calls functions which auto re-connect.
[in]dnto use as base for the search.
[in]scopeto use (LDAP_SCOPE_BASE, LDAP_SCOPE_ONE, LDAP_SCOPE_SUB).
[in]filterto use, should be pre-escaped.
[in]attrsto retrieve.
[in]serverctrlsSearch controls to pass to the server. May be NULL.
[in]clientctrlsSearch controls for ldap_search. May be NULL.
Returns
One of the LDAP_PROC_* (ldap_rcode_t) values.

Definition at line 880 of file ldap.c.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

size_t rlm_ldap_unescape_func ( UNUSED REQUEST request,
char *  out,
size_t  outlen,
char const *  in,
UNUSED void *  arg 
)

Converts escaped DNs and filter strings into normal.

Note
RFC 4515 says filter strings can only use the
\<hex><hex> 
format, whereas RFC 4514 indicates that some chars in DNs, may be escaped simply with a backslash..

Will unescape any special characters in strings, or

\<hex><hex> 

sequences.

Parameters
requestThe current request.
outPointer to output buffer.
outlenSize of the output buffer.
inEscaped string string.
argAny additional arguments (unused).

Definition at line 121 of file ldap.c.

+ Here is the caller graph for this function:

ssize_t rlm_ldap_xlat_filter ( REQUEST request,
char const **  sub,
size_t  sublen,
char *  out,
size_t  outlen 
)

Combine and expand filters.

Parameters
requestCurrent request.
outWhere to write the expanded string.
outlenLength of output buffer.
subArray of subfilters (may contain NULLs).
sublenNumber of potential subfilters in array.
Returns
length of expanded data.

Definition at line 416 of file ldap.c.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Variable Documentation

const char hextab[] = "0123456789abcdef"
static

Definition at line 37 of file ldap.c.

FR_NAME_NUMBER const ldap_supported_extensions[]
Initial value:
= {
{ "bindname", LDAP_DEREF_NEVER },
{ "x-bindpw", LDAP_DEREF_SEARCHING },
{ NULL , -1 }
}

Definition at line 39 of file ldap.c.

const char specials[] = ",+\"\<>;*=()"
static

Definition at line 36 of file ldap.c.