Skip to content

Commit

Permalink
Merge r1878890 from trunk:
Browse files Browse the repository at this point in the history
mod_ldap: Use the LDAP API directly to implement the rebind callback
for modern versions of OpenLDAP, avoiding the overhead of the apr-util
implementation.

* modules/ldap/util_ldap.c:
  Define USE_APR_LDAP_REBIND if a modern version of OpenLDAP is used.
  (uldap_rebind_proc): New function.
  (uldap_rebind_init, uldap_rebind_add): Define, using either the
  callback or the (bad) APR-util versions.
  (uldap_connection_unbind): Clear the rebind pool to remove rebind
  references prior to destroying the LDAP *.
  Omit for !USE_APR_LDAP_REBIND.
  (uldap_connection_init): Use new wrappers, only create the rebind
  pool if USE_APR_LDAP_REBIND.

* include/util_ldap.h: Don't include apr_ldap_rebind.h here.

PR: 64414
Github: closes #124
Reviewed by: jorton, covener, ylavic (by inspection)



git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1910853 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
notroj committed Jul 7, 2023
1 parent 981c250 commit 85be535
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 9 deletions.
2 changes: 2 additions & 0 deletions changes-entries/ldap-rebind.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*) mod_ldap: Avoid performance overhead of APR-util rebind cache for
OpenLDAP 2.2+. PR 64414. [Joe Orton]
1 change: 0 additions & 1 deletion include/util_ldap.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
#if APR_MAJOR_VERSION < 2
/* The LDAP API is currently only present in APR 1.x */
#include "apr_ldap.h"
#include "apr_ldap_rebind.h"
#else
#define APR_HAS_LDAP 0
#endif
Expand Down
51 changes: 43 additions & 8 deletions modules/ldap/util_ldap.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,38 @@ module AP_MODULE_DECLARE_DATA ldap_module;
static const char *ldap_cache_mutex_type = "ldap-cache";
static apr_status_t uldap_connection_unbind(void *param);

/* For OpenLDAP with the 3-arg version of ldap_set_rebind_proc(), use
* a simpler rebind callback than the implementation in APR-util.
* Testing for API version >= 3001 appears safe although OpenLDAP
* 2.1.x (API version = 2004) also has the 3-arg API. */
#if APR_HAS_OPENLDAP_LDAPSDK && defined(LDAP_API_VERSION) && LDAP_API_VERSION >= 3001

#define uldap_rebind_init(p) APR_SUCCESS /* noop */

static int uldap_rebind_proc(LDAP *ld, const char *url, ber_tag_t request,
ber_int_t msgid, void *params)
{
util_ldap_connection_t *ldc = params;

return ldap_bind_s(ld, ldc->binddn, ldc->bindpw, LDAP_AUTH_SIMPLE);
}

static apr_status_t uldap_rebind_add(util_ldap_connection_t *ldc)
{
ldap_set_rebind_proc(ldc->ldap, uldap_rebind_proc, ldc);
return APR_SUCCESS;
}

#else /* !APR_HAS_OPENLDAP_LDAPSDK */

#define USE_APR_LDAP_REBIND
#include <apr_ldap_rebind.h>

#define uldap_rebind_init(p) apr_ldap_rebind_init(p)
#define uldap_rebind_add(ldc) apr_ldap_rebind_add((ldc)->rebind_pool, \
(ldc)->ldap, (ldc)->binddn, \
(ldc)->bindpw)
#endif

static APR_INLINE apr_status_t ldap_cache_lock(util_ldap_state_t *st, request_rec *r) {
apr_status_t rv = APR_SUCCESS;
Expand Down Expand Up @@ -195,6 +227,13 @@ static apr_status_t uldap_connection_unbind(void *param)
util_ldap_connection_t *ldc = param;

if (ldc) {
#ifdef USE_APR_LDAP_REBIND
/* forget the rebind info for this conn */
if (ldc->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) {
apr_pool_clear(ldc->rebind_pool);
}
#endif

if (ldc->ldap) {
if (ldc->r) {
ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, ldc->r, "LDC %pp unbind", ldc);
Expand All @@ -203,12 +242,6 @@ static apr_status_t uldap_connection_unbind(void *param)
ldc->ldap = NULL;
}
ldc->bound = 0;

/* forget the rebind info for this conn */
if (ldc->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) {
apr_ldap_rebind_remove(ldc->ldap);
apr_pool_clear(ldc->rebind_pool);
}
}

return APR_SUCCESS;
Expand Down Expand Up @@ -344,7 +377,7 @@ static int uldap_connection_init(request_rec *r,

if (ldc->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) {
/* Now that we have an ldap struct, add it to the referral list for rebinds. */
rc = apr_ldap_rebind_add(ldc->rebind_pool, ldc->ldap, ldc->binddn, ldc->bindpw);
rc = uldap_rebind_add(ldc);
if (rc != APR_SUCCESS) {
ap_log_error(APLOG_MARK, APLOG_ERR, rc, r->server, APLOGNO(01277)
"LDAP: Unable to add rebind cross reference entry. Out of memory?");
Expand Down Expand Up @@ -870,6 +903,7 @@ static util_ldap_connection_t *
/* whether or not to keep this connection in the pool when it's returned */
l->keep = (st->connection_pool_ttl == 0) ? 0 : 1;

#ifdef USE_APR_LDAP_REBIND
if (l->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) {
if (apr_pool_create(&(l->rebind_pool), l->pool) != APR_SUCCESS) {
ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, APLOGNO(01286)
Expand All @@ -881,6 +915,7 @@ static util_ldap_connection_t *
}
apr_pool_tag(l->rebind_pool, "util_ldap_rebind");
}
#endif

if (p) {
p->next = l;
Expand Down Expand Up @@ -3070,7 +3105,7 @@ static int util_ldap_post_config(apr_pool_t *p, apr_pool_t *plog,
}

/* Initialize the rebind callback's cross reference list. */
apr_ldap_rebind_init (p);
(void) uldap_rebind_init(p);

#ifdef AP_LDAP_OPT_DEBUG
if (st->debug_level > 0) {
Expand Down

0 comments on commit 85be535

Please sign in to comment.