From 8e0a4e7e6f8935b41e6e4ca77ef75f3e766d6eef Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 28 Aug 2006 23:01:30 +0000 Subject: r17897: Store the uid in the memory creds. Don't request the krb5 refresh creds when doing cached NTLM auth, request the memory creds instead. Jeremy. (This used to be commit 310ac0b226edcfd5bedc2c3305a05993db20c7af) --- source3/nsswitch/winbindd_ccache_access.c | 12 ++++++------ source3/nsswitch/winbindd_cred_cache.c | 24 +++++++++++++++++++----- source3/nsswitch/winbindd_nss.h | 1 + source3/nsswitch/winbindd_pam.c | 1 + 4 files changed, 27 insertions(+), 11 deletions(-) (limited to 'source3/nsswitch') diff --git a/source3/nsswitch/winbindd_ccache_access.c b/source3/nsswitch/winbindd_ccache_access.c index 6aa221448e..13b551b696 100644 --- a/source3/nsswitch/winbindd_ccache_access.c +++ b/source3/nsswitch/winbindd_ccache_access.c @@ -29,7 +29,7 @@ #define DBGC_CLASS DBGC_WINBIND static BOOL client_can_access_ccache_entry(uid_t client_uid, - struct WINBINDD_CCACHE_ENTRY *entry) + struct WINBINDD_MEMORY_CREDS *entry) { if (client_uid == entry->uid || client_uid == 0) { DEBUG(10, ("Access granted to uid %d\n", client_uid)); @@ -190,7 +190,7 @@ enum winbindd_result winbindd_dual_ccache_ntlm_auth(struct winbindd_domain *doma struct winbindd_cli_state *state) { NTSTATUS result = NT_STATUS_NOT_SUPPORTED; - struct WINBINDD_CCACHE_ENTRY *entry; + struct WINBINDD_MEMORY_CREDS *entry; DATA_BLOB initial, challenge, auth; fstring name_domain, name_user; uint32 initial_blob_len, challenge_blob_len, extra_len; @@ -229,15 +229,15 @@ enum winbindd_result winbindd_dual_ccache_ntlm_auth(struct winbindd_domain *doma goto process_result; } - entry = get_ccache_by_username(state->request.data.ccache_ntlm_auth.user); - if (entry == NULL || entry->cred_ptr == NULL) { + entry = find_memory_creds_by_name(state->request.data.ccache_ntlm_auth.user); + if (entry == NULL || entry->nt_hash == NULL || entry->lm_hash == NULL) { DEBUG(10,("winbindd_dual_ccache_ntlm_auth: could not find " "credentials for user %s\n", state->request.data.ccache_ntlm_auth.user)); goto process_result; } - DEBUG(10,("winbindd_dual_ccache_ntlm_auth: found ccache [%s]\n", entry->ccname)); + DEBUG(10,("winbindd_dual_ccache_ntlm_auth: found ccache [%s]\n", entry->username)); if (!client_can_access_ccache_entry(state->request.data.ccache_ntlm_auth.uid, entry)) { goto process_result; @@ -258,7 +258,7 @@ enum winbindd_result winbindd_dual_ccache_ntlm_auth(struct winbindd_domain *doma result = NT_STATUS_NO_MEMORY; } else { result = do_ntlm_auth_with_hashes(name_user, name_domain, - entry->cred_ptr->lm_hash, entry->cred_ptr->nt_hash, + entry->lm_hash, entry->nt_hash, initial, challenge, &auth); } diff --git a/source3/nsswitch/winbindd_cred_cache.c b/source3/nsswitch/winbindd_cred_cache.c index ceca389825..e107b82a04 100644 --- a/source3/nsswitch/winbindd_cred_cache.c +++ b/source3/nsswitch/winbindd_cred_cache.c @@ -35,7 +35,7 @@ static struct WINBINDD_CCACHE_ENTRY *ccache_list; Find an entry by name. ****************************************************************/ -struct WINBINDD_CCACHE_ENTRY *get_ccache_by_username(const char *username) +static struct WINBINDD_CCACHE_ENTRY *get_ccache_by_username(const char *username) { struct WINBINDD_CCACHE_ENTRY *entry; @@ -307,7 +307,7 @@ static struct WINBINDD_MEMORY_CREDS *memory_creds_list; Find an entry on the list by name. ***********************************************************/ -static struct WINBINDD_MEMORY_CREDS *find_memory_creds_by_name(const char *username) +struct WINBINDD_MEMORY_CREDS *find_memory_creds_by_name(const char *username) { struct WINBINDD_MEMORY_CREDS *p; @@ -411,7 +411,7 @@ static NTSTATUS winbindd_replace_memory_creds_internal(struct WINBINDD_MEMORY_CR Store credentials in memory in a list. *************************************************************/ -static NTSTATUS winbindd_add_memory_creds_internal(const char *username, const char *pass, BOOL store_pass) +static NTSTATUS winbindd_add_memory_creds_internal(const char *username, uid_t uid, const char *pass, BOOL store_pass) { /* Shortcut to ensure we don't store if no mlock. */ #if !defined(HAVE_MLOCK) || !defined(HAVE_MUNLOCK) @@ -420,8 +420,20 @@ static NTSTATUS winbindd_add_memory_creds_internal(const char *username, const c NTSTATUS status; struct WINBINDD_MEMORY_CREDS *memcredp = find_memory_creds_by_name(username); + if (uid == (uid_t)-1) { + DEBUG(0,("winbindd_add_memory_creds_internal: invalid uid for user %s.\n", + username )); + return NT_STATUS_INVALID_PARAMETER; + } + if (memcredp) { /* Already exists. Increment the reference count and replace stored creds. */ + if (uid != memcredp->uid) { + DEBUG(0,("winbindd_add_memory_creds_internal: uid %u for user %s doesn't " + "match stored uid %u. Replacing.\n", + (unsigned int)uid, username, (unsigned int)memcredp->uid )); + memcredp->uid = uid; + } memcredp->ref_count++; DEBUG(10,("winbindd_add_memory_creds_internal: ref count for user %s is now %d\n", username, memcredp->ref_count )); @@ -440,9 +452,11 @@ static NTSTATUS winbindd_add_memory_creds_internal(const char *username, const c status = store_memory_creds(memcredp, pass, store_pass); if (!NT_STATUS_IS_OK(status)) { + talloc_destroy(memcredp); return status; } + memcredp->uid = uid; memcredp->ref_count = 1; DLIST_ADD(memory_creds_list, memcredp); @@ -460,7 +474,7 @@ static NTSTATUS winbindd_add_memory_creds_internal(const char *username, const c and associate the new credentials with the struct WINBINDD_CCACHE_ENTRY. *************************************************************/ -NTSTATUS winbindd_add_memory_creds(const char *username, const char *pass) +NTSTATUS winbindd_add_memory_creds(const char *username, uid_t uid, const char *pass) { struct WINBINDD_CCACHE_ENTRY *entry = get_ccache_by_username(username); BOOL store_pass = False; @@ -470,7 +484,7 @@ NTSTATUS winbindd_add_memory_creds(const char *username, const char *pass) store_pass = True; } - status = winbindd_add_memory_creds_internal(username, pass, store_pass); + status = winbindd_add_memory_creds_internal(username, uid, pass, store_pass); if (!NT_STATUS_IS_OK(status)) { return status; } diff --git a/source3/nsswitch/winbindd_nss.h b/source3/nsswitch/winbindd_nss.h index 88fe671114..bab200ce04 100644 --- a/source3/nsswitch/winbindd_nss.h +++ b/source3/nsswitch/winbindd_nss.h @@ -459,6 +459,7 @@ struct winbindd_response { struct WINBINDD_MEMORY_CREDS { struct WINBINDD_MEMORY_CREDS *next, *prev; const char *username; /* lookup key. */ + uid_t uid; int ref_count; size_t len; unsigned char *nt_hash; /* Base pointer for the following 2 */ diff --git a/source3/nsswitch/winbindd_pam.c b/source3/nsswitch/winbindd_pam.c index f87749abed..dbd52092ef 100644 --- a/source3/nsswitch/winbindd_pam.c +++ b/source3/nsswitch/winbindd_pam.c @@ -1271,6 +1271,7 @@ process_result: /* Store in-memory creds for single-signon using ntlm_auth. */ result = winbindd_add_memory_creds(state->request.data.auth.user, + get_uid_from_state(state), state->request.data.auth.pass); if (!NT_STATUS_IS_OK(result)) { -- cgit