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