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 {