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