r6793: Move auth_sam to use the dnsDomain rather than the
[samba.git] / source / torture / rpc / samlogon.c
index 3e12054e039c4e0d8c72f92981d6ebd1d64776fc..104583058a08a921c27c432ebe026d104797bf0d 100644 (file)
 #include "librpc/gen_ndr/ndr_netlogon.h"
 #include "auth/auth.h"
 #include "lib/crypto/crypto.h"
+#include "lib/cmdline/popt_common.h"
 
 #define TEST_MACHINE_NAME "samlogontest"
+#define TEST_USER_NAME "samlogontestuser"
 
 enum ntlm_break {
        BREAK_BOTH,
@@ -73,7 +75,7 @@ static NTSTATUS check_samlogon(struct samlogon_state *samlogon_state,
        struct netr_LogonSamLogonWithFlags *r_flags = &samlogon_state->r_flags;
        struct netr_NetworkInfo ninfo;
        struct netr_SamBaseInfo *base = NULL;
-       uint16 validation_level = 0;
+       uint16_t validation_level = 0;
        
        samlogon_state->r.in.logon.network = &ninfo;
        samlogon_state->r_ex.in.logon.network = &ninfo;
@@ -1035,6 +1037,7 @@ static const struct ntlm_tests {
        const char *name;
        BOOL expect_fail;
 } test_table[] = {
+       {test_lmv2_ntlmv2, "NTLMv2 and LMv2", False},
        {test_lm, "LM", False},
        {test_lm_ntlm, "LM and NTLM", False},
        {test_lm_ntlm_both_broken, "LM and NTLM, both broken", False},
@@ -1042,7 +1045,6 @@ static const struct ntlm_tests {
        {test_ntlm_in_lm, "NTLM in LM", False},
        {test_ntlm_in_both, "NTLM in both", False},
        {test_ntlmv2, "NTLMv2", False},
-       {test_lmv2_ntlmv2, "NTLMv2 and LMv2", False},
        {test_lmv2, "LMv2", False},
        {test_ntlmv2_lmv2_broken, "NTLMv2 and LMv2, LMv2 broken", False},
        {test_ntlmv2_ntlmv2_broken, "NTLMv2 and LMv2, NTLMv2 broken", False},
@@ -1065,8 +1067,12 @@ static const struct ntlm_tests {
   try a netlogon SamLogon
 */
 static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
-                         struct creds_CredentialState *creds)
+                         struct creds_CredentialState *creds, 
+                         const char *account_domain, const char *account_name, 
+                         const char *plain_pass,
+                         int n_subtests)
 {
+       TALLOC_CTX *fn_ctx = talloc_named(mem_ctx, 0, "test_SamLogon function-level context");
        int i, v, l, f;
        BOOL ret = True;
        int validation_levels[] = {2,3,6};
@@ -1079,36 +1085,40 @@ static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
        
        printf("testing netr_LogonSamLogon and netr_LogonSamLogonWithFlags\n");
        
-       samlogon_state.mem_ctx = mem_ctx;
-       samlogon_state.account_name = lp_parm_string(-1, "torture", "username");
-       samlogon_state.account_domain = lp_parm_string(-1, "torture", "userdomain");
-       samlogon_state.password = lp_parm_string(-1, "torture", "password");
+       samlogon_state.account_name = account_name;
+       samlogon_state.account_domain = account_domain;
+       samlogon_state.password = plain_pass;
        samlogon_state.p = p;
        samlogon_state.creds = creds;
 
-       samlogon_state.chall = data_blob_talloc(mem_ctx, NULL, 8);
+       samlogon_state.chall = data_blob_talloc(fn_ctx, NULL, 8);
 
        generate_random_buffer(samlogon_state.chall.data, 8);
-       samlogon_state.r_flags.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
+       samlogon_state.r_flags.in.server_name = talloc_asprintf(fn_ctx, "\\\\%s", dcerpc_server_name(p));
        samlogon_state.r_flags.in.workstation = TEST_MACHINE_NAME;
        samlogon_state.r_flags.in.credential = &samlogon_state.auth;
        samlogon_state.r_flags.in.return_authenticator = &samlogon_state.auth2;
        samlogon_state.r_flags.in.flags = 0;
 
-       samlogon_state.r_ex.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
+       samlogon_state.r_ex.in.server_name = talloc_asprintf(fn_ctx, "\\\\%s", dcerpc_server_name(p));
        samlogon_state.r_ex.in.workstation = TEST_MACHINE_NAME;
        samlogon_state.r_ex.in.flags = 0;
 
-       samlogon_state.r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
+       samlogon_state.r.in.server_name = talloc_asprintf(fn_ctx, "\\\\%s", dcerpc_server_name(p));
        samlogon_state.r.in.workstation = TEST_MACHINE_NAME;
        samlogon_state.r.in.credential = &samlogon_state.auth;
        samlogon_state.r.in.return_authenticator = &samlogon_state.auth2;
 
        for (f=0;f<ARRAY_SIZE(function_levels);f++) {
                for (i=0; test_table[i].fn; i++) {
+                       if (n_subtests && (i > n_subtests)) {
+                               continue;
+                       }
                        for (v=0;v<ARRAY_SIZE(validation_levels);v++) {
                                for (l=0;l<ARRAY_SIZE(logon_levels);l++) {
                                        char *error_string = NULL;
+                                       TALLOC_CTX *tmp_ctx = talloc_named(fn_ctx, 0, "test_SamLogon inner loop");
+                                       samlogon_state.mem_ctx = tmp_ctx;
                                        samlogon_state.function_level = function_levels[f];
                                        samlogon_state.r.in.validation_level = validation_levels[v];
                                        samlogon_state.r.in.logon_level = logon_levels[l];
@@ -1117,7 +1127,9 @@ static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                                        samlogon_state.r_flags.in.validation_level = validation_levels[v];
                                        samlogon_state.r_flags.in.logon_level = logon_levels[l];
                                        if (!test_table[i].fn(&samlogon_state, &error_string)) {
-                                               printf("Testing '%s' at validation level %d, logon level %d, function %d: \n", 
+                                               printf("Testing [%s]\\[%s] '%s' at validation level %d, logon level %d, function %d: \n", 
+                                                      samlogon_state.account_domain,
+                                                      samlogon_state.account_name,
                                                       test_table[i].name, validation_levels[v], 
                                                       logon_levels[l], function_levels[f]);
                                                
@@ -1129,11 +1141,12 @@ static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                                                }
                                                SAFE_FREE(error_string);
                                        }
+                                       talloc_free(tmp_ctx);
                                }
                        }
                }
        }
-
+       talloc_free(fn_ctx);
        return ret;
 }
 
@@ -1141,13 +1154,15 @@ static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
   test an ADS style interactive domain logon
 */
 static BOOL test_InteractiveLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
-                                 struct creds_CredentialState *creds)
+                                 struct creds_CredentialState *creds, 
+                                 const char *account_domain, const char *account_name,
+                                 const char *plain_pass)
 {
        NTSTATUS status;
+       TALLOC_CTX *fn_ctx = talloc_named(mem_ctx, 0, "test_InteractiveLogon function-level context");
        struct netr_LogonSamLogonWithFlags r;
        struct netr_Authenticator a, ra;
        struct netr_PasswordInfo pinfo;
-       const char *plain_pass;
 
        ZERO_STRUCT(a);
        ZERO_STRUCT(r);
@@ -1155,7 +1170,7 @@ static BOOL test_InteractiveLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
 
        creds_client_authenticator(creds, &a);
 
-       r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
+       r.in.server_name = talloc_asprintf(fn_ctx, "\\\\%s", dcerpc_server_name(p));
        r.in.workstation = TEST_MACHINE_NAME;
        r.in.credential = &a;
        r.in.return_authenticator = &ra;
@@ -1164,15 +1179,13 @@ static BOOL test_InteractiveLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
        r.in.validation_level = 6;
        r.in.flags = 0;
 
-       pinfo.identity_info.domain_name.string = lp_parm_string(-1, "torture", "userdomain");
+       pinfo.identity_info.domain_name.string = account_domain;
        pinfo.identity_info.parameter_control = 0;
        pinfo.identity_info.logon_id_low = 0;
        pinfo.identity_info.logon_id_high = 0;
-       pinfo.identity_info.account_name.string = lp_parm_string(-1, "torture", "username");
+       pinfo.identity_info.account_name.string = account_name;
        pinfo.identity_info.workstation.string = TEST_MACHINE_NAME;
 
-       plain_pass = lp_parm_string(-1, "torture", "password");
-
        E_deshash(plain_pass, pinfo.lmpassword.hash);
        E_md4hash(plain_pass, pinfo.ntpassword.hash);
 
@@ -1186,14 +1199,17 @@ static BOOL test_InteractiveLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
 
        printf("Testing netr_LogonSamLogonWithFlags (Interactive Logon)\n");
 
-       status = dcerpc_netr_LogonSamLogonWithFlags(p, mem_ctx, &r);
-       if (!NT_STATUS_IS_OK(status)) {
-               printf("netr_LogonSamLogonWithFlags - %s\n", nt_errstr(status));
+       status = dcerpc_netr_LogonSamLogonWithFlags(p, fn_ctx, &r);
+       if (!r.out.return_authenticator || !creds_client_check(creds, &r.out.return_authenticator->cred)) {
+               printf("Credential chaining failed\n");
+               talloc_free(fn_ctx);
                return False;
        }
 
-       if (!creds_client_check(creds, &r.out.return_authenticator->cred)) {
-               printf("Credential chaining failed\n");
+       talloc_free(fn_ctx);
+
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("[%s]\\[%s] netr_LogonSamLogonWithFlags - %s\n", account_name, account_domain, nt_errstr(status));
                return False;
        }
 
@@ -1206,14 +1222,21 @@ BOOL torture_rpc_samlogon(void)
 {
         NTSTATUS status;
         struct dcerpc_pipe *p;
-       struct dcerpc_binding b;
-       TALLOC_CTX *mem_ctx;
+       struct dcerpc_binding *b;
+       struct cli_credentials *credentials;
+       TALLOC_CTX *mem_ctx = talloc_init("torture_rpc_netlogon");
        BOOL ret = True;
-       void *join_ctx;
+       struct test_join *join_ctx;
+#if 0
+       struct test_join *user_ctx;
+       const char *user_password;
+#endif
+       char *test_machine_account;
        const char *machine_password;
        const char *binding = lp_parm_string(-1, "torture", "binding");
        int i;
-       
+       int ci;
+
        unsigned int credential_flags[] = {
                NETLOGON_NEG_AUTH2_FLAGS,
                NETLOGON_NEG_ARCFOUR,
@@ -1224,17 +1247,98 @@ BOOL torture_rpc_samlogon(void)
 
        struct creds_CredentialState *creds;
 
-       mem_ctx = talloc_init("torture_rpc_netlogon");
+       struct {
+               const char *domain;
+               const char *username;
+               const char *password;
+               BOOL network_login;
+       } usercreds[] = {
+               {
+                       cli_credentials_get_domain(cmdline_credentials),
+                       cli_credentials_get_username(cmdline_credentials),
+                       cli_credentials_get_password(cmdline_credentials),
+                       True
+               },
+               {
+                       cli_credentials_get_realm(cmdline_credentials),
+                       cli_credentials_get_username(cmdline_credentials),
+                       cli_credentials_get_password(cmdline_credentials),
+                       True
+               },
+               {
+                       NULL,
+                       talloc_asprintf(mem_ctx, 
+                                       "%s@%s", 
+                                       cli_credentials_get_username(cmdline_credentials),
+                                       cli_credentials_get_domain(cmdline_credentials)
+                               ),
+                       cli_credentials_get_password(cmdline_credentials),
+                       False
+               },
+               {
+                       NULL,
+                       talloc_asprintf(mem_ctx, 
+                                       "%s@%s", 
+                                       cli_credentials_get_username(cmdline_credentials),
+                                       cli_credentials_get_realm(cmdline_credentials)
+                               ),
+                       cli_credentials_get_password(cmdline_credentials),
+                       True
+               },
+#if 0
+               {       
+                       lp_parm_string(-1, "torture", "userdomain"),
+                       TEST_USER_NAME,
+                       NULL,
+                       True
+               },
+               {
+                       NULL,
+                       talloc_asprintf(mem_ctx, 
+                                       "%s@%s", 
+                                       TEST_USER_NAME,
+                                       lp_realm()),
+                       NULL,
+                       True
+               },
+               {
+                       NULL,
+                       talloc_asprintf(mem_ctx, 
+                                       "%s@%s", 
+                                       TEST_USER_NAME,
+                                       lp_parm_string(-1, "torture", "userdomain")),
+                       NULL,
+                       False
+               }
+#endif
+       };
+               
+       credentials = cli_credentials_init(mem_ctx);
 
+       test_machine_account = talloc_asprintf(mem_ctx, "%s$", TEST_MACHINE_NAME);
        /* We only need to join as a workstation here, and in future,
         * if we wish to test against trusted domains, we must be a
         * workstation here */
-       join_ctx = torture_join_domain(TEST_MACHINE_NAME, lp_workgroup(), ACB_WSTRUST, 
-                                      &machine_password);
+       join_ctx = torture_create_testuser(test_machine_account, lp_workgroup(), ACB_WSTRUST, 
+                                          &machine_password);
        if (!join_ctx) {
                printf("Failed to join as Workstation\n");
                return False;
        }
+#if 0
+       user_ctx = torture_create_testuser(TEST_USER_NAME,
+                                          lp_parm_string(-1, "torture", "userdomain"),
+                                          ACB_NORMAL, 
+                                          &user_password);
+       if (!user_ctx) {
+               printf("Failed to join as Workstation\n");
+               return False;
+       }
+
+       usercreds[3].password = user_password;
+       usercreds[4].password = user_password;
+       usercreds[5].password = user_password;
+#endif
 
        status = dcerpc_parse_binding(mem_ctx, binding, &b);
        if (!NT_STATUS_IS_OK(status)) {
@@ -1246,17 +1350,23 @@ BOOL torture_rpc_samlogon(void)
        /* We have to use schannel, otherwise the SamLogonEx fails
         * with INTERNAL_ERROR */
 
-       b.flags &= ~DCERPC_AUTH_OPTIONS;
-       b.flags |= DCERPC_SCHANNEL_WORKSTATION | DCERPC_SIGN | DCERPC_SCHANNEL_128;
+       b->flags &= ~DCERPC_AUTH_OPTIONS;
+       b->flags |= DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_128;
+
+       cli_credentials_set_workstation(credentials, TEST_MACHINE_NAME, CRED_SPECIFIED);
+       cli_credentials_set_domain(credentials, lp_workgroup(), CRED_SPECIFIED);
+       cli_credentials_set_username(credentials, test_machine_account, CRED_SPECIFIED);
+       cli_credentials_set_password(credentials, machine_password, CRED_SPECIFIED);
+       cli_credentials_set_secure_channel_type(credentials,
+                                               SEC_CHAN_WKSTA);
 
-       status = dcerpc_pipe_connect_b(&p, &b, 
+       status = dcerpc_pipe_connect_b(mem_ctx, &p, b, 
                                       DCERPC_NETLOGON_UUID,
                                       DCERPC_NETLOGON_VERSION,
-                                      lp_workgroup(), 
-                                      TEST_MACHINE_NAME,
-                                      machine_password);
+                                      credentials);
 
        if (!NT_STATUS_IS_OK(status)) {
+               printf("RPC pipe connect as domain member failed: %s\n", nt_errstr(status));
                ret = False;
                goto failed;
        }
@@ -1267,37 +1377,55 @@ BOOL torture_rpc_samlogon(void)
                goto failed;
        }
 
-       if (!test_InteractiveLogon(p, mem_ctx, creds)) {
-               ret = False;
-       }
-
-       if (!test_SamLogon(p, mem_ctx, creds)) {
-               ret = False;
-       }
-
-       for (i=0; i < ARRAY_SIZE(credential_flags); i++) {
+       for (ci = 0; ci < ARRAY_SIZE(usercreds); ci++) {
                
-               if (!test_SetupCredentials2(p, mem_ctx, credential_flags[i],
-                                           TEST_MACHINE_NAME, machine_password, 
-                                           SEC_CHAN_WKSTA, creds)) {
-                       return False;
+               if (!test_InteractiveLogon(p, mem_ctx, creds,
+                                          usercreds[ci].domain,
+                                          usercreds[ci].username,
+                                          usercreds[ci].password)) {
+                       ret = False;
                }
                
-               if (!test_InteractiveLogon(p, mem_ctx, creds)) {
-                       ret = False;
+               if (usercreds[ci].network_login) {
+                       if (!test_SamLogon(p, mem_ctx, creds, 
+                                          usercreds[ci].domain,
+                                          usercreds[ci].username,
+                                          usercreds[ci].password,
+                                          0)) {
+                               ret = False;
+                       }
                }
+       }
+
+       for (i=0; i < ARRAY_SIZE(credential_flags); i++) {
                
-               if (!test_SamLogon(p, mem_ctx, creds)) {
-                       ret = False;
+               for (ci = 0; ci < ARRAY_SIZE(usercreds); ci++) {
+                       
+                       if (!test_InteractiveLogon(p, mem_ctx, creds,
+                                                  usercreds[ci].domain,
+                                                  usercreds[ci].username,
+                                                  usercreds[ci].password)) {
+                               ret = False;
+                       }
+                       
+                       if (usercreds[ci].network_login) {
+                               if (!test_SamLogon(p, mem_ctx, creds, 
+                                                  usercreds[ci].domain,
+                                                  usercreds[ci].username,
+                                                  usercreds[ci].password,
+                                                  1)) {
+                                       ret = False;
+                               }
+                       }
                }
        }
 
 failed:
-       talloc_destroy(mem_ctx);
-
-       torture_rpc_close(p);
+       talloc_free(mem_ctx);
 
        torture_leave_domain(join_ctx);
-
+#if 0
+       torture_leave_domain(user_ctx);
+#endif
        return ret;
 }