diff options
author | Jeremy Allison <jra@samba.org> | 2006-08-20 01:25:26 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 11:38:43 -0500 |
commit | b2d5dd7281805a25a86124d76dbc091fe12efff5 (patch) | |
tree | afe2de67ddf4e2a57d16fbe7162bf21193b1ea61 | |
parent | ffa590854ab5f2563c3398ae9ae3182e6abe3f82 (diff) | |
download | samba-b2d5dd7281805a25a86124d76dbc091fe12efff5.tar.gz samba-b2d5dd7281805a25a86124d76dbc091fe12efff5.tar.bz2 samba-b2d5dd7281805a25a86124d76dbc091fe12efff5.zip |
r17616: Add the lm and nt hashes to the cached credentials
stored - only store the password if we're going to
be doing a krb5 refresh. GD please review this change !
Now to add code to reference count the cached creds
(to allow multiple pam_logon/pam_logoffs to keep the
creds around), ensure that the cred cache is called
on all successful pam_logons (if we have winbindd cache
pam credentials = true, set this by default) and finally
ensure the creds cache is changed on successful password
change. GD - you *really* need to review this :-).
Jeremy.
(This used to be commit 017e7e14958d29246a1b221e33755bb91e96b08f)
-rw-r--r-- | source3/nsswitch/winbindd_ccache_access.c | 12 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_cred_cache.c | 66 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_nss.h | 2 |
3 files changed, 52 insertions, 28 deletions
diff --git a/source3/nsswitch/winbindd_ccache_access.c b/source3/nsswitch/winbindd_ccache_access.c index 35d2cb4e51..6ac3942a8d 100644 --- a/source3/nsswitch/winbindd_ccache_access.c +++ b/source3/nsswitch/winbindd_ccache_access.c @@ -40,9 +40,10 @@ static BOOL client_can_access_ccache_entry(uid_t client_uid, return False; } -static NTSTATUS do_ntlm_auth_with_password(const char *username, +static NTSTATUS do_ntlm_auth_with_hashes(const char *username, const char *domain, - const char *password, + const unsigned char lm_hash[LM_HASH_LEN], + const unsigned char nt_hash[NT_HASH_LEN], const DATA_BLOB initial_msg, const DATA_BLOB challenge_msg, DATA_BLOB *auth_msg) @@ -75,10 +76,10 @@ static NTSTATUS do_ntlm_auth_with_password(const char *username, goto done; } - status = ntlmssp_set_password(ntlmssp_state, password); + status = ntlmssp_set_hashes(ntlmssp_state, lm_hash, nt_hash); if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Could not set password: %s\n", + DEBUG(1, ("Could not set hashes: %s\n", nt_errstr(status))); goto done; } @@ -256,7 +257,8 @@ enum winbindd_result winbindd_dual_ccache_ntlm_auth(struct winbindd_domain *doma if (!initial.data || !challenge.data) { result = NT_STATUS_NO_MEMORY; } else { - result = do_ntlm_auth_with_password(name_user, name_domain, entry->pass, + result = do_ntlm_auth_with_hashes(name_user, name_domain, + 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 688c8828d3..b56003a469 100644 --- a/source3/nsswitch/winbindd_cred_cache.c +++ b/source3/nsswitch/winbindd_cred_cache.c @@ -25,7 +25,7 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_WINBIND -#define MAX_CCACHES 100 +#define MAX_CCACHES 10000 static struct WINBINDD_CCACHE_ENTRY *ccache_list; @@ -75,19 +75,24 @@ NTSTATUS remove_ccache_by_ccname(const char *ccname) DLIST_REMOVE(ccache_list, entry); TALLOC_FREE(entry->event); /* unregisters events */ #ifdef HAVE_MUNLOCK - if (entry->pass) { - size_t len = strlen(entry->pass)+1; + if (entry->nt_hash) { + size_t len = NT_HASH_LEN + LM_HASH_LEN; + + if (entry->pass) { + len += strlen(entry->pass)+1; + } + #ifdef DEBUG_PASSWORD - DEBUG(10,("unlocking memory: %p\n", entry->pass)); + DEBUG(10,("unlocking memory: %p\n", entry->nt_hash)); #endif - memset(entry->pass, 0, len); - if ((munlock(entry->pass, len)) == -1) { + memset(entry->nt_hash, 0, len); + if ((munlock(entry->nt_hash, len)) == -1) { DEBUG(0,("failed to munlock memory: %s (%d)\n", strerror(errno), errno)); return map_nt_error_from_unix(errno); } #ifdef DEBUG_PASSWORD - DEBUG(10,("munlocked memory: %p\n", entry->pass)); + DEBUG(10,("munlocked memory: %p\n", entry->nt_hash)); #endif } #endif /* HAVE_MUNLOCK */ @@ -109,7 +114,6 @@ static void krb5_ticket_refresh_handler(struct timed_event *te, time_t new_start; struct timeval t; - DEBUG(10,("krb5_ticket_refresh_handler called\n")); DEBUGADD(10,("event called for: %s, %s\n", entry->ccname, entry->username)); @@ -245,30 +249,47 @@ NTSTATUS add_ccache_to_list(const char *princ_name, NT_STATUS_HAVE_NO_MEMORY(new_entry->service); } - if (schedule_refresh_event && pass) { -#ifdef HAVE_MLOCK - size_t len = strlen(pass)+1; - - new_entry->pass = (char *)TALLOC_ZERO(mem_ctx, len); - NT_STATUS_HAVE_NO_MEMORY(new_entry->pass); + if (pass) { + size_t len = NT_HASH_LEN + LM_HASH_LEN; + + /* We only store the plaintext if we're going to + schedule a krb5 refresh. */ + + if (schedule_refresh_event) { + len += strlen(pass)+1; + } + /* new_entry->nt_hash is the base pointer for the block + of memory pointed into by new_entry->lm_hash and + new_entry->pass (if we're storing plaintext). */ + + new_entry->nt_hash = (unsigned char *)TALLOC_ZERO(mem_ctx, len); + NT_STATUS_HAVE_NO_MEMORY(new_entry->nt_hash); + + new_entry->lm_hash = new_entry->nt_hash + NT_HASH_LEN; +#ifdef HAVE_MLOCK #ifdef DEBUG_PASSWORD - DEBUG(10,("mlocking memory: %p\n", new_entry->pass)); + DEBUG(10,("mlocking memory: %p\n", new_entry->nt_hash)); #endif - if ((mlock(new_entry->pass, len)) == -1) { + if ((mlock(new_entry->nt_hash, len)) == -1) { DEBUG(0,("failed to mlock memory: %s (%d)\n", strerror(errno), errno)); return map_nt_error_from_unix(errno); } #ifdef DEBUG_PASSWORD - DEBUG(10,("mlocked memory: %p\n", new_entry->pass)); + DEBUG(10,("mlocked memory: %p\n", new_entry->nt_hash)); #endif - memcpy(new_entry->pass, pass, len); -#else - new_entry->pass = talloc_strdup(mem_ctx, pass); - NT_STATUS_HAVE_NO_MEMORY(new_entry->pass); #endif /* HAVE_MLOCK */ + + /* Create and store the password hashes. */ + E_md4hash(pass, new_entry->nt_hash); + E_deshash(pass, new_entry->lm_hash); + + if (schedule_refresh_event) { + new_entry->pass = (char *)new_entry->lm_hash + LM_HASH_LEN; + memcpy(new_entry->pass, pass, len - NT_HASH_LEN - LM_HASH_LEN); + } } new_entry->create_time = create_time; @@ -279,7 +300,6 @@ NTSTATUS add_ccache_to_list(const char *princ_name, } new_entry->uid = uid; - if (schedule_refresh_event && renew_until > 0) { struct timeval t = timeval_set((ticket_end -1 ), 0); @@ -316,7 +336,7 @@ NTSTATUS init_ccache_list(void) return NT_STATUS_OK; } - mem_ctx = talloc_init("winbindd_ccache_krb5_handling"); + mem_ctx = talloc_init("winbindd_ccache_handling"); if (mem_ctx == NULL) { return NT_STATUS_NO_MEMORY; } diff --git a/source3/nsswitch/winbindd_nss.h b/source3/nsswitch/winbindd_nss.h index b19026b4db..f393512b72 100644 --- a/source3/nsswitch/winbindd_nss.h +++ b/source3/nsswitch/winbindd_nss.h @@ -462,6 +462,8 @@ struct WINBINDD_CCACHE_ENTRY { const char *service; const char *username; const char *sid_string; + unsigned char *nt_hash; /* Base pointer for the following 2 */ + unsigned char *lm_hash; char *pass; uid_t uid; time_t create_time; |