Blob Blame History Raw
Index: modules/ldap/util_ldap.c
===================================================================
--- a/modules/ldap/util_ldap.c	(revision 1610395)
+++ b/modules/ldap/util_ldap.c	(revision 1610396)
@@ -157,10 +157,12 @@
       */
      if (!ldc->keep) {
          uldap_connection_unbind(ldc);
+         ldc->r = NULL;
      }
      else {
          /* mark our connection as available for reuse */
          ldc->freed = apr_time_now();
+         ldc->r = NULL;
 #if APR_HAS_THREADS
          apr_thread_mutex_unlock(ldc->lock);
 #endif
@@ -179,6 +181,9 @@
 
     if (ldc) {
         if (ldc->ldap) {
+            if (ldc->r) { 
+                ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, ldc->r, "LDC %pp unbind", ldc); 
+            }
             ldap_unbind_s(ldc->ldap);
             ldc->ldap = NULL;
         }
@@ -319,6 +324,8 @@
         return(result->rc);
     }
 
+    ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, "LDC %pp init", ldc);
+
     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);
@@ -516,6 +523,10 @@
         ldc->reason = "LDAP: ldap_simple_bind() parse result failed";
         return uldap_ld_errno(ldc);
     }
+    else { 
+        ldc->last_backend_conn = ldc->r->request_time;
+        ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, ldc->r, "LDC %pp bind", ldc);
+    }
     return rc;
 }
 
@@ -540,7 +551,7 @@
 
     /* If the connection is already bound, return
     */
-    if (ldc->bound)
+    if (ldc->bound && !ldc->must_rebind)
     {
         ldc->reason = "LDAP: connection open successful (already bound)";
         return LDAP_SUCCESS;
@@ -621,6 +632,7 @@
     }
     else {
         ldc->bound = 1;
+        ldc->must_rebind = 0;
         ldc->reason = "LDAP: connection open successful";
     }
 
@@ -718,13 +730,17 @@
             && !compare_client_certs(dc->client_certs, l->client_certs))
         {
             if (st->connection_pool_ttl > 0) {
-                if (l->bound && (now - l->freed) > st->connection_pool_ttl) {
+                if (l->bound && (now - l->last_backend_conn) > st->connection_pool_ttl) {
                     ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                                   "Removing LDAP connection last used %" APR_TIME_T_FMT " seconds ago",
-                                  (now - l->freed) / APR_USEC_PER_SEC);
+                                  (now - l->last_backend_conn) / APR_USEC_PER_SEC);
+                    l->r = r;
                     uldap_connection_unbind(l);
                     /* Go ahead (by falling through) and use it, so we don't create more just to unbind some other old ones */
                 }
+                ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, 
+                              "Reuse %s LDC %pp", 
+                              l->bound ? "bound" : "unbound", l);
             }
             break;
         }
@@ -751,12 +767,25 @@
                 (l->deref == deref) && (l->secure == secureflag) &&
                 !compare_client_certs(dc->client_certs, l->client_certs))
             {
+                if (st->connection_pool_ttl > 0) {
+                    if (l->bound && (now - l->last_backend_conn) > st->connection_pool_ttl) {
+                        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
+                                "Removing LDAP connection last used %" APR_TIME_T_FMT " seconds ago",
+                                (now - l->last_backend_conn) / APR_USEC_PER_SEC);
+                        l->r = r;
+                        uldap_connection_unbind(l);
+                        /* Go ahead (by falling through) and use it, so we don't create more just to unbind some other old ones */
+                    }
+                    ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, 
+                                  "Reuse %s LDC %pp (will rebind)", 
+                                   l->bound ? "bound" : "unbound", l);
+                }
+
                 /* the bind credentials have changed */
-                /* no check for connection_pool_ttl, since we are unbinding any way */
-                uldap_connection_unbind(l);
-
+                l->must_rebind = 1;
                 util_ldap_strdup((char**)&(l->binddn), binddn);
                 util_ldap_strdup((char**)&(l->bindpw), bindpw);
+
                 break;
             }
 #if APR_HAS_THREADS
@@ -846,6 +875,7 @@
 #if APR_HAS_THREADS
     apr_thread_mutex_unlock(st->mutex);
 #endif
+    l->r = r;
     return l;
 }
 
@@ -965,6 +995,7 @@
         return result;
     }
 
+    ldc->last_backend_conn = r->request_time;
     entry = ldap_first_entry(ldc->ldap, res);
     searchdn = ldap_get_dn(ldc->ldap, entry);
 
@@ -1116,6 +1147,7 @@
         goto start_over;
     }
 
+    ldc->last_backend_conn = r->request_time;
     ldc->reason = "Comparison complete";
     if ((LDAP_COMPARE_TRUE == result) ||
         (LDAP_COMPARE_FALSE == result) ||
@@ -1241,6 +1273,7 @@
         return res;
     }
 
+    ldc->last_backend_conn = r->request_time;
     entry = ldap_first_entry(ldc->ldap, sga_res);
 
     /*
@@ -1723,6 +1756,7 @@
      * We should have found exactly one entry; to find a different
      * number is an error.
      */
+    ldc->last_backend_conn = r->request_time;
     count = ldap_count_entries(ldc->ldap, res);
     if (count != 1)
     {
@@ -1788,10 +1822,10 @@
         /*
          * We have just bound the connection to a different user and password
          * combination, which might be reused unintentionally next time this
-         * connection is used from the connection pool. To ensure no confusion,
-         * we mark the connection as unbound.
+         * connection is used from the connection pool.
          */
-        ldc->bound = 0;
+        ldc->must_rebind = 0;
+        ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, "LDC %pp used for authn, must be rebound", ldc);
     }
 
     /*
@@ -1983,6 +2017,7 @@
      * We should have found exactly one entry; to find a different
      * number is an error.
      */
+    ldc->last_backend_conn = r->request_time;
     count = ldap_count_entries(ldc->ldap, res);
     if (count != 1)
     {
Index: include/util_ldap.h
===================================================================
--- a/include/util_ldap.h	(revision 1610395)
+++ b/include/util_ldap.h	(revision 1610396)
@@ -133,6 +133,9 @@
     int ReferralHopLimit;               /* # of referral hops to follow (default = AP_LDAP_DEFAULT_HOPLIMIT) */
     apr_time_t freed;                   /* the time this conn was placed back in the pool */
     apr_pool_t *rebind_pool;            /* frequently cleared pool for rebind data */
+    int must_rebind;                    /* The connection was last bound with other then binddn/bindpw */
+    request_rec *r;                     /* request_rec used to find this util_ldap_connection_t */
+    apr_time_t last_backend_conn;       /* the approximate time of the last backend LDAP requst */
 } util_ldap_connection_t;
 
 typedef struct util_ldap_config_t {