diff options
-rw-r--r-- | source3/nsswitch/winbind_struct_protocol.h | 4 | ||||
-rw-r--r-- | source3/utils/ntlm_auth.c | 18 | ||||
-rw-r--r-- | source3/winbindd/winbindd_pam.c | 25 |
3 files changed, 36 insertions, 11 deletions
diff --git a/source3/nsswitch/winbind_struct_protocol.h b/source3/nsswitch/winbind_struct_protocol.h index ff52dbddaf..169b4a8c95 100644 --- a/source3/nsswitch/winbind_struct_protocol.h +++ b/source3/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/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c index 0a76761cb2..fbb105bfe6 100644 --- a/source3/utils/ntlm_auth.c +++ b/source3/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/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c index 9ff3899661..7de28b08a9 100644 --- a/source3/winbindd/winbindd_pam.c +++ b/source3/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? */ |