r11352: Add newly discovered (via the radiator lists) flags for controlling
authorAndrew Bartlett <abartlet@samba.org>
Fri, 28 Oct 2005 03:40:10 +0000 (03:40 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:45:22 +0000 (13:45 -0500)
plaintext and machine account logins.

Update tests to confirm this behaviour.

Andrew Bartlett

source/librpc/idl/netlogon.idl
source/torture/rpc/samlogon.c

index bec28e3b25f61d7d610f02e3b036ab0f72769e83..80d1026b0a5ace7d25cf9cd1103a8252e74040a5 100644 (file)
@@ -85,6 +85,10 @@ interface netlogon
                [size_is(size/2),length_is(length/2)] uint16 *bindata;
        } netr_AcctLockStr;
 
+       const int MSV1_0_CLEARTEXT_PASSWORD_ALLOWED = 0x002;
+       const int MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT = 0x020;
+       const int MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT = 0x800;
+
        typedef struct {
                lsa_String  domain_name;
                uint32      parameter_control;
index a77b3eaf7b6748caa8c8e627e72fc964104adb97..46e1f90040ed8eab0a912d53eee12ccc212efe5b 100644 (file)
@@ -48,6 +48,7 @@ struct samlogon_state {
        const char *password;
        struct dcerpc_pipe *p;
        int function_level;
+       uint32_t parameter_control;
        struct netr_LogonSamLogon r;
        struct netr_LogonSamLogonEx r_ex;
        struct netr_LogonSamLogonWithFlags r_flags;
@@ -63,6 +64,7 @@ struct samlogon_state {
 */
 static NTSTATUS check_samlogon(struct samlogon_state *samlogon_state, 
                               enum ntlm_break break_which,
+                              uint32_t parameter_control,
                               DATA_BLOB *chall, 
                               DATA_BLOB *lm_response, 
                               DATA_BLOB *nt_response, 
@@ -83,7 +85,7 @@ static NTSTATUS check_samlogon(struct samlogon_state *samlogon_state,
        samlogon_state->r_flags.in.logon.network = &ninfo;
        
        ninfo.identity_info.domain_name.string = samlogon_state->account_domain;
-       ninfo.identity_info.parameter_control = 0;
+       ninfo.identity_info.parameter_control = parameter_control;
        ninfo.identity_info.logon_id_low = 0;
        ninfo.identity_info.logon_id_high = 0;
        ninfo.identity_info.account_name.string = samlogon_state->account_name;
@@ -281,6 +283,7 @@ static BOOL test_lm_ntlm_broken(struct samlogon_state *samlogon_state, enum ntlm
 
        nt_status = check_samlogon(samlogon_state,
                                   break_which,
+                                  samlogon_state->parameter_control,
                                   &samlogon_state->chall,
                                   &lm_response,
                                   &nt_response,
@@ -405,6 +408,7 @@ static BOOL test_ntlm_in_lm(struct samlogon_state *samlogon_state, char **error_
        }
        nt_status = check_samlogon(samlogon_state,
                                   BREAK_NONE,
+                                  samlogon_state->parameter_control,
                                   &samlogon_state->chall,
                                   &nt_response,
                                   NULL,
@@ -432,6 +436,7 @@ static BOOL test_ntlm_in_lm(struct samlogon_state *samlogon_state, char **error_
                        dump_data(1, lm_hash, 8);
                        pass = False;
                }
+#if 0
        } else {
                if (memcmp(session_key.data, lm_key, 
                           sizeof(lm_key)) != 0) {
@@ -442,8 +447,9 @@ static BOOL test_ntlm_in_lm(struct samlogon_state *samlogon_state, char **error_
                        dump_data(1, session_key.data, 8);
                        pass = False;
                }
+#endif
        }
-       if (memcmp(lm_hash, user_session_key, 8) != 0) {
+       if (lm_good && memcmp(lm_hash, user_session_key, 8) != 0) {
                uint8_t lm_key_expected[16];
                memcpy(lm_key_expected, lm_hash, 8);
                memset(lm_key_expected+8, '\0', 8);
@@ -493,6 +499,7 @@ static BOOL test_ntlm_in_both(struct samlogon_state *samlogon_state, char **erro
 
        nt_status = check_samlogon(samlogon_state,
                                   BREAK_NONE,
+                                  samlogon_state->parameter_control,
                                   &samlogon_state->chall,
                                   NULL, 
                                   &nt_response,
@@ -593,6 +600,7 @@ static BOOL test_lmv2_ntlmv2_broken(struct samlogon_state *samlogon_state,
 
        nt_status = check_samlogon(samlogon_state,
                                   break_which,
+                                  samlogon_state->parameter_control,
                                   &samlogon_state->chall,
                                   &lmv2_response,
                                   &ntlmv2_response,
@@ -756,6 +764,7 @@ static BOOL test_lmv2_ntlm_broken(struct samlogon_state *samlogon_state,
 
        nt_status = check_samlogon(samlogon_state,
                                   break_which,
+                                  samlogon_state->parameter_control,
                                   &samlogon_state->chall,
                                   &lmv2_response,
                                   &ntlm_response,
@@ -1038,6 +1047,7 @@ static BOOL test_ntlm2(struct samlogon_state *samlogon_state, char **error_strin
 
        nt_status = check_samlogon(samlogon_state,
                                   BREAK_NONE,
+                                  samlogon_state->parameter_control,
                                   &samlogon_state->chall,
                                   &lm_response,
                                   &nt_response,
@@ -1099,8 +1109,10 @@ static BOOL test_plaintext(struct samlogon_state *samlogon_state, enum ntlm_brea
 
        uint8_t user_session_key[16];
        uint8_t lm_key[16];
+       uint8_t lm_hash[16];
        static const uint8_t zeros[8];
        DATA_BLOB chall = data_blob_talloc(samlogon_state->mem_ctx, zeros, sizeof(zeros));
+       BOOL lm_good = E_deshash(samlogon_state->password, lm_hash); 
 
        ZERO_STRUCT(user_session_key);
        
@@ -1126,6 +1138,7 @@ static BOOL test_plaintext(struct samlogon_state *samlogon_state, enum ntlm_brea
 
        nt_status = check_samlogon(samlogon_state,
                                   break_which,
+                                  samlogon_state->parameter_control | MSV1_0_CLEARTEXT_PASSWORD_ALLOWED,
                                   &chall,
                                   &lm_response,
                                   &nt_response,
@@ -1133,8 +1146,27 @@ static BOOL test_plaintext(struct samlogon_state *samlogon_state, enum ntlm_brea
                                   user_session_key,
                                   error_string);
        
-       if (!NT_STATUS_IS_OK(nt_status)) {
-               return break_which == BREAK_NT;
+       if (NT_STATUS_EQUAL(NT_STATUS_WRONG_PASSWORD, nt_status)) {
+               /* for 'long' passwords, the LM password is invalid */
+               if (break_which == NO_NT && !lm_good) {
+                       return True;
+               }
+               return ((break_which == BREAK_NT) || (break_which == BREAK_BOTH));
+       }
+
+       if (!NT_STATUS_EQUAL(samlogon_state->expected_error, nt_status)) {
+               SAFE_FREE(*error_string);
+               asprintf(error_string, "Expected error: %s, got %s", nt_errstr(samlogon_state->expected_error), nt_errstr(nt_status));
+               return False;
+       } else if (NT_STATUS_EQUAL(samlogon_state->expected_error, nt_status) && !NT_STATUS_IS_OK(nt_status)) {
+               return True;
+       } else if (!NT_STATUS_IS_OK(nt_status)) {
+               return False;
+       }
+
+       if (break_which == NO_NT && !lm_good) {
+               *error_string = strdup("LM password is 'long' (> 14 chars and therefore invalid) but login did not fail!");
+               return False;
        }
 
        return True;
@@ -1219,11 +1251,11 @@ static const struct ntlm_tests {
        {test_lmv2_ntlm_break_ntlm_no_dom, "LMv2 and NTLM, NTLM broken (no domain)", False},
        {test_lmv2_ntlm_break_lm, "LMv2 and NTLM, LMv2 broken", False},
        {test_lmv2_ntlm_break_lm_no_dom, "LMv2 and NTLM, LMv2 broken (no domain)", False},
-       {test_plaintext_none_broken, "Plaintext", True},
-       {test_plaintext_lm_broken, "Plaintext LM broken", True},
-       {test_plaintext_nt_broken, "Plaintext NT broken", True},
-       {test_plaintext_nt_only, "Plaintext NT only", True},
-       {test_plaintext_lm_only, "Plaintext LM only", True},
+       {test_plaintext_none_broken, "Plaintext", False},
+       {test_plaintext_lm_broken, "Plaintext LM broken", False},
+       {test_plaintext_nt_broken, "Plaintext NT broken", False},
+       {test_plaintext_nt_only, "Plaintext NT only", False},
+       {test_plaintext_lm_only, "Plaintext LM only", False},
        {NULL, NULL}
 };
 
@@ -1234,7 +1266,8 @@ static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                          struct creds_CredentialState *creds, 
                          const char *comment,
                          const char *account_domain, const char *account_name, 
-                         const char *plain_pass, NTSTATUS expected_error,
+                         const char *plain_pass, uint32_t parameter_control,
+                         NTSTATUS expected_error,
                          int n_subtests)
 {
        TALLOC_CTX *fn_ctx = talloc_named(mem_ctx, 0, "test_SamLogon function-level context");
@@ -1258,6 +1291,7 @@ static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
        samlogon_state.creds = creds;
        samlogon_state.expected_error = expected_error;
        samlogon_state.chall = data_blob_talloc(fn_ctx, NULL, 8);
+       samlogon_state.parameter_control = parameter_control;
 
        generate_random_buffer(samlogon_state.chall.data, 8);
        samlogon_state.r_flags.in.server_name = talloc_asprintf(fn_ctx, "\\\\%s", dcerpc_server_name(p));
@@ -1489,6 +1523,7 @@ BOOL torture_rpc_samlogon(void)
                        BOOL network_login;
                        NTSTATUS expected_interactive_error;
                        NTSTATUS expected_network_error;
+                       uint32_t parameter_control;
                } usercreds[] = {
                        {
                                .comment       = "domain\\user",
@@ -1541,7 +1576,7 @@ BOOL torture_rpc_samlogon(void)
                                .password     = cli_credentials_get_password(machine_credentials),
                                .network_login = True,
                                .expected_interactive_error = NT_STATUS_NO_SUCH_USER,
-                               .expected_network_error     = NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT
+                               .parameter_control = MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT
                        },
                        {
                                .comment       = "machine realm\\user",
@@ -1550,7 +1585,7 @@ BOOL torture_rpc_samlogon(void)
                                .password      = cli_credentials_get_password(machine_credentials),
                                .network_login = True,
                                .expected_interactive_error = NT_STATUS_NO_SUCH_USER,
-                               .expected_network_error     = NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT
+                               .parameter_control = MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT
                        },
                        {
                                .comment       = "machine user@domain",
@@ -1563,7 +1598,7 @@ BOOL torture_rpc_samlogon(void)
                                .password      = cli_credentials_get_password(machine_credentials),
                                .network_login = False,
                                .expected_interactive_error = NT_STATUS_NO_SUCH_USER,
-                               .expected_network_error     = NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT
+                               .parameter_control = MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT
                        },
                        {
                                .comment       = "machine user@realm",
@@ -1576,7 +1611,7 @@ BOOL torture_rpc_samlogon(void)
                                .password      = cli_credentials_get_password(machine_credentials),
                                .network_login = True,
                                .expected_interactive_error = NT_STATUS_NO_SUCH_USER,
-                               .expected_network_error     = NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT
+                               .parameter_control = MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT
                        },
                        {       
                                .comment       = "test user (long pw): domain\\user",
@@ -1642,6 +1677,7 @@ BOOL torture_rpc_samlogon(void)
                                                   usercreds[ci].domain,
                                                   usercreds[ci].username,
                                                   usercreds[ci].password,
+                                                  usercreds[ci].parameter_control,
                                                   usercreds[ci].expected_network_error,
                                                   0)) {
                                        ret = False;
@@ -1670,6 +1706,7 @@ BOOL torture_rpc_samlogon(void)
                                                   usercreds[0].domain,
                                                   usercreds[0].username,
                                                   usercreds[0].password,
+                                                  usercreds[0].parameter_control,
                                                   usercreds[0].expected_network_error,
                                                   1)) {
                                        ret = False;