From 9161b652101ade5ba0020c214e7eff9394ebda26 Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Fri, 7 Nov 2008 09:50:33 +0100 Subject: [PATCH] ntlm_auth: Put huge NTLMv2 blobs into extra_data on CRAP auth This fixes bug #5865 (cherry picked from commit a982abf3899199faef11b7279d1d5080e8a9f71c) --- source/nsswitch/winbind_struct_protocol.h | 4 +++- source/utils/ntlm_auth.c | 18 +++++++++++++++--- source/winbindd/winbindd_pam.c | 25 ++++++++++++++++++------- 3 files changed, 36 insertions(+), 11 deletions(-) diff --git a/source/nsswitch/winbind_struct_protocol.h b/source/nsswitch/winbind_struct_protocol.h index e81813c77b3..b5b0b11dad8 100644 --- a/source/nsswitch/winbind_struct_protocol.h +++ b/source/nsswitch/winbind_struct_protocol.h @@ -202,7 +202,9 @@ typedef struct winbindd_gr { #define WBFLAG_IS_PRIVILEGED 0x00000400 /* not used */ /* Flag to say this is a winbindd internal send - don't recurse. */ #define WBFLAG_RECURSE 0x00000800 - +/* Flag to tell winbind the NTLMv2 blob is too big for the struct and is in the + * extra_data field */ +#define WBFLAG_BIG_NTLMV2_BLOB 0x00010000 #define WINBINDD_MAX_EXTRA_DATA (128*1024) diff --git a/source/utils/ntlm_auth.c b/source/utils/ntlm_auth.c index 4586086d73f..8dd433c5386 100644 --- a/source/utils/ntlm_auth.c +++ b/source/utils/ntlm_auth.c @@ -380,13 +380,25 @@ NTSTATUS contact_winbind_auth_crap(const char *username, } if (nt_response && nt_response->length) { - memcpy(request.data.auth_crap.nt_resp, - nt_response->data, - MIN(nt_response->length, sizeof(request.data.auth_crap.nt_resp))); + if (nt_response->length > sizeof(request.data.auth_crap.nt_resp)) { + request.flags = request.flags | WBFLAG_BIG_NTLMV2_BLOB; + request.extra_len = nt_response->length; + request.extra_data.data = SMB_MALLOC_ARRAY(char, request.extra_len); + if (request.extra_data.data == NULL) { + return NT_STATUS_NO_MEMORY; + } + memcpy(request.extra_data.data, nt_response->data, + nt_response->length); + + } else { + memcpy(request.data.auth_crap.nt_resp, + nt_response->data, nt_response->length); + } request.data.auth_crap.nt_resp_len = nt_response->length; } result = winbindd_request_response(WINBINDD_PAM_AUTH_CRAP, &request, &response); + SAFE_FREE(request.extra_data.data); /* Display response */ diff --git a/source/winbindd/winbindd_pam.c b/source/winbindd/winbindd_pam.c index d9104ca6005..2fd9352f5e3 100644 --- a/source/winbindd/winbindd_pam.c +++ b/source/winbindd/winbindd_pam.c @@ -1854,17 +1854,28 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain, if (state->request.data.auth_crap.lm_resp_len > sizeof(state->request.data.auth_crap.lm_resp) || state->request.data.auth_crap.nt_resp_len > sizeof(state->request.data.auth_crap.nt_resp)) { - DEBUG(0, ("winbindd_pam_auth_crap: invalid password length %u/%u\n", - state->request.data.auth_crap.lm_resp_len, - state->request.data.auth_crap.nt_resp_len)); - result = NT_STATUS_INVALID_PARAMETER; - goto done; + if (!state->request.flags & WBFLAG_BIG_NTLMV2_BLOB || + state->request.extra_len != state->request.data.auth_crap.nt_resp_len) { + DEBUG(0, ("winbindd_pam_auth_crap: invalid password length %u/%u\n", + state->request.data.auth_crap.lm_resp_len, + state->request.data.auth_crap.nt_resp_len)); + result = NT_STATUS_INVALID_PARAMETER; + goto done; + } } lm_resp = data_blob_talloc(state->mem_ctx, state->request.data.auth_crap.lm_resp, state->request.data.auth_crap.lm_resp_len); - nt_resp = data_blob_talloc(state->mem_ctx, state->request.data.auth_crap.nt_resp, - state->request.data.auth_crap.nt_resp_len); + + if (state->request.flags & WBFLAG_BIG_NTLMV2_BLOB) { + nt_resp = data_blob_talloc(state->mem_ctx, + state->request.extra_data.data, + state->request.data.auth_crap.nt_resp_len); + } else { + nt_resp = data_blob_talloc(state->mem_ctx, + state->request.data.auth_crap.nt_resp, + state->request.data.auth_crap.nt_resp_len); + } /* what domain should we contact? */ -- 2.11.4.GIT