27 #include <freeradius-devel/radiusd.h>
28 #include <freeradius-devel/modules.h>
29 #include <freeradius-devel/rad_assert.h>
36 static const char specials[] =
",+\"\\<>;*=()";
37 static const char hextab[] =
"0123456789abcdef";
40 {
"bindname", LDAP_DEREF_NEVER },
41 {
"x-bindpw", LDAP_DEREF_SEARCHING },
70 if (*in && ((*in ==
' ') || (*in ==
'#')))
goto encode;
84 *out++ =
hextab[(*in >> 4) & 0x0f];
85 *out++ =
hextab[*in & 0x0f];
103 return outlen - left;
125 size_t freespace = outlen;
127 if (outlen <= 1)
return 0;
130 while (*p && (--freespace > 0)) {
146 if (!(c1 = memchr(
hextab, tolower(p[0]), 16)) ||
147 !(c2 = memchr(
hextab, tolower(p[1]), 16)))
goto next;
156 return outlen - freespace;
173 bool too_soon =
true;
176 for (p = in; inlen > 0; p++, inlen--) {
185 if (inlen < 2)
return false;
221 if (inlen < 3)
return false;
226 if (
fr_hex2bin((uint8_t *) &c, 1, p + 1, 2) == 1) {
240 if (too_soon || (*p != want))
return false;
246 if (too_soon || (*p != want))
return false;
264 if (too_soon || (comp < 2))
return false;
285 out = talloc_array(ctx,
char, in->bv_len + 1);
286 if (!out)
return NULL;
288 memcpy(out, in->bv_val, in->bv_len);
289 out[in->bv_len] =
'\0';
317 for (p = in; *p !=
'\0'; p++) {
336 if (
fr_hex2bin((uint8_t *) &c, 1, p + 1, 2) == 1) {
377 size_t f_len, p_len, i;
383 f_len = strlen(full);
389 p_len = strlen(part);
394 if ((f_len < p_len) || !f_len) {
398 for (i = 0; i < p_len; i++) {
399 if (part[p_len - i] != full[f_len - i]) {
404 return f_len - p_len;
419 char const *in = NULL;
430 for (i = 0; i < sublen; i++) {
431 if (sub[i] && *sub[i]) {
450 for (i = 0; i < sublen; i++) {
451 if (sub[i] && (*sub[i] !=
'\0')) {
452 len +=
strlcpy(p + len, sub[i], outlen - len);
454 if ((
size_t) len >= outlen) {
456 REDEBUG(
"Out of buffer space creating filter");
463 if ((outlen - len) < 2) {
475 REDEBUG(
"Failed creating filter");
491 ldap_get_option(conn->
handle, LDAP_OPT_ERROR_NUMBER, &lib_errno);
492 if (lib_errno == LDAP_SUCCESS) {
496 return ldap_err2string(lib_errno);
518 LDAPMessage **result,
char const **error,
char **extra)
522 int lib_errno = LDAP_SUCCESS;
523 int srv_errno = LDAP_SUCCESS;
525 char *part_dn = NULL;
526 char *our_err = NULL;
527 char *srv_err = NULL;
535 LDAPMessage *tmp_msg = NULL;
539 if (!error) error = &tmp_err;
542 if (extra) *extra = NULL;
543 if (result) *result = NULL;
556 ldap_get_option(conn->
handle, LDAP_OPT_ERROR_NUMBER, &lib_errno);
557 if (lib_errno != LDAP_SUCCESS)
goto process_error;
558 if (msgid < 0)
return LDAP_SUCCESS;
560 memset(&tv, 0,
sizeof(tv));
567 lib_errno = ldap_result(conn->
handle, msgid, 1, &tv, result);
568 if (lib_errno == 0) {
569 lib_errno = LDAP_TIMEOUT;
574 if (lib_errno == -1) {
575 ldap_get_option(conn->
handle, LDAP_OPT_ERROR_NUMBER, &lib_errno);
583 lib_errno = ldap_parse_result(conn->
handle, *result,
585 extra ? &part_dn : NULL,
586 extra ? &srv_err : NULL,
588 if (freeit) *result = NULL;
590 if (lib_errno != LDAP_SUCCESS) {
591 ldap_get_option(conn->
handle, LDAP_OPT_ERROR_NUMBER, &lib_errno);
596 if ((lib_errno == LDAP_SUCCESS) && (srv_errno != LDAP_SUCCESS)) {
597 lib_errno = srv_errno;
598 }
else if ((lib_errno != LDAP_SUCCESS) && (srv_errno == LDAP_SUCCESS)) {
599 srv_errno = lib_errno;
607 case LDAP_SASL_BIND_IN_PROGRESS:
608 *error =
"Continuing";
612 case LDAP_NO_SUCH_OBJECT:
613 *error =
"The specified DN wasn't found";
624 our_err =
talloc_typed_asprintf(conn,
"Match stopped here: [%.*s]%s", len, dn, part_dn ? part_dn :
"");
627 case LDAP_INSUFFICIENT_ACCESS:
628 *error =
"Insufficient access. Check the identity and password configuration directives";
632 case LDAP_UNWILLING_TO_PERFORM:
633 *error =
"Server was unwilling to perform";
637 case LDAP_FILTER_ERROR:
638 *error =
"Bad search filter";
643 *error =
"Timed out while waiting for server to respond";
646 case LDAP_TIMELIMIT_EXCEEDED:
647 *error =
"Time limit exceeded";
653 case LDAP_UNAVAILABLE:
654 case LDAP_SERVER_DOWN:
658 case LDAP_INVALID_CREDENTIALS:
659 case LDAP_CONSTRAINT_VIOLATION:
663 case LDAP_OPERATIONS_ERROR:
664 *error =
"Please set 'chase_referrals=yes' and 'rebind=yes'. See the ldap module configuration "
672 if (!*error) *error = ldap_err2string(lib_errno);
674 if (!extra || ((lib_errno == srv_errno) && !our_err && !srv_err))
break;
679 p = talloc_zero_array(conn,
char, 1);
682 if (lib_errno != srv_errno) {
683 a = talloc_asprintf_append(p,
"LDAP lib error: %s (%u), srv error: %s (%u). ",
684 ldap_err2string(lib_errno), lib_errno,
685 ldap_err2string(srv_errno), srv_errno);
695 a = talloc_asprintf_append_buffer(p,
"%s. ", our_err);
705 a = talloc_asprintf_append_buffer(p,
"Server said: %s. ", srv_err);
722 if (srv_err) ldap_memfree(srv_err);
723 if (part_dn) ldap_memfree(part_dn);
725 talloc_free(our_err);
727 if ((status < 0) && *result) {
728 ldap_msgfree(*result);
752 char const *password,
ldap_sasl *sasl,
bool retry,
753 LDAPControl **serverctrls, LDAPControl **clientctrls
760 char const *error = NULL;
782 for (i = num; i >= 0; i--) {
784 if (sasl && sasl->
mech) {
786 serverctrls, clientctrls, &error, &extra);
793 memcpy(&cred.bv_val, &password,
sizeof(cred.bv_val));
794 cred.bv_len = talloc_array_length(password) - 1;
796 ret = ldap_sasl_bind((*pconn)->handle, dn, LDAP_SASL_SIMPLE, &cred,
797 serverctrls, clientctrls, &msgid);
799 if ((ret == 0) && (msgid >= 0)) {
803 status =
rlm_ldap_result(inst, *pconn, msgid, dn, NULL, &error, &extra);
827 LDAP_DBGW_REQ(
"Bind with %s to %s failed: %s. Got new socket, retrying...",
828 *dn ? dn :
"(anonymous)", inst->
server, error);
843 LDAP_ERR_REQ(
"Bind with %s to %s failed: %s", *dn ? dn :
"(anonymous)",
853 if (retry && (i < 0)) {
882 char const *dn,
int scope,
char const *filter,
char const *
const *attrs,
883 LDAPControl **serverctrls, LDAPControl **clientctrls)
886 LDAPMessage *our_result = NULL;
895 char const *error = NULL;
904 sizeof(our_serverctrls) /
sizeof(*our_serverctrls),
905 sizeof(our_clientctrls) /
sizeof(*our_clientctrls),
906 *pconn, serverctrls, clientctrls);
915 memcpy(&search_attrs, &attrs,
sizeof(attrs));
920 if ((*pconn)->rebound) {
922 (*pconn)->inst->admin_password, &(*pconn)->inst->admin_sasl,
true,
930 (*pconn)->rebound =
false;
934 LDAP_DBG_REQ(
"Performing search in \"%s\" with filter \"%s\", scope \"%s\"", dn, filter,
937 LDAP_DBG_REQ(
"Performing unfiltered search in \"%s\", scope \"%s\"", dn,
945 memset(&tv, 0,
sizeof(tv));
953 (void) ldap_search_ext((*pconn)->handle, dn, scope, filter, search_attrs,
954 0, our_serverctrls, our_clientctrls, &tv, 0, &msgid);
957 status =
rlm_ldap_result(inst, *pconn, msgid, dn, &our_result, &error, &extra);
976 LDAP_DBGW_REQ(
"Search failed: %s. Got new socket, retrying...", error);
1003 count = ldap_count_entries((*pconn)->handle, our_result);
1008 ldap_msgfree(our_result);
1010 }
else if (count == 0) {
1014 ldap_msgfree(our_result);
1027 if (our_result) ldap_msgfree(our_result);
1029 *result = our_result;
1049 char const *dn, LDAPMod *mods[],
1050 LDAPControl **serverctrls, LDAPControl **clientctrls)
1056 char const *error = NULL;
1065 sizeof(our_serverctrls) /
sizeof(*our_serverctrls),
1066 sizeof(our_clientctrls) /
sizeof(*our_clientctrls),
1067 *pconn, serverctrls, clientctrls);
1074 if ((*pconn)->rebound) {
1076 (*pconn)->inst->admin_password, &(*pconn)->inst->admin_sasl,
true,
1084 (*pconn)->rebound =
false;
1092 RDEBUG2(
"Modifying object with DN \"%s\"", dn);
1093 (void) ldap_modify_ext((*pconn)->handle, dn, mods, our_serverctrls, our_clientctrls, &msgid);
1095 RDEBUG2(
"Waiting for modify result...");
1096 status =
rlm_ldap_result(inst, *pconn, msgid, dn, NULL, &error, &extra);
1104 RWDEBUG(
"Modify failed: %s. Got new socket, retrying...", error);
1114 REDEBUG(
"Failed modifying object: %s", error);
1153 char const *attrs[],
bool force, LDAPMessage **result,
rlm_rcode_t *rcode)
1155 static char const *tmp_attrs[] = { NULL };
1159 LDAPMessage *tmp_msg = NULL, *entry = NULL;
1163 char const *filter = NULL;
1165 char const *base_dn;
1169 bool freeit =
false;
1181 memset(&attrs, 0,
sizeof(tmp_attrs));
1190 RDEBUG(
"Using user DN from request \"%s\"", vp->vp_strvalue);
1192 return vp->vp_strvalue;
1199 if ((*pconn)->rebound) {
1201 (*pconn)->inst->admin_password, &(*pconn)->inst->admin_sasl,
true,
1210 (*pconn)->rebound =
false;
1216 REDEBUG(
"Unable to create filter");
1223 if (
tmpl_expand(&base_dn, base_dn_buff,
sizeof(base_dn_buff), request,
1225 REDEBUG(
"Unable to create base_dn");
1255 cnt = ldap_count_entries((*pconn)->handle, *result);
1257 REDEBUG(
"Ambiguous search result, returned %i unsorted entries (should return 1 or 0). "
1258 "Enable sorting, or specify a more restrictive base_dn, filter or scope", cnt);
1259 REDEBUG(
"The following entries were returned:");
1261 for (entry = ldap_first_entry((*pconn)->handle, *result);
1263 entry = ldap_next_entry((*pconn)->handle, entry)) {
1264 dn = ldap_get_dn((*pconn)->handle, entry);
1274 entry = ldap_first_entry((*pconn)->handle, *result);
1276 ldap_get_option((*pconn)->handle, LDAP_OPT_RESULT_CODE, &ldap_errno);
1277 REDEBUG(
"Failed retrieving entry: %s",
1278 ldap_err2string(ldap_errno));
1283 dn = ldap_get_dn((*pconn)->handle, entry);
1285 ldap_get_option((*pconn)->handle, LDAP_OPT_RESULT_CODE, &ldap_errno);
1286 REDEBUG(
"Retrieving object DN from entry failed: %s", ldap_err2string(ldap_errno));
1300 RDEBUG(
"User object found at DN \"%s\"", dn);
1310 ldap_msgfree(*result);
1314 return vp ? vp->vp_strvalue : NULL;
1331 struct berval **values = NULL;
1336 if ((values[0]->bv_len >= 5) && (
strncasecmp(values[0]->bv_val,
"false", 5) == 0)) {
1337 RDEBUG(
"\"%s\" attribute exists but is set to 'false' - user locked out",
1342 }
else if ((values[0]->bv_len < 5) || (
strncasecmp(values[0]->bv_val,
"false", 5) != 0)) {
1346 ldap_value_free_len(values);
1376 RWDEBUG(
"No \"known good\" password added. Ensure the admin user has permission to "
1377 "read the password attribute");
1378 RWDEBUG(
"PAP authentication will *NOT* work with Active Directory (if that is what you "
1379 "were trying to configure)");
1384 #if LDAP_SET_REBIND_PROC_ARGS == 3
1395 static int rlm_ldap_rebind(LDAP *handle, LDAP_CONST
char *url,
UNUSED ber_tag_t request,
UNUSED ber_int_t msgid,
1402 char const *admin_identity = NULL;
1403 char const *admin_password = NULL;
1411 DEBUG(
"rlm_ldap (%s): Rebinding to URL %s", inst->
name, url);
1413 # ifdef HAVE_LDAP_URL_PARSE
1420 LDAPURLDesc *ldap_url;
1424 ret = ldap_url_parse(url, &ldap_url);
1425 if (ret != LDAP_SUCCESS) {
1426 ERROR(
"rlm_ldap (%s): Failed parsing LDAP URL \"%s\": %s",
1427 inst->
name, url, ldap_err2string(ret));
1435 for (ext = ldap_url->lud_exts; ext && *ext; ext++) {
1437 bool critical =
false;
1454 ERROR(
"rlm_ldap (%s): Failed parsing extension \"%s\": "
1455 "No attribute/value delimiter '='", inst->
name, *ext);
1456 ldap_free_urldesc(ldap_url);
1459 admin_identity = p + 1;
1464 if (!p)
goto bad_ext;
1465 admin_password = p + 1;
1470 ERROR(
"rlm_ldap (%s): Failed parsing critical extension \"%s\": "
1471 "Not supported by rlm_ldap", inst->
name, *ext);
1472 ldap_free_urldesc(ldap_url);
1475 DEBUG2(
"rlm_ldap (%s): Skipping unsupported extension \"%s\"", inst->
name, *ext);
1479 ldap_free_urldesc(ldap_url);
1487 status =
rlm_ldap_bind(inst, NULL, &conn, admin_identity, admin_password,
1490 ldap_get_option(handle, LDAP_OPT_ERROR_NUMBER, &ldap_errno);
1495 return LDAP_SUCCESS;
1510 #ifdef HAVE_LDAP_UNBIND_EXT_S
1515 sizeof(our_serverctrls) /
sizeof(*our_serverctrls),
1516 sizeof(our_clientctrls) /
sizeof(*our_clientctrls),
1519 DEBUG3(
"rlm_ldap: Closing libldap handle %p", conn->
handle);
1520 ldap_unbind_ext_s(conn->
handle, our_serverctrls, our_clientctrls);
1522 DEBUG3(
"rlm_ldap: Closing libldap handle %p", conn->
handle);
1523 ldap_unbind_s(conn->
handle);
1539 int ldap_errno, ldap_version;
1548 if (!conn)
return NULL;
1556 #ifdef HAVE_LDAP_INITIALIZE
1557 ldap_errno = ldap_initialize(&conn->
handle, inst->
server);
1558 if (ldap_errno != LDAP_SUCCESS) {
1559 LDAP_ERR(
"ldap_initialize failed: %s", ldap_err2string(ldap_errno));
1576 #define do_ldap_option(_option, _name, _value) \
1577 if (ldap_set_option(conn->handle, _option, _value) != LDAP_OPT_SUCCESS) { \
1578 ldap_get_option(conn->handle, LDAP_OPT_ERROR_NUMBER, &ldap_errno); \
1579 LDAP_ERR("Failed setting connection option %s: %s", _name, \
1580 (ldap_errno != LDAP_SUCCESS) ? ldap_err2string(ldap_errno) : "Unknown error"); \
1584 #define do_ldap_global_option(_option, _name, _value) \
1585 if (ldap_set_option(NULL, _option, _value) != LDAP_OPT_SUCCESS) { \
1586 ldap_get_option(conn->handle, LDAP_OPT_ERROR_NUMBER, &ldap_errno); \
1587 LDAP_ERR("Failed setting global option %s: %s", _name, \
1588 (ldap_errno != LDAP_SUCCESS) ? ldap_err2string(ldap_errno) : "Unknown error"); \
1608 do_ldap_option(LDAP_OPT_REFERRALS,
"chase_referrals", LDAP_OPT_ON);
1610 if (inst->
rebind ==
true) {
1611 #if LDAP_SET_REBIND_PROC_ARGS == 3
1612 ldap_set_rebind_proc(conn->
handle, rlm_ldap_rebind, conn);
1616 do_ldap_option(LDAP_OPT_REFERRALS,
"chase_referrals", LDAP_OPT_OFF);
1620 #ifdef LDAP_OPT_NETWORK_TIMEOUT
1621 do_ldap_option(LDAP_OPT_NETWORK_TIMEOUT,
"pool.connect_timeout", &timeout);
1626 ldap_version = LDAP_VERSION3;
1627 do_ldap_option(LDAP_OPT_PROTOCOL_VERSION,
"ldap_version", &ldap_version);
1629 #ifdef LDAP_OPT_X_KEEPALIVE_IDLE
1630 do_ldap_option(LDAP_OPT_X_KEEPALIVE_IDLE,
"keepalive_idle", &(inst->keepalive_idle));
1633 #ifdef LDAP_OPT_X_KEEPALIVE_PROBES
1634 do_ldap_option(LDAP_OPT_X_KEEPALIVE_PROBES,
"keepalive_probes", &(inst->keepalive_probes));
1637 #ifdef LDAP_OPT_X_KEEPALIVE_INTERVAL
1638 do_ldap_option(LDAP_OPT_X_KEEPALIVE_INTERVAL,
"keepalive_interval", &(inst->keepalive_interval));
1641 #ifdef HAVE_LDAP_START_TLS_S
1649 # define maybe_ldap_option(_option, _name, _value) \
1650 if (_value) do_ldap_option(_option, _name, _value)
1652 maybe_ldap_option(LDAP_OPT_X_TLS_CACERTFILE,
"ca_file", inst->
tls_ca_file);
1653 maybe_ldap_option(LDAP_OPT_X_TLS_CACERTDIR,
"ca_path", inst->
tls_ca_path);
1661 maybe_ldap_option(LDAP_OPT_X_TLS_RANDOM_FILE,
"random_file", inst->
tls_random_file);
1663 # ifdef LDAP_OPT_X_TLS_NEVER
1673 # ifdef LDAP_OPT_X_TLS_NEWCTX
1677 do_ldap_option(LDAP_OPT_X_TLS_NEWCTX,
"new TLS context", &is_server);
1686 if (inst->
port == 636) {
1687 WARN(
"Told to Start TLS on LDAPS port this will probably fail, please correct the "
1691 if (ldap_start_tls_s(conn->
handle, NULL, NULL) != LDAP_SUCCESS) {
1692 ldap_get_option(conn->
handle, LDAP_OPT_ERROR_NUMBER, &ldap_errno);
1694 LDAP_ERR(
"Could not start TLS: %s", ldap_err2string(ldap_errno));
1723 #ifdef LDAP_CONTROL_X_SESSION_TRACKING
1734 #ifdef LDAP_CONTROL_X_SESSION_TRACKING
1740 if ((conn != NULL) & (request != NULL) & inst->session_tracking) {
static size_t rlm_ldap_common_dn(char const *full, char const *part)
Find the place at which the two DN strings diverge.
ssize_t tmpl_expand(char const **out, char *buff, size_t outlen, REQUEST *request, vp_tmpl_t const *vpt, xlat_escape_t escape, void *escape_ctx)
Expand a vp_tmpl_t to a string writing the result to a buffer.
Tracks the state of a libldap connection handle.
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.
void * mod_conn_create(TALLOC_CTX *ctx, void *instance, struct timeval const *timeout)
Create and return a new connection.
ldap_rcode_t rlm_ldap_sasl_interactive(rlm_ldap_t const *inst, REQUEST *request, ldap_handle_t *pconn, char const *dn, char const *password, ldap_sasl *sasl, LDAPControl **serverctrls, LDAPControl **clientctrls, char const **error, char **error_extra)
Initiate an LDAP interactive bind.
VALUE_PAIR * config
VALUE_PAIR (s) used to set per request parameters for modules and the server core at runtime...
Operation was successfull.
#define RINDENT()
Indent R* messages by one level.
The module is OK, continue.
char const * userobj_access_attr
Attribute to check to see if the user should be locked out.
void exec_trigger(REQUEST *request, CONF_SECTION *cs, char const *name, bool quench) CC_HINT(nonnull(3))
Execute a trigger - call an executable to process an event.
int rlm_ldap_control_add_session_tracking(ldap_handle_t *conn, REQUEST *request)
fr_connection_pool_t * pool
Connection pool instance.
uint32_t res_timeout
How long we wait for a result from the server.
ldap_handle_t * mod_conn_get(rlm_ldap_t const *inst, UNUSED REQUEST *request)
Gets an LDAP socket from the connection pool.
uint32_t srv_timelimit
How long the server should spent on a single request (also bounded by value on the server)...
void rlm_ldap_control_merge(LDAPControl *serverctrls_out[], LDAPControl *clientctrls_out[], size_t serverctrls_len, size_t clientctrls_len, ldap_handle_t *conn, LDAPControl *serverctrls_in[], LDAPControl *clientctrls_in[])
Merge connection and call specific client and server controls.
char const * admin_identity
Identity we bind as when we need to query the LDAP directory.
Specifies the password for an LDAP bind.
char const * admin_password
Password used in administrative bind.
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.
bool start_tls
Send the Start TLS message to the LDAP directory to start encrypted communications using the standard...
static const char specials[]
bool use_referral_credentials
If true use credentials from the referral URL.
char const * tls_certificate_file
Sets the path to the public certificate file we present to the servers.
bool chase_referrals_unset
If true, use the OpenLDAP defaults for chase_referrals.
char * server
Initial server to bind to.
The module considers the request invalid.
int userobj_scope
Search scope.
ldap_rcode_t
Codes returned by rlm_ldap internal functions.
#define LDAP_MAX_FILTER_STR_LEN
Maximum length of an xlat expanded filter.
Specifies the user DN or name for an LDAP bind.
#define LDAP_DBG_REQ(fmt,...)
size_t rlm_ldap_normalise_dn(char *out, char const *in)
Normalise escape sequences in a DN.
#define LDAP_ERR_REQ(fmt,...)
Operation was not permitted, either current user was locked out in the case of binds, or has insufficient access.
int dereference
libldap value specifying dereferencing behaviour.
void mod_conn_release(rlm_ldap_t const *inst, ldap_handle_t *conn)
Frees an LDAP socket back to the connection pool.
Reject the request (user is locked out).
bool chase_referrals
If the LDAP server returns a referral to another server or point in the tree, follow it...
char const * tls_ca_file
Sets the full path to a CA certificate (used to validate the certificate the server presents)...
#define LDAP_MAX_DN_STR_LEN
Maximum length of an xlat expanded DN.
vp_tmpl_t * userobj_base_dn
DN to search for users under.
static int comp(void const *a, void const *b)
void fr_pair_value_strcpy(VALUE_PAIR *vp, char const *src)
Copy data into an "string" data type.
#define LDAP_ERR(fmt,...)
bool rebound
Whether the connection has been rebound to something other than the admin user.
#define MOD_ROPTIONAL(_l_request, _l_global, fmt,...)
Use different logging functions depending on whether request is NULL or not.
size_t fr_hex2bin(uint8_t *bin, size_t outlen, char const *hex, size_t inlen)
Convert hex strings to binary data.
void rlm_ldap_check_reply(rlm_ldap_t const *inst, REQUEST *request)
Verify we got a password from the search.
static int _mod_conn_free(ldap_handle_t *conn)
Close and delete a connection.
bool rebind
Controls whether we set an ldad_rebind_proc function and so determines if we can bind to other server...
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.
Stores an attribute, a value and various bits of other data.
uint16_t port
Port to use when binding to the server.
char const * rlm_ldap_error_str(ldap_handle_t const *conn)
Return the error string associated with a handle.
ssize_t rlm_ldap_xlat_filter(REQUEST *request, char const **sub, size_t sublen, char *out, size_t outlen)
Combine and expand filters.
char * talloc_typed_asprintf(void const *t, char const *fmt,...)
Call talloc vasprintf, setting the type on the new chunk correctly.
CONF_SECTION * cs
Main configuration section for this instance.
Operation is in progress.
static const char hextab[]
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.
#define REXDENT()
Exdent (unindent) R* messages by one level.
char const * name
Instance name.
char const * tls_ca_path
Sets the path to a directory containing CA certificates.
enum rlm_rcodes rlm_rcode_t
Return codes indicating the result of the module call.
int tls_require_cert
OpenLDAP constant representing the require cert string.
ssize_t radius_xlat(char *out, size_t outlen, REQUEST *request, char const *fmt, xlat_escape_t escape, void *escape_ctx) CC_HINT(nonnull(1
rlm_ldap_t * inst
rlm_ldap configuration.
#define do_ldap_option(_option, _name, _value)
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.
Module failed, don't reply.
uint32_t ldap_debug
Debug flag for the SDK.
log_lvl_t rad_debug_lvl
Global debugging level.
Specified an invalid object in a bind or search DN.
uint32_t num
Number of connections in the pool.
int strncasecmp(char *s1, char *s2, int n)
void * fr_connection_get(fr_connection_pool_t *pool)
Reserve a connection in the connection pool.
int fr_connection_close(fr_connection_pool_t *pool, void *conn)
Delete a connection from the connection pool.
vp_tmpl_t * userobj_filter
Filter to retrieve only user objects.
Transitory error, caller should retry the operation with a new connection.
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.
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.
char const * tls_require_cert_str
Sets requirements for validating the certificate the server presents.
#define LDAP_DBGW_REQ(fmt,...)
char const * tls_random_file
Path to the random file if /dev/random and /dev/urandom are unavailable.
VALUE_PAIR * fr_pair_find_by_num(VALUE_PAIR *head, unsigned int vendor, unsigned int attr, int8_t tag)
Find the pair with the matching attribute.
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.
char const * mech
SASL mech(s) to try.
size_t strlcpy(char *dst, char const *src, size_t siz)
FR_NAME_NUMBER const ldap_supported_extensions[]
LDAPControl * userobj_sort_ctrl
Server side sort control.
char const * fr_int2str(FR_NAME_NUMBER const *table, int number, char const *def)
char * rlm_ldap_berval_to_string(TALLOC_CTX *ctx, struct berval const *in)
Convert a berval to a talloced string.
void fr_connection_release(fr_connection_pool_t *pool, void *conn)
Release a connection.
bool access_positive
If true the presence of the attribute will allow access, else it will deny access.
ldap_sasl admin_sasl
SASL parameters used when binding as the admin.
Unrecoverable library/server error.
#define LDAP_MAX_CONTROLS
Maximum number of client/server controls.
int fr_substr2int(FR_NAME_NUMBER const *table, char const *name, int def, int len)
LDAP authorization and authentication module headers.
fr_connection_pool_state_t const * fr_connection_pool_state(fr_connection_pool_t *pool)
Get the number of connections currently in the pool.
void rlm_ldap_control_clear(ldap_handle_t *conn)
Clear and free any controls associated with a connection.
bool expect_password
True if the user_map included a mapping between an LDAP attribute and one of our password reference a...
VALUE_PAIR * fr_pair_make(TALLOC_CTX *ctx, VALUE_PAIR **vps, char const *attribute, char const *value, FR_TOKEN op)
Create a VALUE_PAIR from ASCII strings.
void * fr_connection_reconnect(fr_connection_pool_t *pool, void *conn)
Reconnect a suspected inviable connection.
char const * dereference_str
When to dereference (never, searching, finding, always)
#define do_ldap_global_option(_option, _name, _value)
bool referred
Whether the connection is now established a server other than the configured one. ...
bool rlm_ldap_is_dn(char const *in, size_t inlen)
Check whether a string looks like a DN.
LDAP * handle
libldap handle.
Bind failed, user was rejected.
char const * tls_private_key_file
Sets the path to the private key for our public certificate.
FR_NAME_NUMBER const ldap_scope[]