Based on the detective work of Jianliang Lu <j.lu@tiesse.com>, allow yet
authorAndrew Bartlett <abartlet@samba.org>
Sat, 27 Mar 2004 07:53:47 +0000 (07:53 +0000)
committerAndrew Bartlett <abartlet@samba.org>
Sat, 27 Mar 2004 07:53:47 +0000 (07:53 +0000)
another NTLMv2 combination.

We should allow the NTLMv2 response to be calculated with either the domain
as supplied, or the domain in UPPER case (as we always did in the past).

As a client, we always UPPER case it (as per the spec), but we also
make sure to UPPER case the domain, when we send it.  This should give
us maximum compatability.

Andrew Bartlett
(This used to be commit 1e91cd0cf87b29899641585f46b0dcecaefd848e)

source3/lib/talloc.c
source3/libsmb/cliconnect.c
source3/libsmb/ntlm_check.c
source3/libsmb/ntlmssp.c
source3/libsmb/smbencrypt.c

index 485dc28f31d3897656cc5a1da1cf9151db8e94bd..093a221fd3d44b40fe29d07da719b826c4a9ed1f 100644 (file)
@@ -276,6 +276,24 @@ char *talloc_strdup(TALLOC_CTX *t, const char *p)
                return NULL;
 }
 
+/** strdup_upper with a talloc */
+char *talloc_strdup_upper(TALLOC_CTX *t, const char *p)
+{
+       char *r;
+       if (p) {
+               char *q = strdup_upper(p);
+               if (q) { 
+                       r = talloc_strdup(t, q);
+                       SAFE_FREE(q);
+                       return r;
+               } else {
+                       return NULL;
+               }
+       } else {
+               return NULL;
+       }
+}
+
 /** strdup_w with a talloc */
 smb_ucs2_t *talloc_strdup_w(TALLOC_CTX *t, const smb_ucs2_t *p)
 {
index 63541e18b5da913ab4f36960ba0b4ec42589af22..adfeec229049259d2e76222948a4c0f0bf03fd41 100644 (file)
@@ -358,7 +358,9 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user,
                memcpy(p,nt_response.data, nt_response.length); p += nt_response.length;
        }
        p += clistr_push(cli, p, user, -1, STR_TERMINATE);
-       p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE);
+
+       /* Upper case here might help some NTLMv2 implementations */
+       p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE|STR_UPPER);
        p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE);
        p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE);
        cli_setup_bcc(cli, p);
@@ -649,7 +651,7 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use
                           for checking the first reply from the server */
                        cli_calculate_sign_mac(cli);
                        
-                       if (!cli_check_sign_mac(cli, True)) {
+                       if (!cli_check_sign_mac(cli, False)) {
                                nt_status = NT_STATUS_ACCESS_DENIED;
                        }
                }
@@ -874,7 +876,7 @@ BOOL cli_send_tconX(struct cli_state *cli,
 
        if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && *pass && passlen != 24) {
                if (!lp_client_lanman_auth()) {
-                       DEBUG(1, ("Server requested LANMAN password but 'client use lanman auth'"
+                       DEBUG(1, ("Server requested LANMAN password (share-level security) but 'client use lanman auth'"
                                  " is disabled\n"));
                        return False;
                }
index 362b640f913834d839ac88a2f3c74167445030ef..bc291b512863f139462328598b45e04b289ea670 100644 (file)
@@ -85,6 +85,7 @@ static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB *ntv2_response,
                                 const uchar *part_passwd,
                                 const DATA_BLOB *sec_blob,
                                 const char *user, const char *domain,
+                                BOOL upper_case_domain, /* should the domain be transformed into upper case? */
                                 DATA_BLOB *user_sess_key)
 {
        /* Finish the encryption of part_passwd. */
@@ -122,7 +123,7 @@ static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB *ntv2_response,
 
        memcpy(client_response, ntv2_response->data, sizeof(client_response));
 
-       if (!ntv2_owf_gen(part_passwd, user, domain, kr)) {
+       if (!ntv2_owf_gen(part_passwd, user, domain, upper_case_domain, kr)) {
                return False;
        }
 
@@ -235,13 +236,24 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx,
        if (nt_response->length >= 24 && nt_pw) {
                if (nt_response->length > 24) {
                        /* We have the NT MD4 hash challenge available - see if we can
-                          use it (ie. does it exist in the smbpasswd file).
+                          use it 
                        */
                        DEBUG(4,("ntlm_password_check: Checking NTLMv2 password with domain [%s]\n", client_domain));
                        if (smb_pwd_check_ntlmv2( nt_response, 
                                                  nt_pw, challenge, 
-                                         client_username, 
+                                                 client_username, 
+                                                 client_domain,
+                                                 False,
+                                                 user_sess_key)) {
+                               return NT_STATUS_OK;
+                       }
+                       
+                       DEBUG(4,("ntlm_password_check: Checking NTLMv2 password with uppercased version of domain [%s]\n", client_domain));
+                       if (smb_pwd_check_ntlmv2( nt_response, 
+                                                 nt_pw, challenge, 
+                                                 client_username, 
                                                  client_domain,
+                                                 True,
                                                  user_sess_key)) {
                                return NT_STATUS_OK;
                        }
@@ -251,6 +263,7 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx,
                                                  nt_pw, challenge, 
                                                  client_username, 
                                                  "",
+                                                 False,
                                                  user_sess_key)) {
                                return NT_STATUS_OK;
                        } else {
@@ -334,6 +347,17 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx,
                                  nt_pw, challenge, 
                                  client_username,
                                  client_domain,
+                                 False,
+                                 NULL)) {
+               return NT_STATUS_OK;
+       }
+       
+       DEBUG(4,("ntlm_password_check: Checking LMv2 password with upper-cased version of domain %s\n", client_domain));
+       if (smb_pwd_check_ntlmv2( lm_response, 
+                                 nt_pw, challenge, 
+                                 client_username,
+                                 client_domain,
+                                 True,
                                  NULL)) {
                return NT_STATUS_OK;
        }
@@ -343,6 +367,7 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx,
                                  nt_pw, challenge, 
                                  client_username,
                                  "",
+                                 False,
                                  NULL)) {
                return NT_STATUS_OK;
        }
index 60523ddf9d08034ba8e54681affcb7c7647a5a20..82eafc4cd53045848af14ed85d67eef51846ce3d 100644 (file)
@@ -168,7 +168,9 @@ NTSTATUS ntlmssp_set_password(NTLMSSP_STATE *ntlmssp_state, const char *password
  */
 NTSTATUS ntlmssp_set_domain(NTLMSSP_STATE *ntlmssp_state, const char *domain) 
 {
-       ntlmssp_state->domain = talloc_strdup(ntlmssp_state->mem_ctx, domain);
+       /* Possibly make our NTLMv2 client more robust by always having 
+          an uppercase domain */
+       ntlmssp_state->domain = talloc_strdup_upper(ntlmssp_state->mem_ctx, domain);
        if (!ntlmssp_state->domain) {
                return NT_STATUS_NO_MEMORY;
        }
index c5acedae51c2158bc2e36b2fe37377fa403e314c..270a659e57fba818c8e0889c5af43c3856f8d3c5 100644 (file)
@@ -127,7 +127,9 @@ void nt_lm_owf_gen(const char *pwd, uchar nt_p16[16], uchar p16[16])
 
 /* Does both the NTLMv2 owfs of a user's password */
 BOOL ntv2_owf_gen(const uchar owf[16],
-                 const char *user_in, const char *domain_in, uchar kr_buf[16])
+                 const char *user_in, const char *domain_in,
+                 BOOL upper_case_domain, /* Transform the domain into UPPER case */
+                 uchar kr_buf[16])
 {
        smb_ucs2_t *user;
        smb_ucs2_t *domain;
@@ -150,7 +152,9 @@ BOOL ntv2_owf_gen(const uchar owf[16],
        }
 
        strupper_w(user);
-       strupper_w(domain);
+
+       if (upper_case_domain)
+               strupper_w(domain);
 
        SMB_ASSERT(user_byte_len >= 2);
        SMB_ASSERT(domain_byte_len >= 2);
@@ -426,7 +430,7 @@ BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password
           the username and domain.
           This prevents username swapping during the auth exchange
        */
-       if (!ntv2_owf_gen(nt_hash, user, domain, ntlm_v2_hash)) {
+       if (!ntv2_owf_gen(nt_hash, user, domain, True, ntlm_v2_hash)) {
                return False;
        }