summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/docbook/smbdotconf/security/clientntlmv2auth.xml6
-rw-r--r--source3/libsmb/cliconnect.c5
-rw-r--r--source3/libsmb/ntlmssp.c63
-rw-r--r--source3/param/loadparm.c3
4 files changed, 45 insertions, 32 deletions
diff --git a/docs/docbook/smbdotconf/security/clientntlmv2auth.xml b/docs/docbook/smbdotconf/security/clientntlmv2auth.xml
index 0bf196488bc..611ebcd0947 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 63db6b1aeaf..48bcb61f926 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 e4d4acd29b0..42bf18d1d26 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 c801c4c522f..41b32cef109 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. */