summaryrefslogtreecommitdiff
path: root/source3/nsswitch
diff options
context:
space:
mode:
authorGünther Deschner <gd@samba.org>2007-02-08 17:02:39 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:17:50 -0500
commit69cee2a3ec4f39aab83a8cbf55307df182bf3065 (patch)
tree9fa3b999223e30149041cbd17665f19f18abdb1c /source3/nsswitch
parente6ce37679f121672802ea69e21d16ea360364389 (diff)
downloadsamba-69cee2a3ec4f39aab83a8cbf55307df182bf3065.tar.gz
samba-69cee2a3ec4f39aab83a8cbf55307df182bf3065.tar.bz2
samba-69cee2a3ec4f39aab83a8cbf55307df182bf3065.zip
r21240: Fix longstanding Bug #4009.
For the winbind cached ADS LDAP connection handling (ads_cached_connection()) we were (incorrectly) assuming that the service ticket lifetime equaled the tgt lifetime. For setups where the service ticket just lives 10 minutes, we were leaving hundreds of LDAP connections in CLOSE_WAIT state, until we fail to service entirely with "Too many open files". Also sequence_number() in winbindd_ads.c needs to delete the cached LDAP connection after the ads_do_search_retry() has failed to submit the search request (although the bind succeeded (returning an expired service ticket that we cannot delete from the memory cred cache - this will get fixed later)). Guenther (This used to be commit 7e1a84b7226fb8dcd5d34c64a3478a6d886a9a91)
Diffstat (limited to 'source3/nsswitch')
-rw-r--r--source3/nsswitch/idmap_ad.c13
-rw-r--r--source3/nsswitch/winbindd_ads.c32
-rw-r--r--source3/nsswitch/winbindd_pam.c3
3 files changed, 33 insertions, 15 deletions
diff --git a/source3/nsswitch/idmap_ad.c b/source3/nsswitch/idmap_ad.c
index a0ed084765..fee53a0539 100644
--- a/source3/nsswitch/idmap_ad.c
+++ b/source3/nsswitch/idmap_ad.c
@@ -64,16 +64,23 @@ static ADS_STRUCT *ad_idmap_cached_connection_internal(void)
struct in_addr dc_ip;
if (ad_idmap_ads != NULL) {
+
+ time_t expire;
+ time_t now = time(NULL);
+
ads = ad_idmap_ads;
+ expire = MIN(ads->auth.tgt_expire, ads->auth.tgs_expire);
+
/* check for a valid structure */
+ DEBUG(7, ("Current tickets expire in %d seconds (at %d, time is now %d)\n",
+ (uint32)expire-(uint32)now, (uint32) expire, (uint32) now));
- DEBUG(7, ("Current tickets expire at %d, time is now %d\n",
- (uint32) ads->auth.expire, (uint32) time(NULL)));
- if ( ads->config.realm && (ads->auth.expire > time(NULL))) {
+ if ( ads->config.realm && (expire > time(NULL))) {
return ads;
} else {
/* we own this ADS_STRUCT so make sure it goes away */
+ DEBUG(7,("Deleting expired krb5 credential cache\n"));
ads->is_mine = True;
ads_destroy( &ads );
ads_kdestroy(WINBIND_CCACHE_NAME);
diff --git a/source3/nsswitch/winbindd_ads.c b/source3/nsswitch/winbindd_ads.c
index f572dd08ff..9c8f23b1cf 100644
--- a/source3/nsswitch/winbindd_ads.c
+++ b/source3/nsswitch/winbindd_ads.c
@@ -44,17 +44,23 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain)
DEBUG(10,("ads_cached_connection\n"));
if (domain->private_data) {
- ads = (ADS_STRUCT *)domain->private_data;
+
+ time_t expire;
+ time_t now = time(NULL);
/* check for a valid structure */
+ ads = (ADS_STRUCT *)domain->private_data;
- DEBUG(7, ("Current tickets expire at %d, time is now %d\n",
- (uint32) ads->auth.expire, (uint32) time(NULL)));
- if ( ads->config.realm && (ads->auth.expire > time(NULL))) {
+ expire = MIN(ads->auth.tgt_expire, ads->auth.tgs_expire);
+
+ DEBUG(7, ("Current tickets expire in %d seconds (at %d, time is now %d)\n",
+ (uint32)expire-(uint32)now, (uint32) expire, (uint32) now));
+
+ if ( ads->config.realm && (expire > now)) {
return ads;
- }
- else {
+ } else {
/* we own this ADS_STRUCT so make sure it goes away */
+ DEBUG(7,("Deleting expired krb5 credential cache\n"));
ads->is_mine = True;
ads_destroy( &ads );
ads_kdestroy("MEMORY:winbind_ccache");
@@ -998,11 +1004,15 @@ static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
if (!ADS_ERR_OK(rc)) {
- /* its a dead connection ; don't destroy it
- through since ads_USN() has already done
- that indirectly */
-
- domain->private_data = NULL;
+ /* its a dead connection, destroy it */
+
+ if (domain->private_data) {
+ ads = (ADS_STRUCT *)domain->private_data;
+ ads->is_mine = True;
+ ads_destroy(&ads);
+ ads_kdestroy("MEMORY:winbind_ccache");
+ domain->private_data = NULL;
+ }
}
return ads_ntstatus(rc);
}
diff --git a/source3/nsswitch/winbindd_pam.c b/source3/nsswitch/winbindd_pam.c
index fcaad1fb1f..2a5ca40125 100644
--- a/source3/nsswitch/winbindd_pam.c
+++ b/source3/nsswitch/winbindd_pam.c
@@ -598,7 +598,8 @@ static NTSTATUS winbindd_raw_kerberos_login(struct winbindd_domain *domain,
&tkt,
&session_key_krb5,
0,
- cc);
+ cc,
+ NULL);
if (krb5_ret) {
DEBUG(1,("winbindd_raw_kerberos_login: failed to get ticket for %s: %s\n",
local_service, error_message(krb5_ret)));