diff options
Diffstat (limited to 'source3/libsmb/ntlmssp.c')
-rw-r--r-- | source3/libsmb/ntlmssp.c | 110 |
1 files changed, 36 insertions, 74 deletions
diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 0764f97d85..c5d271cdba 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -22,6 +22,7 @@ */ #include "includes.h" +#include "../libcli/auth/libcli_auth.h" static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state, DATA_BLOB reply, DATA_BLOB *next_request); @@ -322,7 +323,7 @@ NTSTATUS ntlmssp_update(NTLMSSP_STATE *ntlmssp_state, break; } } else { - if (!msrpc_parse(&input, "Cd", + if (!msrpc_parse(ntlmssp_state, &input, "Cd", "NTLMSSP", &ntlmssp_command)) { DEBUG(1, ("Failed to parse NTLMSSP packet, could not extract NTLMSSP command\n")); @@ -524,10 +525,10 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, #endif if (request.length) { - if ((request.length < 16) || !msrpc_parse(&request, "Cdd", - "NTLMSSP", - &ntlmssp_command, - &neg_flags)) { + if ((request.length < 16) || !msrpc_parse(ntlmssp_state, &request, "Cdd", + "NTLMSSP", + &ntlmssp_command, + &neg_flags)) { DEBUG(1, ("ntlmssp_server_negotiate: failed to parse NTLMSSP Negotiate of length %u\n", (unsigned int)request.length)); dump_data(2, request.data, request.length); @@ -581,7 +582,7 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, /* This creates the 'blob' of names that appears at the end of the packet */ if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) { - msrpc_gen(&struct_blob, "aaaaa", + msrpc_gen(ntlmssp_state, &struct_blob, "aaaaa", NTLMSSP_NAME_TYPE_DOMAIN, target_name, NTLMSSP_NAME_TYPE_SERVER, ntlmssp_state->get_global_myname(), NTLMSSP_NAME_TYPE_DOMAIN_DNS, dnsdomname, @@ -600,7 +601,7 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, gen_string = "CdAdbddB"; } - msrpc_gen(reply, gen_string, + msrpc_gen(ntlmssp_state, reply, gen_string, "NTLMSSP", NTLMSSP_CHALLENGE, target_name, @@ -643,9 +644,6 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, uchar session_nonce_hash[16]; const char *parse_string; - char *domain = NULL; - char *user = NULL; - char *workstation = NULL; /* parse the NTLMSSP packet */ *reply = data_blob_null; @@ -668,20 +666,16 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, ntlmssp_state->workstation = NULL; /* now the NTLMSSP encoded auth hashes */ - if (!msrpc_parse(&request, parse_string, + if (!msrpc_parse(ntlmssp_state, &request, parse_string, "NTLMSSP", &ntlmssp_command, &ntlmssp_state->lm_resp, &ntlmssp_state->nt_resp, - &domain, - &user, - &workstation, + &ntlmssp_state->domain, + &ntlmssp_state->user, + &ntlmssp_state->workstation, &encrypted_session_key, &auth_flags)) { - SAFE_FREE(domain); - SAFE_FREE(user); - SAFE_FREE(workstation); - data_blob_free(&encrypted_session_key); auth_flags = 0; /* Try again with a shorter string (Win9X truncates this packet) */ @@ -692,19 +686,16 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, } /* now the NTLMSSP encoded auth hashes */ - if (!msrpc_parse(&request, parse_string, + if (!msrpc_parse(ntlmssp_state, &request, parse_string, "NTLMSSP", &ntlmssp_command, &ntlmssp_state->lm_resp, &ntlmssp_state->nt_resp, - &domain, - &user, - &workstation)) { + &ntlmssp_state->domain, + &ntlmssp_state->user, + &ntlmssp_state->workstation)) { DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP (tried both formats):\n")); dump_data(2, request.data, request.length); - SAFE_FREE(domain); - SAFE_FREE(user); - SAFE_FREE(workstation); return NT_STATUS_INVALID_PARAMETER; } @@ -713,34 +704,6 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, if (auth_flags) ntlmssp_handle_neg_flags(ntlmssp_state, auth_flags, lp_lanman_auth()); - if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, domain))) { - SAFE_FREE(domain); - SAFE_FREE(user); - SAFE_FREE(workstation); - data_blob_free(&encrypted_session_key); - return nt_status; - } - - if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, user))) { - SAFE_FREE(domain); - SAFE_FREE(user); - SAFE_FREE(workstation); - data_blob_free(&encrypted_session_key); - return nt_status; - } - - if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_workstation(ntlmssp_state, workstation))) { - SAFE_FREE(domain); - SAFE_FREE(user); - SAFE_FREE(workstation); - data_blob_free(&encrypted_session_key); - return nt_status; - } - - SAFE_FREE(domain); - SAFE_FREE(user); - SAFE_FREE(workstation); - DEBUG(3,("Got user=[%s] domain=[%s] workstation=[%s] len1=%lu len2=%lu\n", ntlmssp_state->user, ntlmssp_state->domain, ntlmssp_state->workstation, (unsigned long)ntlmssp_state->lm_resp.length, (unsigned long)ntlmssp_state->nt_resp.length)); @@ -873,9 +836,9 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, ntlmssp_state->session_key = session_key; } else { dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length); - SamOEMhash(encrypted_session_key.data, - session_key.data, - encrypted_session_key.length); + arcfour_crypt_blob(encrypted_session_key.data, + encrypted_session_key.length, + &session_key); ntlmssp_state->session_key = data_blob_talloc( ntlmssp_state, encrypted_session_key.data, encrypted_session_key.length); @@ -970,7 +933,7 @@ static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state, } /* generate the ntlmssp negotiate packet */ - msrpc_gen(next_request, "CddAA", + msrpc_gen(ntlmssp_state, next_request, "CddAA", "NTLMSSP", NTLMSSP_NEGOTIATE, ntlmssp_state->neg_flags, @@ -1007,7 +970,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB encrypted_session_key = data_blob_null; NTSTATUS nt_status = NT_STATUS_OK; - if (!msrpc_parse(&reply, "CdBd", + if (!msrpc_parse(ntlmssp_state, &reply, "CdBd", "NTLMSSP", &ntlmssp_command, &server_domain_blob, @@ -1045,7 +1008,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, DEBUG(3, ("NTLMSSP: Set final flags:\n")); debug_ntlmssp_flags(ntlmssp_state->neg_flags); - if (!msrpc_parse(&reply, chal_parse_string, + if (!msrpc_parse(ntlmssp_state, &reply, chal_parse_string, "NTLMSSP", &ntlmssp_command, &server_domain, @@ -1058,10 +1021,8 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, return NT_STATUS_INVALID_PARAMETER; } - ntlmssp_state->server_domain = talloc_strdup(ntlmssp_state, - server_domain); + ntlmssp_state->server_domain = server_domain; - SAFE_FREE(server_domain); if (challenge_blob.length != 8) { data_blob_free(&struct_blob); return NT_STATUS_INVALID_PARAMETER; @@ -1079,7 +1040,6 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, /* not doing NLTM2 without a password */ ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; } else if (ntlmssp_state->use_ntlmv2) { - if (!struct_blob.length) { /* be lazy, match win2k - we can't do NTLMv2 without it */ DEBUG(1, ("Server did not provide 'target information', required for NTLMv2\n")); @@ -1089,11 +1049,13 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, /* TODO: if the remote server is standalone, then we should replace 'domain' with the server name as supplied above */ - if (!SMBNTLMv2encrypt_hash(ntlmssp_state->user, - ntlmssp_state->domain, - ntlmssp_state->nt_hash, &challenge_blob, - &struct_blob, - &lm_response, &nt_response, &session_key)) { + if (!SMBNTLMv2encrypt_hash(ntlmssp_state, + ntlmssp_state->user, + ntlmssp_state->domain, + ntlmssp_state->nt_hash, &challenge_blob, + &struct_blob, + &lm_response, &nt_response, NULL, + &session_key)) { data_blob_free(&challenge_blob); data_blob_free(&struct_blob); return NT_STATUS_NO_MEMORY; @@ -1122,12 +1084,12 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, nt_response = data_blob_talloc(ntlmssp_state, NULL, 24); SMBNTencrypt_hash(ntlmssp_state->nt_hash, - session_nonce_hash, - nt_response.data); + session_nonce_hash, + nt_response.data); session_key = data_blob_talloc(ntlmssp_state, NULL, 16); - SMBsesskeygen_ntv1(ntlmssp_state->nt_hash, NULL, user_session_key); + SMBsesskeygen_ntv1(ntlmssp_state->nt_hash, user_session_key); hmac_md5(user_session_key, session_nonce, sizeof(session_nonce), session_key.data); dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length); } else { @@ -1150,7 +1112,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, session_key.data); dump_data_pw("LM session key\n", session_key.data, session_key.length); } else { - SMBsesskeygen_ntv1(ntlmssp_state->nt_hash, NULL, session_key.data); + SMBsesskeygen_ntv1(ntlmssp_state->nt_hash, session_key.data); dump_data_pw("NT session key:\n", session_key.data, session_key.length); } } @@ -1166,7 +1128,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, /* Encrypt the new session key with the old one */ encrypted_session_key = data_blob(client_session_key, sizeof(client_session_key)); dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, encrypted_session_key.length); - SamOEMhash(encrypted_session_key.data, session_key.data, encrypted_session_key.length); + arcfour_crypt_blob(encrypted_session_key.data, encrypted_session_key.length, &session_key); dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length); /* Mark the new session key as the 'real' session key */ @@ -1177,7 +1139,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, } /* this generates the actual auth packet */ - if (!msrpc_gen(next_request, auth_gen_string, + if (!msrpc_gen(ntlmssp_state, next_request, auth_gen_string, "NTLMSSP", NTLMSSP_AUTH, lm_response.data, lm_response.length, |