From 3ff4f4410ff71fc4c74b7546d0c0002918a32cf3 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 14 Dec 2006 16:34:24 +0000 Subject: r20171: Don't delete the krb5 credential if others still reference to it. Guenther (This used to be commit a1378979be4fe5ac5148b0a7830859aebb97838c) --- source3/nsswitch/winbindd_cred_cache.c | 39 ++++++++++++++++++++++++++++------ source3/nsswitch/winbindd_pam.c | 19 +++++------------ 2 files changed, 37 insertions(+), 21 deletions(-) diff --git a/source3/nsswitch/winbindd_cred_cache.c b/source3/nsswitch/winbindd_cred_cache.c index 37e3bb2f8c..5772be15a8 100644 --- a/source3/nsswitch/winbindd_cred_cache.c +++ b/source3/nsswitch/winbindd_cred_cache.c @@ -382,9 +382,17 @@ NTSTATUS add_ccache_to_list(const char *princ_name, return NT_STATUS_NO_MEMORY; } +/******************************************************************* + Remove a WINBINDD_CCACHE_ENTRY entry and the krb5 ccache if no longer referenced. +*******************************************************************/ + NTSTATUS remove_ccache(const char *username) { struct WINBINDD_CCACHE_ENTRY *entry = get_ccache_by_username(username); + NTSTATUS status; +#ifdef HAVE_KRB5 + krb5_error_code ret; +#endif if (!entry) { return NT_STATUS_OBJECT_NAME_NOT_FOUND; @@ -397,17 +405,34 @@ NTSTATUS remove_ccache(const char *username) } entry->ref_count--; - if (entry->ref_count <= 0) { - DLIST_REMOVE(ccache_list, entry); - TALLOC_FREE(entry->event); /* unregisters events */ - TALLOC_FREE(entry); - DEBUG(10,("remove_ccache: removed ccache for user %s\n", username)); - } else { + + if (entry->ref_count > 0) { DEBUG(10,("remove_ccache: entry %s ref count now %d\n", username, entry->ref_count )); + return NT_STATUS_OK; } - return NT_STATUS_OK; + /* no references any more */ + + DLIST_REMOVE(ccache_list, entry); + TALLOC_FREE(entry->event); /* unregisters events */ + +#ifdef HAVE_KRB5 + ret = ads_kdestroy(entry->ccname); + if (ret) { + DEBUG(0,("remove_ccache: failed to destroy user krb5 ccache %s with: %s\n", + entry->ccname, error_message(ret))); + } else { + DEBUG(10,("remove_ccache: successfully destroyed krb5 ccache %s for user %s\n", + entry->ccname, username)); + } + status = krb5_to_nt_status(ret); +#endif + + TALLOC_FREE(entry); + DEBUG(10,("remove_ccache: removed ccache for user %s\n", username)); + + return status; } /******************************************************************* diff --git a/source3/nsswitch/winbindd_pam.c b/source3/nsswitch/winbindd_pam.c index 6a13b38b3a..257008497b 100644 --- a/source3/nsswitch/winbindd_pam.c +++ b/source3/nsswitch/winbindd_pam.c @@ -1976,9 +1976,6 @@ enum winbindd_result winbindd_dual_pam_logoff(struct winbindd_domain *domain, struct winbindd_cli_state *state) { NTSTATUS result = NT_STATUS_NOT_SUPPORTED; -#ifdef HAVE_KRB5 - int ret; -#endif DEBUG(3, ("[%5lu]: pam dual logoff %s\n", (unsigned long)state->pid, state->request.data.logoff.user)); @@ -2010,19 +2007,13 @@ enum winbindd_result winbindd_dual_pam_logoff(struct winbindd_domain *domain, goto process_result; } - ret = ads_kdestroy(state->request.data.logoff.krb5ccname); - - if (ret) { - DEBUG(0,("winbindd_pam_logoff: failed to destroy user ccache %s with: %s\n", - state->request.data.logoff.krb5ccname, error_message(ret))); - } else { - DEBUG(10,("winbindd_pam_logoff: successfully destroyed ccache %s for user %s\n", - state->request.data.logoff.krb5ccname, state->request.data.logoff.user)); + result = remove_ccache(state->request.data.logoff.user); + if (!NT_STATUS_IS_OK(result)) { + DEBUG(0,("winbindd_pam_logoff: failed to remove ccache: %s\n", + nt_errstr(result))); + goto process_result; } - remove_ccache(state->request.data.logoff.user); - - result = krb5_to_nt_status(ret); #else result = NT_STATUS_NOT_SUPPORTED; #endif -- cgit