You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by jo...@apache.org on 2020/06/16 14:31:27 UTC

svn commit: r1878890 - in /httpd/httpd/trunk: CHANGES include/util_ldap.h modules/ldap/util_ldap.c

Author: jorton
Date: Tue Jun 16 14:31:26 2020
New Revision: 1878890

URL: http://svn.apache.org/viewvc?rev=1878890&view=rev
Log:
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 OpenSSL 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

Modified:
    httpd/httpd/trunk/CHANGES
    httpd/httpd/trunk/include/util_ldap.h
    httpd/httpd/trunk/modules/ldap/util_ldap.c

Modified: httpd/httpd/trunk/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/CHANGES?rev=1878890&r1=1878889&r2=1878890&view=diff
==============================================================================
--- httpd/httpd/trunk/CHANGES [utf-8] (original)
+++ httpd/httpd/trunk/CHANGES [utf-8] Tue Jun 16 14:31:26 2020
@@ -1,6 +1,8 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.5.1
 
+  *) mod_ldap: Avoid performance overhead of APR-util rebind cache for
+     OpenLDAP 2.2+.  PR 64414.  [Joe Orton]
 
   *) core: Have the HTTP 0.9 / 1.1 processing code reject requests for
      HTTP >= 2.0 with a HTTP Version Not Support status code. [Ruediger Pluem]

Modified: httpd/httpd/trunk/include/util_ldap.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/include/util_ldap.h?rev=1878890&r1=1878889&r2=1878890&view=diff
==============================================================================
--- httpd/httpd/trunk/include/util_ldap.h (original)
+++ httpd/httpd/trunk/include/util_ldap.h Tue Jun 16 14:31:26 2020
@@ -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

Modified: httpd/httpd/trunk/modules/ldap/util_ldap.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/ldap/util_ldap.c?rev=1878890&r1=1878889&r2=1878890&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/ldap/util_ldap.c (original)
+++ httpd/httpd/trunk/modules/ldap/util_ldap.c Tue Jun 16 14:31:26 2020
@@ -75,6 +75,38 @@ module AP_MODULE_DECLARE_DATA ldap_modul
 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;
@@ -224,6 +256,13 @@ static apr_status_t uldap_connection_unb
     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); 
@@ -232,12 +271,6 @@ static apr_status_t uldap_connection_unb
             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;
@@ -373,7 +406,7 @@ static int uldap_connection_init(request
 
     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? Try 'LDAPReferrals OFF'");
@@ -900,6 +933,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)
@@ -911,6 +945,7 @@ static util_ldap_connection_t *
             }
             apr_pool_tag(l->rebind_pool, "util_ldap_rebind");
         }
+#endif
 
         if (p) {
             p->next = l;
@@ -3116,7 +3151,7 @@ static int util_ldap_post_config(apr_poo
     }
 
     /* 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) {