summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2003-09-06 19:23:24 +0000
committerGerald Carter <jerry@samba.org>2003-09-06 19:23:24 +0000
commitc913fc058113b3a3a193f7b98459679945afcf03 (patch)
treeef134e0d629f2aa8f31953212fd58a4538b22a3c
parentd5bef211d0cee0f0c7fab5c890694cabd408e6e3 (diff)
downloadsamba-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)
-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 0bf196488b..611ebcd094 100644
--- a/docs/docbook/smbdotconf/security/clientntlmv2auth.xml
+++ b/docs/docbook/smbdotconf/security/clientntlmv2auth.xml
@@ -13,6 +13,12 @@
(including NT4 &lt; 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. */