From e357bc3216b226dbd61d6a816e199a9450b706db Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 30 Sep 2004 00:49:41 +0000 Subject: [PATCH] r2755: Fix NTLMv2 for use with pam_winbind, the plaintext ntlm_auth modes, and the wbinfo -a test tool. If 'client ntlmv2 auth' is set, then we will send an NTLMv2, rather than an NT/LM response to the server. Andrew Bartlett (This used to be commit ce2456e436c5d57cd95cd10c6edf759592d0e843) --- source3/nsswitch/wbinfo.c | 53 ++++++++++++++++++++++++++++---- source3/nsswitch/winbindd_pam.c | 54 ++++++++++++++++++++++++++++++--- 2 files changed, 97 insertions(+), 10 deletions(-) diff --git a/source3/nsswitch/wbinfo.c b/source3/nsswitch/wbinfo.c index b6a09bf2a1f..2abd9c69a17 100644 --- a/source3/nsswitch/wbinfo.c +++ b/source3/nsswitch/wbinfo.c @@ -582,13 +582,54 @@ static BOOL wbinfo_auth_crap(char *username) generate_random_buffer(request.data.auth_crap.chal, 8); - SMBencrypt(pass, request.data.auth_crap.chal, - (uchar *)request.data.auth_crap.lm_resp); - SMBNTencrypt(pass, request.data.auth_crap.chal, - (uchar *)request.data.auth_crap.nt_resp); + if (lp_client_ntlmv2_auth()) { + DATA_BLOB server_chal; + DATA_BLOB names_blob; - request.data.auth_crap.lm_resp_len = 24; - request.data.auth_crap.nt_resp_len = 24; + DATA_BLOB lm_response; + DATA_BLOB nt_response; + + server_chal = data_blob(request.data.auth_crap.chal, 8); + + /* Pretend this is a login to 'us', for blob purposes */ + names_blob = NTLMv2_generate_names_blob(global_myname(), lp_workgroup()); + + if (!SMBNTLMv2encrypt(name_user, name_domain, pass, &server_chal, + &names_blob, + &lm_response, &nt_response, NULL)) { + data_blob_free(&names_blob); + data_blob_free(&server_chal); + return False; + } + data_blob_free(&names_blob); + data_blob_free(&server_chal); + + memcpy(request.data.auth_crap.nt_resp, nt_response.data, + MIN(nt_response.length, + sizeof(request.data.auth_crap.nt_resp))); + request.data.auth_crap.nt_resp_len = nt_response.length; + + memcpy(request.data.auth_crap.lm_resp, lm_response.data, + MIN(lm_response.length, + sizeof(request.data.auth_crap.lm_resp))); + request.data.auth_crap.lm_resp_len = lm_response.length; + + data_blob_free(&nt_response); + data_blob_free(&lm_response); + + } else { + if (lp_client_lanman_auth() + && SMBencrypt(pass, request.data.auth_crap.chal, + (uchar *)request.data.auth_crap.lm_resp)) { + request.data.auth_crap.lm_resp_len = 24; + } else { + request.data.auth_crap.lm_resp_len = 0; + } + SMBNTencrypt(pass, request.data.auth_crap.chal, + (uchar *)request.data.auth_crap.nt_resp); + + request.data.auth_crap.nt_resp_len = 24; + } result = winbindd_request(WINBINDD_PAM_AUTH_CRAP, &request, &response); diff --git a/source3/nsswitch/winbindd_pam.c b/source3/nsswitch/winbindd_pam.c index 129f876f817..e8d15f47038 100644 --- a/source3/nsswitch/winbindd_pam.c +++ b/source3/nsswitch/winbindd_pam.c @@ -190,13 +190,59 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state) /* do password magic */ + generate_random_buffer(chal, 8); - SMBencrypt(state->request.data.auth.pass, chal, local_lm_response); + if (lp_client_ntlmv2_auth()) { + DATA_BLOB server_chal; + DATA_BLOB names_blob; + DATA_BLOB nt_response; + DATA_BLOB lm_response; + server_chal = data_blob_talloc(mem_ctx, chal, 8); + + /* note that the 'workgroup' here is a best guess - we don't know + the server's domain at this point. The 'server name' is also + dodgy... + */ + names_blob = NTLMv2_generate_names_blob(global_myname(), lp_workgroup()); - SMBNTencrypt(state->request.data.auth.pass, chal, local_nt_response); + if (!SMBNTLMv2encrypt(name_user, name_domain, + state->request.data.auth.pass, + &server_chal, + &names_blob, + &lm_response, &nt_response, NULL)) { + data_blob_free(&names_blob); + data_blob_free(&server_chal); + DEBUG(0, ("winbindd_pam_auth: SMBNTLMv2encrypt() failed!\n")); + result = NT_STATUS_NO_MEMORY; + goto done; + } + data_blob_free(&names_blob); + data_blob_free(&server_chal); + lm_resp = data_blob_talloc(mem_ctx, lm_response.data, lm_response.length); + nt_resp = data_blob_talloc(mem_ctx, nt_response.data, nt_response.length); + data_blob_free(&lm_response); + data_blob_free(&nt_response); + + } else { + if (lp_client_lanman_auth() + && SMBencrypt(state->request.data.auth.pass, + chal, + local_lm_response)) { + lm_resp = data_blob_talloc(mem_ctx, + local_lm_response, + sizeof(local_lm_response)); + } else { + lm_resp = data_blob(NULL, 0); + } + SMBNTencrypt(state->request.data.auth.pass, + chal, + local_nt_response); + + nt_resp = data_blob_talloc(mem_ctx, + local_nt_response, + sizeof(local_nt_response)); + } - lm_resp = data_blob_talloc(mem_ctx, local_lm_response, sizeof(local_lm_response)); - nt_resp = data_blob_talloc(mem_ctx, local_nt_response, sizeof(local_nt_response)); /* what domain should we contact? */ -- 2.34.1