r4566: Fix Samba4 to pass it's own RPC-SAMLOGON torture test.
authorAndrew Bartlett <abartlet@samba.org>
Thu, 6 Jan 2005 12:13:31 +0000 (12:13 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:08:28 +0000 (13:08 -0500)
Include RPC-SAMLOGON in the list of tests expected to pass

Remove silly extra loops from the RPC-SAMLOGON test, which mostly just
slowed htings down.

Andrew Bartlett
(This used to be commit 518ca9fb695b0f9d480122a74a2159f7f17a3219)

source4/auth/ntlm_check.c
source4/script/tests/test_rpc.sh
source4/torture/rpc/samlogon.c

index 474742bee0bbdcc210714bdbd4dfa3b44cd3edc1..b3087419709b7abed7727aa685d71872adf51f29 100644 (file)
@@ -58,11 +58,6 @@ static BOOL smb_pwd_check_ntlmv1(TALLOC_CTX *mem_ctx,
        }
 
        SMBOWFencrypt(part_passwd, sec_blob->data, p24);
-       if (user_sess_key != NULL) {
-               *user_sess_key = data_blob_talloc(mem_ctx, NULL, 16);
-               SMBsesskeygen_ntv1(part_passwd, user_sess_key->data);
-       }
-       
        
 #if DEBUG_PASSWORD
        DEBUG(100,("Part password (P16) was |\n"));
@@ -74,7 +69,14 @@ static BOOL smb_pwd_check_ntlmv1(TALLOC_CTX *mem_ctx,
        DEBUGADD(100,("Value from encryption was |\n"));
        dump_data(100, p24, 24);
 #endif
-       return (memcmp(p24, nt_response->data, 24) == 0);
+       if (memcmp(p24, nt_response->data, 24) == 0) {
+               if (user_sess_key != NULL) {
+                       *user_sess_key = data_blob_talloc(mem_ctx, NULL, 16);
+                       SMBsesskeygen_ntv1(part_passwd, user_sess_key->data);
+               }
+               return True;
+       } 
+       return False;
 }
 
 /****************************************************************************
@@ -93,7 +95,6 @@ static BOOL smb_pwd_check_ntlmv2(TALLOC_CTX *mem_ctx,
        /* Finish the encryption of part_passwd. */
        uint8_t kr[16];
        uint8_t value_from_encryption[16];
-       uint8_t client_response[16];
        DATA_BLOB client_key_data;
 
        if (part_passwd == NULL) {
@@ -123,17 +124,11 @@ static BOOL smb_pwd_check_ntlmv2(TALLOC_CTX *mem_ctx,
           but for NTLMv2 it is meant to contain the current time etc.
        */
 
-       memcpy(client_response, ntv2_response->data, sizeof(client_response));
-
        if (!ntv2_owf_gen(part_passwd, user, domain, upper_case_domain, kr)) {
                return False;
        }
 
        SMBOWFencrypt_ntv2(kr, sec_blob, &client_key_data, value_from_encryption);
-       if (user_sess_key != NULL) {
-               *user_sess_key = data_blob_talloc(mem_ctx, NULL, 16);
-               SMBsesskeygen_ntv2(kr, value_from_encryption, user_sess_key->data);
-       }
 
 #if DEBUG_PASSWORD
        DEBUG(100,("Part password (P16) was |\n"));
@@ -148,7 +143,65 @@ static BOOL smb_pwd_check_ntlmv2(TALLOC_CTX *mem_ctx,
        dump_data(100, value_from_encryption, 16);
 #endif
        data_blob_clear_free(&client_key_data);
-       return (memcmp(value_from_encryption, client_response, 16) == 0);
+       if (memcmp(value_from_encryption, ntv2_response->data, 16) == 0) { 
+               if (user_sess_key != NULL) {
+                       *user_sess_key = data_blob_talloc(mem_ctx, NULL, 16);
+                       SMBsesskeygen_ntv2(kr, value_from_encryption, user_sess_key->data);
+               }
+               return True;
+       }
+       return False;
+}
+
+/****************************************************************************
+ Core of smb password checking routine. (NTLMv2, LMv2)
+ Note:  The same code works with both NTLMv2 and LMv2.
+****************************************************************************/
+
+static BOOL smb_sess_key_ntlmv2(TALLOC_CTX *mem_ctx,
+                               const DATA_BLOB *ntv2_response,
+                               const uint8_t *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. */
+       uint8_t kr[16];
+       uint8_t value_from_encryption[16];
+       DATA_BLOB client_key_data;
+
+       if (part_passwd == NULL) {
+               DEBUG(10,("No password set - DISALLOWING access\n"));
+               /* No password set - always False */
+               return False;
+       }
+
+       if (sec_blob->length != 8) {
+               DEBUG(0, ("smb_sess_key_ntlmv2: incorrect challenge size (%lu)\n", 
+                         (unsigned long)sec_blob->length));
+               return False;
+       }
+       
+       if (ntv2_response->length < 24) {
+               /* We MUST have more than 16 bytes, or the stuff below will go
+                  crazy.  No known implementation sends less than the 24 bytes
+                  for LMv2, let alone NTLMv2. */
+               DEBUG(0, ("smb_sess_key_ntlmv2: incorrect password length (%lu)\n", 
+                         (unsigned long)ntv2_response->length));
+               return False;
+       }
+
+       client_key_data = data_blob_talloc(mem_ctx, ntv2_response->data+16, ntv2_response->length-16);
+
+       if (!ntv2_owf_gen(part_passwd, user, domain, upper_case_domain, kr)) {
+               return False;
+       }
+
+       SMBOWFencrypt_ntv2(kr, sec_blob, &client_key_data, value_from_encryption);
+       *user_sess_key = data_blob_talloc(mem_ctx, NULL, 16);
+       SMBsesskeygen_ntv2(kr, value_from_encryption, user_sess_key->data);
+       return True;
 }
 
 /**
@@ -182,6 +235,8 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx,
                             DATA_BLOB *lm_sess_key)
 {
        static const uint8_t zeros[8];
+       DATA_BLOB tmp_sess_key;
+
        if (nt_pw == NULL) {
                DEBUG(3,("ntlm_password_check: NO NT password stored for user %s.\n", 
                         username));
@@ -299,7 +354,9 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx,
                                         user_sess_key)) {
                        if (lm_sess_key) {
                                *lm_sess_key = *user_sess_key;
-                               lm_sess_key->length = 8;
+                               if (user_sess_key->length) {
+                                       lm_sess_key->length = 8;
+                               }
                        }
                        return NT_STATUS_OK;
                }
@@ -314,7 +371,9 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx,
                                         user_sess_key)) {
                        if (lm_sess_key) {
                                *lm_sess_key = *user_sess_key;
-                               lm_sess_key->length = 8;
+                               if (user_sess_key->length) {
+                                       lm_sess_key->length = 8;
+                               }
                        }
                        return NT_STATUS_OK;
                }
@@ -329,7 +388,9 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx,
                                         user_sess_key)) {
                        if (lm_sess_key) {
                                *lm_sess_key = *user_sess_key;
-                               lm_sess_key->length = 8;
+                               if (user_sess_key->length) {
+                                       lm_sess_key->length = 8;
+                               }
                        }
                        return NT_STATUS_OK;
                } else {
@@ -418,10 +479,28 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx,
                                 client_username,
                                 client_domain,
                                 False,
-                                user_sess_key)) {
-               if (lm_sess_key) {
+                                &tmp_sess_key)) {
+               if (nt_response->length > 24) {
+                       /* If NTLMv2 authentication has preceeded us
+                        * (even if it failed), then use the session
+                        * key from that.  See the RPC-SAMLOGON
+                        * torture test */
+                       smb_sess_key_ntlmv2(mem_ctx,
+                                           nt_response, 
+                                           nt_pw, challenge, 
+                                           client_username,
+                                           client_domain,
+                                           False,
+                                           user_sess_key);
+               } else if (user_sess_key) {
+                       /* Otherwise, use the LMv2 session key */
+                       *user_sess_key = tmp_sess_key;
+               }
+               if (user_sess_key && lm_sess_key) {
                        *lm_sess_key = *user_sess_key;
-                       lm_sess_key->length = 8;
+                       if (user_sess_key->length) {
+                               lm_sess_key->length = 8;
+                       }
                }
                return NT_STATUS_OK;
        }
@@ -433,10 +512,28 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx,
                                 client_username,
                                 client_domain,
                                 True,
-                                user_sess_key)) {
-               if (lm_sess_key) {
+                                &tmp_sess_key)) {
+               if (nt_response->length > 24) {
+                       /* If NTLMv2 authentication has preceeded us
+                        * (even if it failed), then use the session
+                        * key from that.  See the RPC-SAMLOGON
+                        * torture test */
+                       smb_sess_key_ntlmv2(mem_ctx,
+                                           nt_response, 
+                                           nt_pw, challenge, 
+                                           client_username,
+                                           client_domain,
+                                           True,
+                                           user_sess_key);
+               } else if (user_sess_key) {
+                       /* Otherwise, use the LMv2 session key */
+                       *user_sess_key = tmp_sess_key;
+               }
+               if (user_sess_key && lm_sess_key) {
                        *lm_sess_key = *user_sess_key;
-                       lm_sess_key->length = 8;
+                       if (user_sess_key->length) {
+                               lm_sess_key->length = 8;
+                       }
                }
                return NT_STATUS_OK;
        }
@@ -448,10 +545,28 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx,
                                 client_username,
                                 "",
                                 False,
-                                user_sess_key)) {
-               if (lm_sess_key) {
+                                &tmp_sess_key)) {
+               if (nt_response->length > 24) {
+                       /* If NTLMv2 authentication has preceeded us
+                        * (even if it failed), then use the session
+                        * key from that.  See the RPC-SAMLOGON
+                        * torture test */
+                       smb_sess_key_ntlmv2(mem_ctx,
+                                           nt_response, 
+                                           nt_pw, challenge, 
+                                           client_username,
+                                           "",
+                                           False,
+                                           user_sess_key);
+               } else if (user_sess_key) {
+                       /* Otherwise, use the LMv2 session key */
+                       *user_sess_key = tmp_sess_key;
+               }
+               if (user_sess_key && lm_sess_key) {
                        *lm_sess_key = *user_sess_key;
-                       lm_sess_key->length = 8;
+                       if (user_sess_key->length) {
+                               lm_sess_key->length = 8;
+                       }
                }
                return NT_STATUS_OK;
        }
index a1181cab4207c87e9528e7627e95c752afad93d2..c15ce87b05fc46af9a9b2d62c506d067bc6dc2b5 100755 (executable)
@@ -2,9 +2,9 @@
 
 # add tests to this list as they start passing, so we test
 # that they stay passing
-ncacn_np_tests="RPC-SCHANNEL RPC-ECHO RPC-DSSETUP"
-ncalrpc_tests="RPC-SCHANNEL RPC-ECHO RPC-DSSETUP"
-ncacn_ip_tcp_tests="RPC-SCHANNEL RPC-ECHO"
+ncacn_np_tests="RPC-SCHANNEL RPC-ECHO RPC-DSSETUP RPC-SAMLOGON"
+ncalrpc_tests="RPC-SCHANNEL RPC-ECHO RPC-DSSETUP RPC-SAMLOGON"
+ncacn_ip_tcp_tests="RPC-SCHANNEL RPC-ECHO RPC-SAMLOGON"
 
 if [ $# -lt 4 ]; then
 cat <<EOF
index 0c5afd44fe863adb87f6d243161b504e41ed12f4..7e5579b213d6c5d432a5edbb51d1b3c6b33fd69e 100644 (file)
@@ -582,7 +582,7 @@ static BOOL test_lmv2_ntlmv2_broken(struct samlogon_state *samlogon_state, enum
 
        switch (break_which) {
        case NO_NT:
-               if (memcmp(lmv2_session_key.data, user_session_key, 
+               if (memcmp(lmv2_session_key.data, user_session_key,
                           sizeof(user_session_key)) != 0) {
                        printf("USER (LMv2) Session Key does not match expectations!\n");
                        printf("user_session_key:\n");
@@ -604,21 +604,42 @@ static BOOL test_lmv2_ntlmv2_broken(struct samlogon_state *samlogon_state, enum
        default:
                if (memcmp(ntlmv2_session_key.data, user_session_key, 
                           sizeof(user_session_key)) != 0) {
-                       printf("USER (NTLMv2) Session Key does not match expectations!\n");
-                       printf("user_session_key:\n");
-                       dump_data(1, user_session_key, 16);
-                       printf("expected:\n");
-                       dump_data(1, ntlmv2_session_key.data, ntlmv2_session_key.length);
-                       pass = False;
+                       if (memcmp(lmv2_session_key.data, user_session_key,
+                                  sizeof(user_session_key)) == 0) {
+                               printf("USER (NTLMv2) Session Key expected, got LMv2 sessesion key instead:\n");
+                               printf("user_session_key:\n");
+                               dump_data(1, user_session_key, 16);
+                               printf("expected:\n");
+                               dump_data(1, ntlmv2_session_key.data, ntlmv2_session_key.length);
+                               pass = False;
+                               
+                       } else {
+                               printf("USER (NTLMv2) Session Key does not match expectations!\n");
+                               printf("user_session_key:\n");
+                               dump_data(1, user_session_key, 16);
+                               printf("expected:\n");
+                               dump_data(1, ntlmv2_session_key.data, ntlmv2_session_key.length);
+                               pass = False;
+                       }
                }
                if (memcmp(ntlmv2_session_key.data, lm_session_key, 
                           sizeof(lm_session_key)) != 0) {
-                       printf("LM (NTLMv2) Session Key does not match expectations!\n");
-                       printf("lm_session_key:\n");
-                       dump_data(1, lm_session_key, 8);
-                       printf("expected:\n");
-                       dump_data(1, ntlmv2_session_key.data, 8);
-                       pass = False;
+                       if (memcmp(lmv2_session_key.data, lm_session_key,
+                                  sizeof(lm_session_key)) == 0) {
+                               printf("LM (NTLMv2) Session Key expected, got LMv2 sessesion key instead:\n");
+                               printf("user_session_key:\n");
+                               dump_data(1, lm_session_key, 8);
+                               printf("expected:\n");
+                               dump_data(1, ntlmv2_session_key.data, 8);
+                               pass = False;
+                       } else {
+                               printf("LM (NTLMv2) Session Key does not match expectations!\n");
+                               printf("lm_session_key:\n");
+                               dump_data(1, lm_session_key, 8);
+                               printf("expected:\n");
+                               dump_data(1, ntlmv2_session_key.data, 8);
+                               pass = False;
+                       }
                }
        }
 
@@ -1267,21 +1288,6 @@ BOOL torture_rpc_samlogon(void)
                }
        }
 
-       for (i=0; i < 32; i++) {
-               if (!test_SetupCredentials2(p, mem_ctx, 1 << i,
-                                           TEST_MACHINE_NAME, machine_password, creds)) {
-                       return False;
-               }
-               
-               if (!test_InteractiveLogon(p, mem_ctx, creds)) {
-                       ret = False;
-               }
-               
-               if (!test_SamLogon(p, mem_ctx, creds)) {
-                       ret = False;
-               }
-       }
-
 failed:
        talloc_destroy(mem_ctx);