diff options
author | Gerald Carter <jerry@samba.org> | 2003-09-06 19:23:24 +0000 |
---|---|---|
committer | Gerald Carter <jerry@samba.org> | 2003-09-06 19:23:24 +0000 |
commit | c913fc058113b3a3a193f7b98459679945afcf03 (patch) | |
tree | ef134e0d629f2aa8f31953212fd58a4538b22a3c /source3 | |
parent | d5bef211d0cee0f0c7fab5c890694cabd408e6e3 (diff) | |
download | samba-c913fc058113b3a3a193f7b98459679945afcf03.tar.gz samba-c913fc058113b3a3a193f7b98459679945afcf03.tar.bz2 samba-c913fc058113b3a3a193f7b98459679945afcf03.zip |
address bug #359. Andrew B's patch for implementing client
portion of NTLMv2 key exchange. Also revert the default for
'client ntlmv2 auth' to no. This caused no ends of grief in
different cases.
And based on abartlet's mail....
> All I care about at this point is that we use NTLMv2
> in our client code when connecting to a server that
> supports it.
There is *no* way to tell this. The server can't tell us, because it
doesn't know what it's DC supports. The DC can't tell us, because it
doesn't know what the trusted DC supports. One DC might be Win2k, and
the PDC could be an older NT4.
(This used to be commit fe585d49cc3df0d71314ff43d3271d276d7d4503)
Diffstat (limited to 'source3')
-rw-r--r-- | source3/libsmb/cliconnect.c | 5 | ||||
-rw-r--r-- | source3/libsmb/ntlmssp.c | 63 | ||||
-rw-r--r-- | source3/param/loadparm.c | 3 |
3 files changed, 39 insertions, 32 deletions
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 63db6b1aea..48bcb61f92 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -271,10 +271,7 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, if (passlen == 0) { /* do nothing - guest login */ } else if (passlen != 24) { - /* if client ntlmv2 auth is set, then don't use it on a - connection without extended security. This isn't a very - good check, but it is a start */ - if ((cli->capabilities & CAP_EXTENDED_SECURITY) && lp_client_ntlmv2_auth()) { + if (lp_client_ntlmv2_auth()) { DATA_BLOB server_chal; DATA_BLOB names_blob; server_chal = data_blob(cli->secblob.data, MIN(cli->secblob.length, 8)); diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index e4d4acd29b..42bf18d1d2 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -23,12 +23,6 @@ #include "includes.h" -#if 0 -/* we currently do not know how to get the right session key for this, so - we cannot enable it by default... :-( */ -#define USE_NTLM2 1 -#endif - /** * Print out the NTLMSSP flags for debugging * @param neg_flags The flags from the packet @@ -422,9 +416,7 @@ static NTSTATUS ntlmssp_client_initial(struct ntlmssp_client_state *ntlmssp_stat ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2; } -#ifdef USE_NTLM2 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2; -#endif /* generate the ntlmssp negotiate packet */ msrpc_gen(next_request, "CddAA", @@ -459,16 +451,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st DATA_BLOB lm_response = data_blob(NULL, 0); DATA_BLOB nt_response = data_blob(NULL, 0); DATA_BLOB session_key = data_blob(NULL, 0); - uint8 datagram_sess_key[16]; - size_t datagram_sess_key_len; - -#if 0 /* until we know what flag to tigger it on */ - generate_random_buffer(datagram_sess_key, sizeof(datagram_sess_key), False); - datagram_sess_key_len = sizeof(datagram_sess_key); -#else - ZERO_STRUCT(datagram_sess_key); - datagram_sess_key_len = 0; -#endif + DATA_BLOB encrypted_session_key = data_blob(NULL, 0); if (!msrpc_parse(&reply, "CdBd", "NTLMSSP", @@ -502,7 +485,9 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st } else { chal_parse_string = "CdAdbdd"; } + auth_gen_string = "CdBBAAABd"; + ntlmssp_state->unicode = False; ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_UNICODE; ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM; @@ -526,6 +511,10 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_128; } + if (!(chal_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) { + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_KEY_EXCH; + } + DEBUG(3, ("NTLMSSP: Set final flags:\n")); debug_ntlmssp_flags(ntlmssp_state->neg_flags); @@ -572,31 +561,35 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st data_blob_free(&struct_blob); return NT_STATUS_NO_MEMORY; } -#ifdef USE_NTLM2 } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { struct MD5Context md5_session_nonce_ctx; uchar nt_hash[16]; uchar session_nonce[16]; + uchar session_nonce_hash[16]; + uchar nt_session_key[16]; E_md4hash(ntlmssp_state->password, nt_hash); + lm_response = data_blob(NULL, 24); generate_random_buffer(lm_response.data, 8, False); memset(lm_response.data+8, 0, 16); - + + memcpy(session_nonce, challenge_blob.data, 8); + memcpy(&session_nonce[8], lm_response.data, 8); + MD5Init(&md5_session_nonce_ctx); MD5Update(&md5_session_nonce_ctx, challenge_blob.data, 8); MD5Update(&md5_session_nonce_ctx, lm_response.data, 8); - MD5Final(session_nonce, &md5_session_nonce_ctx); + MD5Final(session_nonce_hash, &md5_session_nonce_ctx); nt_response = data_blob(NULL, 24); SMBNTencrypt(ntlmssp_state->password, - challenge_blob.data, + session_nonce_hash, nt_response.data); - /* This is *NOT* the correct session key algorithm - just - fill in the bytes with something... */ session_key = data_blob(NULL, 16); - SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data); -#endif + + SMBsesskeygen_ntv1(nt_hash, NULL, nt_session_key); + hmac_md5(nt_session_key, session_nonce, sizeof(session_nonce), session_key.data); } else { @@ -627,6 +620,18 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st } data_blob_free(&struct_blob); + /* Key exchange encryptes a new client-generated session key with + the password-derived key */ + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { + uint8 client_session_key[16]; + + generate_random_buffer(client_session_key, sizeof(client_session_key), False); + encrypted_session_key = data_blob(client_session_key, sizeof(client_session_key)); + SamOEMhash(encrypted_session_key.data, session_key.data, encrypted_session_key.length); + data_blob_free(&session_key); + session_key = data_blob(client_session_key, sizeof(client_session_key)); + } + /* this generates the actual auth packet */ if (!msrpc_gen(next_request, auth_gen_string, "NTLMSSP", @@ -636,7 +641,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st ntlmssp_state->domain, ntlmssp_state->user, ntlmssp_state->get_global_myname(), - datagram_sess_key, datagram_sess_key_len, + encrypted_session_key.data, encrypted_session_key.length, ntlmssp_state->neg_flags)) { data_blob_free(&lm_response); @@ -645,6 +650,8 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st return NT_STATUS_NO_MEMORY; } + data_blob_free(&encrypted_session_key); + data_blob_free(&ntlmssp_state->chal); data_blob_free(&ntlmssp_state->lm_resp); data_blob_free(&ntlmssp_state->nt_resp); @@ -683,6 +690,8 @@ NTSTATUS ntlmssp_client_start(NTLMSSP_CLIENT_STATE **ntlmssp_state) (*ntlmssp_state)->neg_flags = NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_NTLM | + NTLMSSP_NEGOTIATE_NTLM2 | + NTLMSSP_NEGOTIATE_KEY_EXCH | NTLMSSP_REQUEST_TARGET; (*ntlmssp_state)->ref_count = 1; diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index c801c4c522..41b32cef10 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -1427,7 +1427,8 @@ static void init_globals(void) Globals.bClientPlaintextAuth = True; /* Do use a plaintext password if is requested by the server */ Globals.bLanmanAuth = True; /* Do use the LanMan hash if it is available */ Globals.bNTLMAuth = True; /* Do use NTLMv1 if it is available (otherwise NTLMv2) */ - Globals.bClientNTLMv2Auth = True; /* Client should use NTLMv2 if available. */ + Globals.bClientNTLMv2Auth = False; /* Client should not use NTLMv2, as we can't tell that the server supports it. */ + /* Note, that we will use NTLM2 session security (which is different), if it is available */ Globals.map_to_guest = 0; /* By Default, "Never" */ Globals.min_passwd_length = MINPASSWDLENGTH; /* By Default, 5. */ |