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