-chase_referrals:: and the such `rebind` control whether the server follows
-references returned by LDAP directory.
+chase_referrals:: controls whether the server follows references returned by LDAP directory.
-They are mostly for Active Directory compatibility.
-If you set these to `no`, then searches will likely return 'operations error',
+They are mostly for Active Directory compatibility.
+If you set this to `no`, then searches will likely return 'operations error',
instead of a useful result.
-rebind:: See `chase_referrals` for more detail.
+rebind:: If `chase_referrals` is `yes`, then, when a referral is followed, having `rebind`
+set to `no` will cause libldap to do an anonymous bind when making any additional connections.
+Setting this to `yes` will either bind with the admin credentials or the credientials from the
+rebind url depending on `use_referral_credentials`.
# dereference = 'always'
#
- # chase_referrals:: and the such `rebind` control whether the server follows
- # references returned by LDAP directory.
+ # chase_referrals:: controls whether the server follows references returned
+ # by the LDAP directory.
#
- # They are mostly for Active Directory compatibility.
- # If you set these to `no`, then searches will likely return 'operations error',
+ # They are mostly for Active Directory compatibility.
+ # If you set this to `no`, then searches will likely return 'operations error',
# instead of a useful result.
#
chase_referrals = yes
#
- # rebind:: See `chase_referrals` for more detail.
+ # rebind:: If `chase_referrals` is `yes` then, when a referral is followed
+ # having `rebind` set to `no` will cause the server to do an anonymous bind when
+ # making any additional connections. Setting this to `yes` will either bind
+ # with the admin credentials or the credentials from the rebind url depending
+ # on `use_referral_credentials`.
#
rebind = yes
return status;
}
-/** Bind to the LDAP directory as a user
- *
- * Performs a simple bind to the LDAP directory, and handles any errors that occur.
- *
- * @param[in] request Current request, this may be NULL, in which case all
- * debug logging is done with log.
- * @param[in,out] pconn to use. May change as this function calls functions
- * which auto re-connect.
- * @param[in] dn of the user, may be NULL to bind anonymously.
- * @param[in] password of the user, may be NULL if no password is specified.
- * @param[in] sasl mechanism to use for bind, and additional parameters.
- * @param[in] timeout Maximum time bind is allowed to take.
- * @param[in] serverctrls Only used for SASL binds. May be NULL.
- * @param[in] clientctrls Search controls for sasl_bind.
- * Only used for SASL binds. May be NULL.
- * @return One of the LDAP_PROC_* (#fr_ldap_rcode_t) values.
- */
-fr_ldap_rcode_t fr_ldap_bind(request_t *request,
- fr_ldap_connection_t **pconn,
- char const *dn, char const *password,
-#ifdef WITH_SASL
- fr_ldap_sasl_t const *sasl,
-#else
- NDEBUG_UNUSED fr_ldap_sasl_t const *sasl,
-#endif
- fr_time_delta_t timeout,
- LDAPControl **serverctrls, LDAPControl **clientctrls)
-{
- fr_ldap_rcode_t status = LDAP_PROC_ERROR;
- fr_ldap_config_t const *handle_config = (*pconn)->config;
-
- int msgid = -1;
-
- fr_assert(*pconn && (*pconn)->handle);
-
-#ifndef WITH_SASL
- fr_assert(!sasl || !sasl->mech);
-#endif
-
- if (DEBUG_ENABLED4 || (request && RDEBUG_ENABLED4)) {
- fr_ldap_timeout_debug(request, *pconn, timeout, __FUNCTION__);
- }
-
- /*
- * Bind as anonymous user
- */
- if (!dn) dn = "";
-
-#ifdef WITH_SASL
- if (sasl && sasl->mech) {
- status = fr_ldap_sasl_interactive(request, *pconn, dn, password, sasl,
- serverctrls, clientctrls, timeout);
- } else
-#endif
- {
- int ret;
- struct berval cred;
-
- if (password) {
- memcpy(&cred.bv_val, &password, sizeof(cred.bv_val));
- cred.bv_len = talloc_array_length(password) - 1;
- } else {
- cred.bv_val = NULL;
- cred.bv_len = 0;
- }
-
- /*
- * Yes, confusingly named. This is the simple version
- * of the SASL bind function that should always be
- * available.
- */
- ret = ldap_sasl_bind((*pconn)->handle, dn, LDAP_SASL_SIMPLE, &cred,
- serverctrls, clientctrls, &msgid);
-
- /* We got a valid message ID */
- if ((ret == 0) && (msgid >= 0)) ROPTIONAL(RDEBUG2, DEBUG2, "Waiting for bind result...");
-
- status = fr_ldap_result(NULL, NULL, *pconn, msgid, 0, dn, fr_time_delta_wrap(0));
- }
-
- switch (status) {
- case LDAP_PROC_SUCCESS:
- ROPTIONAL(RDEBUG2, DEBUG2, "Bind successful");
- break;
-
- case LDAP_PROC_NOT_PERMITTED:
- ROPTIONAL(RPEDEBUG, PERROR, "Bind as \"%s\" to \"%s\" not permitted",
- *dn ? dn : "(anonymous)", handle_config->server);
- break;
-
- default:
- ROPTIONAL(RPEDEBUG, PERROR, "Bind as \"%s\" to \"%s\" failed",
- *dn ? dn : "(anonymous)", handle_config->server);
- break;
- }
-
- return status; /* caller closes the connection */
-}
-
-/** Search for something in the LDAP directory
- *
- * Binds as the administrative user and performs a search, dealing with any errors.
- *
- * @param[out] result Where 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.
- * @param[in] request Current request.
- * @param[in,out] pconn to use. May change as this function calls functions which auto re-connect.
- * @param[in] dn to use as base for the search.
- * @param[in] scope to use (LDAP_SCOPE_BASE, LDAP_SCOPE_ONE, LDAP_SCOPE_SUB).
- * @param[in] filter to use, should be pre-escaped.
- * @param[in] attrs to retrieve.
- * @param[in] serverctrls Search controls to pass to the server. May be NULL.
- * @param[in] clientctrls Search controls for ldap_search. May be NULL.
- * @return One of the LDAP_PROC_* (#fr_ldap_rcode_t) values.
- */
-fr_ldap_rcode_t fr_ldap_search(LDAPMessage **result, request_t *request,
- fr_ldap_connection_t **pconn,
- char const *dn, int scope, char const *filter, char const * const *attrs,
- LDAPControl **serverctrls, LDAPControl **clientctrls)
-{
- fr_ldap_rcode_t status = LDAP_PROC_ERROR;
- LDAPMessage *our_result = NULL;
-
- fr_ldap_config_t const *handle_config = (*pconn)->config;
-
- int msgid; // Message id returned by
- // ldap_search_ext.
-
- int count = 0; // Number of results we got.
-
- struct timeval tv; // Holds timeout values.
-
- LDAPControl *our_serverctrls[LDAP_MAX_CONTROLS];
- LDAPControl *our_clientctrls[LDAP_MAX_CONTROLS];
-
- fr_ldap_control_merge(our_serverctrls, our_clientctrls,
- NUM_ELEMENTS(our_serverctrls),
- NUM_ELEMENTS(our_clientctrls),
- *pconn, serverctrls, clientctrls);
-
- fr_assert(*pconn && (*pconn)->handle);
-
- if (DEBUG_ENABLED4 || (request && RDEBUG_ENABLED4)) {
- fr_ldap_timeout_debug(request, *pconn, fr_time_delta_wrap(0), __FUNCTION__);
- }
-
- /*
- * OpenLDAP library doesn't declare attrs array as const, but
- * it really should be *sigh*.
- */
- char **search_attrs;
- memcpy(&search_attrs, &attrs, sizeof(attrs));
-
- /*
- * Do all searches as the admin user.
- */
- if ((*pconn)->rebound) {
- status = fr_ldap_bind(request, pconn,
- (*pconn)->config->admin_identity, (*pconn)->config->admin_password,
- &(*pconn)->config->admin_sasl, fr_time_delta_wrap(0),
- NULL, NULL);
- if (status != LDAP_PROC_SUCCESS) return LDAP_PROC_ERROR;
-
- fr_assert(*pconn);
-
- (*pconn)->rebound = false;
- }
-
- if (filter) {
- ROPTIONAL(RDEBUG2, DEBUG2, "Performing search in \"%s\" with filter \"%s\", scope \"%s\"", dn, filter,
- fr_table_str_by_value(fr_ldap_scope, scope, "<INVALID>"));
- } else {
- ROPTIONAL(RDEBUG2, DEBUG2, "Performing unfiltered search in \"%s\", scope \"%s\"", dn,
- fr_table_str_by_value(fr_ldap_scope, scope, "<INVALID>"));
- }
- /*
- * If LDAP search produced an error it should also be logged
- * to the ld. result should pick it up without us
- * having to pass it explicitly.
- */
- memset(&tv, 0, sizeof(tv));
-
- (void) ldap_search_ext((*pconn)->handle, dn, scope, filter, search_attrs,
- 0, our_serverctrls, our_clientctrls, NULL, 0, &msgid);
-
- ROPTIONAL(RDEBUG2, DEBUG2, "Waiting for search result...");
- status = fr_ldap_result(&our_result, NULL, *pconn, msgid, 1, dn, fr_time_delta_wrap(0));
- switch (status) {
- case LDAP_PROC_SUCCESS:
- break;
-
- case LDAP_PROC_BAD_DN:
- ROPTIONAL(RDEBUG2, DEBUG2, "DN %s does not exist", dn);
- break;
-
- default:
- ROPTIONAL(RPEDEBUG, PERROR, "Failed performing search");
-
- goto finish;
- }
-
- count = ldap_count_entries((*pconn)->handle, our_result);
- if (count < 0) {
- ROPTIONAL(REDEBUG, ERROR, "Error counting results: %s", fr_ldap_error_str(*pconn));
- status = LDAP_PROC_ERROR;
-
- ldap_msgfree(our_result);
- our_result = NULL;
- } else if (count == 0) {
- ROPTIONAL(RDEBUG2, DEBUG2, "Search returned no results");
- status = LDAP_PROC_NO_RESULT;
-
- ldap_msgfree(our_result);
- our_result = NULL;
- }
-
-finish:
-
- /*
- * We always need to get the result to count entries, but the caller
- * may not of requested one. If that's the case, free it, else write
- * it to where our caller said.
- */
- if (!result) {
- if (our_result) ldap_msgfree(our_result);
- } else {
- *result = our_result;
- }
-
- return status;
-}
-
/** Search for something in the LDAP directory
*
* Binds as the administrative user and performs a search, dealing with any errors.
* @param[in] clientctrls Search controls for ldap_modify. May be NULL.
* @return One of the LDAP_PROC_* (#fr_ldap_rcode_t) values.
*/
-fr_ldap_rcode_t fr_ldap_modify(request_t *request, fr_ldap_connection_t **pconn,
- char const *dn, LDAPMod *mods[],
- LDAPControl **serverctrls, LDAPControl **clientctrls)
-{
- fr_ldap_rcode_t status = LDAP_PROC_ERROR;
-
- int msgid; // Message id returned by ldap_search_ext.
-
- LDAPControl *our_serverctrls[LDAP_MAX_CONTROLS];
- LDAPControl *our_clientctrls[LDAP_MAX_CONTROLS];
-
- fr_ldap_control_merge(our_serverctrls, our_clientctrls,
- NUM_ELEMENTS(our_serverctrls),
- NUM_ELEMENTS(our_clientctrls),
- *pconn, serverctrls, clientctrls);
-
- fr_assert(*pconn && (*pconn)->handle);
-
- if (RDEBUG_ENABLED4) fr_ldap_timeout_debug(request, *pconn, fr_time_delta_wrap(0), __FUNCTION__);
-
- /*
- * Perform all modifications as the admin user.
- */
- if ((*pconn)->rebound) {
- status = fr_ldap_bind(request, pconn,
- (*pconn)->config->admin_identity, (*pconn)->config->admin_password,
- &(*pconn)->config->admin_sasl,
- fr_time_delta_wrap(0), NULL, NULL);
- if (status != LDAP_PROC_SUCCESS) {
- return LDAP_PROC_ERROR;
- }
-
- fr_assert(*pconn);
-
- (*pconn)->rebound = false;
- }
-
- RDEBUG2("Modifying object with DN \"%s\"", dn);
- (void) ldap_modify_ext((*pconn)->handle, dn, mods, our_serverctrls, our_clientctrls, &msgid);
-
- RDEBUG2("Waiting for modify result...");
- status = fr_ldap_result(NULL, NULL, *pconn, msgid, 0, dn, fr_time_delta_wrap(0));
- switch (status) {
- case LDAP_PROC_SUCCESS:
- break;
-
- case LDAP_PROC_BAD_CONN:
- default:
- ROPTIONAL(RPEDEBUG, RPERROR, "Failed modifying object");
-
- goto finish;
- }
-
-finish:
- return status;
-}
-
-/** Modify something in the LDAP directory
- *
- * @param[in] request Current request.
- * @param[in,out] pconn to use. May change as this function calls functions which auto re-connect.
- * @param[in] dn of the object to modify.
- * @param[in] mods to make, see 'man ldap_modify' for more information.
- * @param[in] serverctrls Search controls to pass to the server. May be NULL.
- * @param[in] clientctrls Search controls for ldap_modify. May be NULL.
- * @return One of the LDAP_PROC_* (#fr_ldap_rcode_t) values.
- */
fr_ldap_rcode_t fr_ldap_modify_async(int *msgid, request_t *request, fr_ldap_connection_t **pconn,
char const *dn, LDAPMod *mods[],
LDAPControl **serverctrls, LDAPControl **clientctrls)
uint16_t referral_depth; //!< How many referrals to chase
- bool rebind; //!< Controls whether we set an ldad_rebind_proc function
- ///< and so determines if we can bind to other servers whilst
- ///< chasing referrals. If this is false, we will still chase
- ///< referrals on the same server, but won't bind to other
- ///< servers.
+ bool rebind; //!< If use_referral_credentials is false, controls whether we
+ ///< bind as our admin credentials (true) or anonymously (false)
+ ///< when connecting to a different server to follow a referral
/*
* TLS items.
typedef struct {
LDAP *handle; //!< libldap handle.
- bool rebound; //!< Whether the connection has been rebound to something
- ///< other than the admin user.
- bool referred; //!< Whether the connection is now established a server
- ///< other than the configured one.
-
fr_ldap_control_t serverctrls[LDAP_MAX_CONTROLS + 1]; //!< Server controls to use for all operations
///< with this handle.
fr_ldap_control_t clientctrls[LDAP_MAX_CONTROLS + 1]; //!< Client controls to use for all operations
ssize_t fr_ldap_xlat_filter(request_t *request, char const **sub, size_t sublen, char *out, size_t outlen);
-fr_ldap_rcode_t fr_ldap_bind(request_t *request,
- fr_ldap_connection_t **pconn,
- char const *dn, char const *password,
-#ifdef WITH_SASL
- fr_ldap_sasl_t const *sasl,
-#else
- NDEBUG_UNUSED fr_ldap_sasl_t const *sasl,
-#endif
- fr_time_delta_t timeout,
- LDAPControl **serverctrls, LDAPControl **clientctrls);
-
char const *fr_ldap_error_str(fr_ldap_connection_t const *conn);
-fr_ldap_rcode_t fr_ldap_search(LDAPMessage **result, request_t *request,
- fr_ldap_connection_t **pconn,
- char const *dn, int scope, char const *filter, char const * const * attrs,
- LDAPControl **serverctrls, LDAPControl **clientctrls);
-
fr_ldap_rcode_t fr_ldap_search_async(int *msgid, request_t *request,
fr_ldap_connection_t **pconn,
char const *dn, int scope, char const *filter, char const * const *attrs,
LDAPControl **serverctrls, LDAPControl **clientctrls);
-fr_ldap_rcode_t fr_ldap_modify(request_t *request, fr_ldap_connection_t **pconn,
- char const *dn, LDAPMod *mods[],
- LDAPControl **serverctrls, LDAPControl **clientctrls);
-
fr_ldap_rcode_t fr_ldap_modify_async(int *msgid, request_t *request, fr_ldap_connection_t **pconn,
char const *dn, LDAPMod *mods[],
LDAPControl **serverctrls, LDAPControl **clientctrls);
/*
* directory.c - Get directory capabilities from the remote server
*/
-int fr_ldap_directory_alloc(TALLOC_CTX *ctx, fr_ldap_directory_t **out, fr_ldap_connection_t **pconn);
-
int fr_ldap_trunk_directory_alloc_async(TALLOC_CTX *ctx, fr_ldap_thread_trunk_t *ttrunk);
/*
/* Define to 1 if you have the `ldap_sasl_interactive_bind' function. */
#undef HAVE_LDAP_SASL_INTERACTIVE_BIND
-/* Define to 1 if you have the `ldap_set_rebind_proc' function. */
-#undef HAVE_LDAP_SET_REBIND_PROC
-
/* Define to 1 if you have the `ldap_start_tls_s' function. */
#undef HAVE_LDAP_START_TLS_S
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
-/* Number of arguments the rebind procedure takes */
-#undef LDAP_SET_REBIND_PROC_ARGS
-
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
then :
printf "%s\n" "#define HAVE_LDAP_INITIALIZE 1" >>confdefs.h
-fi
-ac_fn_c_check_func "$LINENO" "ldap_set_rebind_proc" "ac_cv_func_ldap_set_rebind_proc"
-if test "x$ac_cv_func_ldap_set_rebind_proc" = xyes
-then :
- printf "%s\n" "#define HAVE_LDAP_SET_REBIND_PROC 1" >>confdefs.h
-
fi
ac_fn_c_check_func "$LINENO" "ldap_create_sort_control" "ac_cv_func_ldap_create_sort_control"
if test "x$ac_cv_func_ldap_create_sort_control" = xyes
fi
printf "%s\n" "#define HAVE_DECL_LDAP_CREATE_SESSION_TRACKING_CONTROL $ac_have_decl" >>confdefs.h
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ldap_set_rebind_proc takes 3 arguments" >&5
-printf %s "checking whether ldap_set_rebind_proc takes 3 arguments... " >&6; }
-if test ${ac_cv_ldap_set_rebind_proc+y}
-then :
- printf %s "(cached) " >&6
-else $as_nop
-
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
- #include <lber.h>
- #include <ldap.h>
-int
-main (void)
-{
-ldap_set_rebind_proc(0, 0, 0);
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"
-then :
- ac_cv_ldap_set_rebind_proc=3
-else $as_nop
- ac_cv_ldap_set_rebind_proc=2
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
-
-fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_ldap_set_rebind_proc" >&5
-printf "%s\n" "$ac_cv_ldap_set_rebind_proc" >&6; }
fi
printf "%s\n" "#define WITH_EDIR 1" >>confdefs.h
-printf "%s\n" "#define LDAP_SET_REBIND_PROC_ARGS ${ac_cv_ldap_set_rebind_proc}" >>confdefs.h
-
-
mod_ldflags=$SMART_LIBS
mod_cflags="$SMART_CPPFLAGS"
ldap_unbind_ext_s \
ldap_start_tls_s \
ldap_initialize \
- ldap_set_rebind_proc \
ldap_create_sort_control \
ldap_create_sort_keylist \
ldap_free_sort_keylist \
)
AC_CHECK_DECLS([ldap_create_session_tracking_control], [], [], [[#include <ldap.h>]])
- AC_CACHE_CHECK(whether ldap_set_rebind_proc takes 3 arguments, ac_cv_ldap_set_rebind_proc, [
- AC_TRY_COMPILE([
- #include <lber.h>
- #include <ldap.h>], [ldap_set_rebind_proc(0, 0, 0);],
- [ac_cv_ldap_set_rebind_proc=3],
- [ac_cv_ldap_set_rebind_proc=2])
- ])
fi
dnl ############################################################
fi
AC_DEFINE(WITH_EDIR, 1, [Build the server with support for Novell eDir Universal Password])
-AC_DEFINE_UNQUOTED(LDAP_SET_REBIND_PROC_ARGS, ${ac_cv_ldap_set_rebind_proc}, [Number of arguments the rebind procedure takes])
mod_ldflags=$SMART_LIBS
mod_cflags="$SMART_CPPFLAGS"
c->config = config;
c->handle = handle;
- c->rebound = false;
- c->referred = false;
/*
* We now have a connection structure, but no actual connection.
static fr_table_num_sorted_t const fr_ldap_directory_type_table[] = {
{ L("Active Directory"), FR_LDAP_DIRECTORY_ACTIVE_DIRECTORY },
- { L("IBM"), FR_LDAP_DIRECTORY_IBM },
+ { L("IBM"), FR_LDAP_DIRECTORY_IBM },
{ L("NetScape"), FR_LDAP_DIRECTORY_NETSCAPE },
{ L("OpenLDAP"), FR_LDAP_DIRECTORY_OPENLDAP },
{ L("Oracle Internet Directory"), FR_LDAP_DIRECTORY_ORACLE_INTERNET_DIRECTORY },
{ L("Siemens AG"), FR_LDAP_DIRECTORY_SIEMENS_AG },
{ L("Sun One Directory"), FR_LDAP_DIRECTORY_SUN_ONE_DIRECTORY },
{ L("Unbound ID"), FR_LDAP_DIRECTORY_UNBOUND_ID },
- { L("Unknown"), FR_LDAP_DIRECTORY_UNKNOWN },
+ { L("Unknown"), FR_LDAP_DIRECTORY_UNKNOWN },
{ L("eDirectory"), FR_LDAP_DIRECTORY_EDIRECTORY }
};
static size_t fr_ldap_directory_type_table_len = NUM_ELEMENTS(fr_ldap_directory_type_table);
return 0;
}
-/** Extract useful information from the rootDSE of the LDAP server
- *
- * @param[in] ctx to allocate fr_ldap_directory_t in.
- * @param[out] out where to write pointer to new fr_ldap_directory_t struct.
- * @param[in,out] pconn connection for querying the directory.
- * @return
- * - 0 on success.
- * - 1 if we failed identifying the directory server.
- * - -1 on error.
- */
-int fr_ldap_directory_alloc(TALLOC_CTX *ctx, fr_ldap_directory_t **out, fr_ldap_connection_t **pconn)
-{
- static char const *attrs[] = { "vendorname",
- "vendorversion",
- "isGlobalCatalogReady",
- "objectClass",
- "orcldirectoryversion",
- NULL };
- fr_ldap_rcode_t status;
- int rcode = 0;
- fr_ldap_directory_t *directory;
- char const *name = (*pconn)->config->name;
-
- LDAPMessage *result = NULL;
-
- *out = NULL;
-
- directory = talloc_zero(ctx, fr_ldap_directory_t);
- if (!directory) return -2;
- *out = directory;
-
- directory->type = FR_LDAP_DIRECTORY_UNKNOWN;
-
- status = fr_ldap_search(&result, NULL, pconn, "", LDAP_SCOPE_BASE, "(objectclass=*)",
- attrs, NULL, NULL);
- switch (status) {
- case LDAP_PROC_SUCCESS:
- break;
-
- case LDAP_PROC_NO_RESULT:
- WARN("Capability check failed: Can't access rootDSE");
- rcode = 1;
- goto finish;
-
- default:
- rcode = 1;
- goto finish;
- }
-
- rcode = ldap_directory_result_parse(directory, (*pconn)->handle, result, name);
-
-finish:
- if (result) ldap_msgfree(result);
-
- return rcode;
-}
-
/** Parse results of search on rootDSE to gather data on LDAP server
*
* @param[in] query which requested the rootDSE.
static int proto_ldap_socket_open(UNUSED CONF_SECTION *cs, rad_listen_t *listen)
{
proto_ldap_inst_t *inst = listen->data;
+#if 0
fr_ldap_rcode_t status;
+#endif
size_t i;
struct sockaddr_storage addr;
return -1;
}
}
-
+#if 0
status = fr_ldap_bind(NULL,
&inst->conn,
inst->conn->config->admin_identity, inst->conn->config->admin_password,
* We need to know the directory type so we can synthesize cookies
*/
if (fr_ldap_directory_alloc(inst->conn, &inst->conn->directory, &inst->conn) < 0) goto error;
-
+#endif
if (ldap_get_option(inst->conn->handle, LDAP_OPT_DESC, &listen->fd) != LDAP_OPT_SUCCESS) {
int ldap_errno;
TARGET := $(TARGETNAME).a
endif
-SOURCES := $(TARGETNAME).c conn.c groups.c user.c
+SOURCES := $(TARGETNAME).c groups.c user.c
SRC_CFLAGS += -I$(top_builddir)/src/modules/rlm_ldap
TGT_PREREQS := libfreeradius-ldap.a
+++ /dev/null
-/*
- * This program is is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-/**
- * $Id$
- * @file rlm_ldap.c
- * @brief Connection wrappers
- *
- * @author Arran Cudbard-Bell (a.cudbardb@freeradius.org)
- *
- * @copyright 2017 The FreeRADIUS Server Project.
- */
-RCSID("$Id$")
-
-USES_APPLE_DEPRECATED_API
-
-#define LOG_PREFIX "%s - "
-#define LOG_PREFIX_ARGS handle_config->name
-
-#include <freeradius-devel/util/debug.h>
-
-#include "rlm_ldap.h"
-
-/** 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).
- *
- * @param inst rlm_ldap configuration.
- * @param request Current request (may be NULL).
- */
-fr_ldap_connection_t *mod_conn_get(rlm_ldap_t const *inst, request_t *request)
-{
- fr_ldap_connection_t *conn;
-
- conn = fr_pool_connection_get(inst->pool, request);
-
- fr_assert(!conn || conn->config);
-
-#ifdef LDAP_CONTROL_X_SESSION_TRACKING
- /*
- * Add optional session tracking controls,
- * that contain values of some attributes
- * in the request.
- */
- if ((conn != NULL) && (request != NULL) && inst->session_tracking) {
- if (fr_ldap_control_add_session_tracking(conn, request) < 0) {
- fr_pool_connection_release(inst->pool, request, conn);
- return NULL;
- }
- }
-#endif
- return conn;
-}
-
-/** Releases 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.
- *
- * @param inst rlm_ldap configuration.
- * @param request The current request.
- * @param conn to release.
- */
-void ldap_mod_conn_release(rlm_ldap_t const *inst, request_t *request, fr_ldap_connection_t *conn)
-{
- /*
- * Could have already been free'd due to a previous error.
- */
- if (!conn) return;
-
- /*
- * Clear any client/server controls associated with the connection.
- */
- fr_ldap_control_clear(conn);
-
- /*
- * We chased a referral to another server.
- *
- * This connection is no longer part of the pool which is
- * connected to and bound to the configured server.
- * Close it.
- *
- * Note that we do NOT close it if it was bound to another user.
- * Instead, we let the next caller do the rebind.
- */
- if (conn->referred) {
- fr_pool_connection_close(inst->pool, request, conn);
- return;
- }
-
- fr_pool_connection_release(inst->pool, request, conn);
- return;
-}
-
-/** Create and return a new connection
- *
- * Create a new ldap connection and allocate memory for a new rlm_handle_t
- */
-void *ldap_mod_conn_create(TALLOC_CTX *ctx, void *instance, fr_time_delta_t timeout)
-{
- fr_ldap_rcode_t status;
- fr_ldap_connection_t *conn;
- fr_ldap_config_t const *handle_config = instance; /* Not talloced */
-
- conn = fr_ldap_connection_alloc(ctx);
- if (!conn) return NULL;
-
- if (fr_ldap_connection_configure(conn, handle_config) < 0) {
- talloc_free(conn);
- return NULL;
- }
-
- fr_ldap_connection_timeout_set(conn, timeout);
- if (handle_config->start_tls) {
- if (ldap_start_tls_s(conn->handle, NULL, NULL) != LDAP_SUCCESS) {
- int ldap_errno;
-
- ldap_get_option(conn->handle, LDAP_OPT_ERROR_NUMBER, &ldap_errno);
-
- ERROR("Could not start TLS: %s", ldap_err2string(ldap_errno));
-
- error:
- talloc_free(conn);
-
- return NULL;
- }
- }
-
- status = fr_ldap_bind(NULL,
- &conn,
- conn->config->admin_identity, conn->config->admin_password,
- &(conn->config->admin_sasl),
- timeout,
- NULL, NULL);
- if (status != LDAP_PROC_SUCCESS) goto error;
- fr_ldap_connection_timeout_reset(conn);
-
- /*
- * Only error out on memory allocation errors
- */
- if (fr_ldap_directory_alloc(conn, &conn->directory, &conn) < 0) goto error;
-
- return conn;
-}
fr_ldap_thread_trunk_t *ttrunk,
char **names, char **out, size_t outlen)
{
- rlm_rcode_t rcode = RLM_MODULE_OK;
- int ldap_errno;
+ rlm_rcode_t rcode = RLM_MODULE_OK;
+ int ldap_errno;
- unsigned int name_cnt = 0;
- unsigned int entry_cnt;
- char const *attrs[] = { NULL };
+ unsigned int name_cnt = 0;
+ unsigned int entry_cnt;
+ char const *attrs[] = { NULL };
- LDAPMessage *entry;
+ LDAPMessage *entry;
fr_ldap_query_t *query = NULL;
- char **name = names;
- char **dn = out;
- char const *base_dn = NULL;
- char base_dn_buff[LDAP_MAX_DN_STR_LEN];
- char buffer[LDAP_MAX_GROUP_NAME_LEN + 1];
+ char **name = names;
+ char **dn = out;
+ char const *base_dn = NULL;
+ char base_dn_buff[LDAP_MAX_DN_STR_LEN];
+ char buffer[LDAP_MAX_GROUP_NAME_LEN + 1];
- char *filter;
+ char *filter;
*dn = NULL;
static unlang_action_t rlm_ldap_group_dn2name(rlm_rcode_t *p_result, rlm_ldap_t const *inst, request_t *request,
fr_ldap_thread_trunk_t *ttrunk, char const *dn, char **out)
{
- rlm_rcode_t rcode = RLM_MODULE_OK;
- int ldap_errno;
+ rlm_rcode_t rcode = RLM_MODULE_OK;
+ int ldap_errno;
- struct berval **values = NULL;
- char const *attrs[] = { inst->groupobj_name_attr, NULL };
+ struct berval **values = NULL;
+ char const *attrs[] = { inst->groupobj_name_attr, NULL };
LDAPMessage *entry;
fr_ldap_query_t *query = NULL;
unlang_action_t rlm_ldap_cacheable_groupobj(rlm_rcode_t *p_result, rlm_ldap_t const *inst,
request_t *request, fr_ldap_thread_trunk_t *ttrunk)
{
- rlm_rcode_t rcode = RLM_MODULE_OK;
- int ldap_errno;
+ rlm_rcode_t rcode = RLM_MODULE_OK;
+ int ldap_errno;
- LDAPMessage *entry;
+ LDAPMessage *entry;
fr_ldap_query_t *query;
- char const *base_dn;
- char base_dn_buff[LDAP_MAX_DN_STR_LEN];
+ char const *base_dn;
+ char base_dn_buff[LDAP_MAX_DN_STR_LEN];
- char const *filters[] = { inst->groupobj_filter, inst->groupobj_membership_filter };
- char filter[LDAP_MAX_FILTER_STR_LEN + 1];
+ char const *filters[] = { inst->groupobj_filter, inst->groupobj_membership_filter };
+ char filter[LDAP_MAX_FILTER_STR_LEN + 1];
- char const *attrs[] = { inst->groupobj_name_attr, NULL };
+ char const *attrs[] = { inst->groupobj_name_attr, NULL };
- fr_pair_t *vp;
- char *dn;
+ fr_pair_t *vp;
+ char *dn;
fr_assert(inst->groupobj_base_dn);
}
}
-#if !defined (LDAP_SET_REBIND_PROC_ARGS) || LDAP_SET_REBIND_PROC_ARGS != 3
- /*
- * The 2-argument rebind doesn't take an instance variable. Our rebind function needs the instance
- * variable for the username, password, etc.
- */
- if (inst->handle_config.rebind == true) {
- cf_log_err(conf, "Cannot use 'rebind' configuration item as this version of libldap "
- "does not support the API that we need");
-
- goto error;
- }
-#endif
-
/*
* Convert scope strings to enumerated constants
*/
unlang_action_t rlm_ldap_check_cached(rlm_rcode_t *p_result,
rlm_ldap_t const *inst, request_t *request, fr_pair_t const *check);
-
-/*
- * conn.c - Connection wrappers.
- */
-fr_ldap_connection_t *mod_conn_get(rlm_ldap_t const *inst, request_t *request);
-
-void ldap_mod_conn_release(rlm_ldap_t const *inst, request_t *request, fr_ldap_connection_t *conn);
-
-void *ldap_mod_conn_create(TALLOC_CTX *ctx, void *instance, fr_time_delta_t timeout);