diff options
-rw-r--r-- | docs/docbook/smbdotconf/security/clientntlmv2auth.xml | 6 | ||||
-rw-r--r-- | source3/libsmb/cliconnect.c | 5 | ||||
-rw-r--r-- | source3/libsmb/ntlmssp.c | 63 | ||||
-rw-r--r-- | source3/param/loadparm.c | 3 |
4 files changed, 45 insertions, 32 deletions
diff --git a/docs/docbook/smbdotconf/security/clientntlmv2auth.xml b/docs/docbook/smbdotconf/security/clientntlmv2auth.xml index 0bf196488b..611ebcd094 100644 --- a/docs/docbook/smbdotconf/security/clientntlmv2auth.xml +++ b/docs/docbook/smbdotconf/security/clientntlmv2auth.xml @@ -13,6 +13,12 @@ (including NT4 < SP4, Win9x and Samba 2.2) are not compatible with NTLMv2. </para> + <para>Similarly, if enabled, NTLMv1, <command + moreinfo="none">client lanman auth</command> and <command + moreinfo="none">client plaintext auth</command> + authentication will be disabled. This also disables share-level + authentication. </para> + <para>If disabled, an NTLM response (and possibly a LANMAN response) will be sent by the client, depending on the value of <command moreinfo="none">client lanman auth</command>. </para> 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. */ |