TODO own torture test -- source4/torture/rpc/schannel.c schannel per computer name
authorStefan Metzmacher <metze@samba.org>
Wed, 17 Jul 2013 14:04:49 +0000 (16:04 +0200)
committerStefan Metzmacher <metze@samba.org>
Tue, 10 Apr 2018 07:35:15 +0000 (09:35 +0200)
source4/torture/rpc/schannel.c

index de3a36eaa4f1ca52074f37578eb060e539fe74b6..667d2091816d97e506d651c11c3ac2ae948027cb 100644 (file)
@@ -945,42 +945,28 @@ bool torture_rpc_schannel_bench1(struct torture_context *torture)
        s->nprocs = torture_setting_int(torture, "nprocs", 4);
        s->conns = talloc_zero_array(s, struct torture_schannel_bench_conn, s->nprocs);
 
-       s->user1_creds = cli_credentials_shallow_copy(s,
-                               popt_get_cmdline_credentials());
-       tmp = torture_setting_string(s->tctx, "extra_user1", NULL);
-       if (tmp) {
-               cli_credentials_parse_string(s->user1_creds, tmp, CRED_SPECIFIED);
-       }
-       s->user2_creds = cli_credentials_shallow_copy(s,
-                               popt_get_cmdline_credentials());
-       tmp = torture_setting_string(s->tctx, "extra_user2", NULL);
-       if (tmp) {
-               cli_credentials_parse_string(s->user1_creds, tmp, CRED_SPECIFIED);
-       }
-
        s->join_ctx1 = torture_join_domain(s->tctx, talloc_asprintf(s, "%sb", TEST_MACHINE_NAME),
                                           ACB_WSTRUST, &s->wks_creds1);
        torture_assert(torture, s->join_ctx1 != NULL,
                       "Failed to join domain with acct_flags=ACB_WSTRUST");
-       s->join_ctx2 = torture_join_domain(s->tctx, talloc_asprintf(s, "%sc", TEST_MACHINE_NAME),
-                                          ACB_WSTRUST, &s->wks_creds2);
-       torture_assert(torture, s->join_ctx2 != NULL,
-                      "Failed to join domain with acct_flags=ACB_WSTRUST");
 
        cli_credentials_set_kerberos_state(s->wks_creds1, CRED_DONT_USE_KERBEROS);
-       cli_credentials_set_kerberos_state(s->wks_creds2, CRED_DONT_USE_KERBEROS);
 
        for (i=0; i < s->nprocs; i++) {
                struct cli_credentials *wks = s->wks_creds1;
 
-               if ((i % 2) && (torture_setting_bool(torture, "multijoin", false))) {
-                       wks = s->wks_creds2;
-               }
-
                s->conns[i].s = s;
                s->conns[i].index = i;
                s->conns[i].wks_creds = cli_credentials_shallow_copy(s->conns, wks);
                cli_credentials_set_netlogon_creds(s->conns[i].wks_creds, NULL);
+#if 1
+               cli_credentials_set_workstation(s->conns[i].wks_creds,
+                                               talloc_asprintf(s->conns[i].wks_creds,
+                                                       "%s_%u",
+                                                       cli_credentials_get_workstation(s->wks_creds1),
+                                                       i),
+                                               CRED_SPECIFIED);
+#endif
        }
 
        status = dcerpc_parse_binding(s, binding, &s->b);
@@ -992,136 +978,150 @@ bool torture_rpc_schannel_bench1(struct torture_context *torture)
 
        torture_comment(torture, "Opening %d connections in parallel\n", s->nprocs);
        for (i=0; i < s->nprocs; i++) {
-#if 1
                s->error = dcerpc_pipe_connect_b(s->conns, &s->conns[i].pipe, s->b,
                                                 &ndr_table_netlogon,
                                                 s->conns[i].wks_creds,
                                                 torture->ev, torture->lp_ctx);
                torture_assert_ntstatus_ok(torture, s->error, "Failed to connect with schannel");
-#else
-               /*
-                * This path doesn't work against windows,
-                * because of windows drops the connections
-                * which haven't reached a session setup yet
-                *
-                * The same as the reset on zero vc stuff.
-                */
-               struct composite_context *c;
-               c = dcerpc_pipe_connect_b_send(s->conns, s->b,
-                                              &ndr_table_netlogon,
-                                              s->conns[i].wks_creds,
-                                              torture->ev,
-                                              torture->lp_ctx);
-               torture_assert(torture, c != NULL, "Failed to setup connect");
-               c->async.fn = torture_schannel_bench_connected;
-               c->async.private_data = &s->conns[i];
-       }
-
-       while (NT_STATUS_IS_OK(s->error) && s->nprocs != s->nconns) {
-               int ev_ret = tevent_loop_once(torture->ev);
-               torture_assert(torture, ev_ret == 0, "tevent_loop_once failed");
-#endif
        }
-       torture_assert_ntstatus_ok(torture, s->error, "Failed establish a connect");
 
-       /*
-        * Change the workstation password after establishing the netlogon
-        * schannel connections to prove that existing connections are not
-        * affected by a wks pwchange.
-        */
-
-       {
-               struct netr_ServerPasswordSet pwset;
-               char *password = generate_random_password(s->join_ctx1, 8, 255);
+{ int n; for (n=0; n < 5; n++) {
+       for (i=0; i < s->nprocs; i++) {
+               struct netr_LogonSamLogon lg;
                struct netlogon_creds_CredentialState *creds_state;
-               struct dcerpc_pipe *net_pipe;
                struct netr_Authenticator credential, return_authenticator;
-               struct samr_Password new_password;
+               union netr_LogonLevel logon;
+               struct netr_PasswordInfo password;
+               struct netr_NetworkInfo ninfo;
+               union netr_Validation validation;
+               uint8_t authoritative;
+               DATA_BLOB chal;
+               DATA_BLOB names_blob;
+               DATA_BLOB lm_resp, nt_resp;
+               int flags = CLI_CRED_NTLM_AUTH;
+
+               if (lpcfg_client_lanman_auth(s->tctx->lp_ctx)) {
+                       flags |= CLI_CRED_LANMAN_AUTH;
+               }
 
-               status = dcerpc_pipe_connect_b(s, &net_pipe, s->b,
-                                              &ndr_table_netlogon,
-                                              s->wks_creds1,
-                                              torture->ev, torture->lp_ctx);
+               if (1 || lpcfg_client_ntlmv2_auth(s->tctx->lp_ctx)) {
+                       flags |= CLI_CRED_NTLMv2_AUTH;
+               }
+
+               ZERO_STRUCT(lg);
+               lg.in.server_name = talloc_asprintf(
+                       torture, "\\\\%s", dcerpc_server_name(s->conns[i].pipe));
+               lg.in.computer_name =
+                       cli_credentials_get_workstation(s->conns[i].wks_creds);
+               lg.in.credential = &credential;
+               lg.in.logon_level = 2;
+               lg.in.logon = &logon;
+               lg.in.validation_level = 2;
+               lg.in.return_authenticator = &return_authenticator;
+               lg.out.return_authenticator = &return_authenticator;
+               lg.out.validation = &validation;
+               lg.out.authoritative = &authoritative;
+
+               logon.password = &password;
+               logon.network = &ninfo;
+
+               ZERO_STRUCT(password);
+               password.identity_info.account_name.string = cli_credentials_get_username(s->conns[i].wks_creds);
+               password.identity_info.domain_name.string = cli_credentials_get_domain(s->conns[i].wks_creds);
+               password.identity_info.workstation.string = cli_credentials_get_workstation(s->conns[i].wks_creds);
+               password.identity_info.parameter_control = MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
+               password.ntpassword = *cli_credentials_get_nt_hash(s->conns[i].wks_creds, s);
+
+               ZERO_STRUCT(ninfo);
+
+               ninfo.identity_info.parameter_control = MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
+               cli_credentials_get_ntlm_username_domain(cmdline_credentials, s,
+                                                &ninfo.identity_info.account_name.string,
+                                                &ninfo.identity_info.domain_name.string);
+
+               generate_random_buffer(ninfo.challenge,
+                              sizeof(ninfo.challenge));
+               chal = data_blob_const(ninfo.challenge,
+                              sizeof(ninfo.challenge));
+
+               names_blob = NTLMv2_generate_names_blob(s,
+                                                       cli_credentials_get_workstation(s->conns[i].wks_creds),
+                                                       cli_credentials_get_domain(s->conns[i].wks_creds));
+
+               status = cli_credentials_get_ntlm_response(cmdline_credentials, s,
+                                                  &flags,
+                                                  chal,
+                                                  names_blob,
+                                                  &lm_resp, &nt_resp,
+                                                  NULL, NULL);
+               torture_assert_ntstatus_ok(s->tctx, status,
+                                          "cli_credentials_get_ntlm_response failed");
 
-               torture_assert_ntstatus_ok(torture, status,
-                                          "dcerpc_pipe_connect_b failed");
+               ninfo.lm.data = lm_resp.data;
+               ninfo.lm.length = lm_resp.length;
 
-               pwset.in.server_name = talloc_asprintf(
-                       net_pipe, "\\\\%s", dcerpc_server_name(net_pipe));
-               pwset.in.computer_name =
-                       cli_credentials_get_workstation(s->wks_creds1);
-               pwset.in.account_name = talloc_asprintf(
-                       net_pipe, "%s$", pwset.in.computer_name);
-               pwset.in.secure_channel_type = SEC_CHAN_WKSTA;
-               pwset.in.credential = &credential;
-               pwset.in.new_password = &new_password;
-               pwset.out.return_authenticator = &return_authenticator;
+               ninfo.nt.data = nt_resp.data;
+               ninfo.nt.length = nt_resp.length;
 
-               E_md4hash(password, new_password.hash);
+               ninfo.identity_info.parameter_control = 0;
+               ninfo.identity_info.logon_id_low = 0;
+               ninfo.identity_info.logon_id_high = 0;
+               ninfo.identity_info.workstation.string = cli_credentials_get_workstation(s->conns[i].wks_creds);
 
                creds_state = cli_credentials_get_netlogon_creds(
-                       s->wks_creds1);
-               netlogon_creds_des_encrypt(creds_state, &new_password);
+                       s->conns[i].wks_creds);
                netlogon_creds_client_authenticator(creds_state, &credential);
 
-               torture_assert_ntstatus_ok(torture, dcerpc_netr_ServerPasswordSet_r(net_pipe->binding_handle, torture, &pwset),
-                       "ServerPasswordSet failed");
-               torture_assert_ntstatus_ok(torture, pwset.out.result,
-                                          "ServerPasswordSet failed");
+               netlogon_creds_encrypt_samlogon_logon(creds_state,
+                                       lg.in.logon_level,
+                                       lg.in.logon);
 
+               torture_assert_ntstatus_ok(torture, dcerpc_netr_LogonSamLogon_r(
+                                       s->conns[i].pipe->binding_handle,
+                                       torture, &lg),
+                                       "LogonSamLogon failed");
                if (!netlogon_creds_client_check(creds_state,
-                                       &pwset.out.return_authenticator->cred)) {
+                                       &lg.out.return_authenticator->cred)) {
                        torture_comment(torture, "Credential chaining failed\n");
                }
 
-               cli_credentials_set_password(s->wks_creds1, password,
-                                            CRED_SPECIFIED);
-
-               talloc_free(net_pipe);
-
-               /* Just as a test, connect with the new creds */
-
-               cli_credentials_set_netlogon_creds(s->wks_creds1, NULL);
-
-               status = dcerpc_pipe_connect_b(s, &net_pipe, s->b,
-                                              &ndr_table_netlogon,
-                                              s->wks_creds1,
-                                              torture->ev, torture->lp_ctx);
-
-               torture_assert_ntstatus_ok(torture, status,
-                                          "dcerpc_pipe_connect_b failed");
-
-               talloc_free(net_pipe);
-       }
-
-       torture_comment(torture, "Start looping LogonSamLogonEx on %d connections for %d secs\n",
-                       s->nprocs, s->timelimit);
-       for (i=0; i < s->nprocs; i++) {
-               ret = torture_schannel_bench_start(&s->conns[i]);
-               torture_assert(torture, ret, "Failed to setup LogonSamLogonEx");
+               torture_assert_ntstatus_ok(torture, lg.out.result,
+                                          "LogonSamLogon failed");
        }
+       for (i=0; 0 && i < s->nprocs; i++) {
+               struct netr_LogonGetCapabilities cp;
+               struct netlogon_creds_CredentialState *creds_state;
+               struct netr_Authenticator credential, return_authenticator;
+               union netr_Capabilities capabilities;
+
+               ZERO_STRUCT(cp);
+               cp.in.server_name = talloc_asprintf(
+                       torture, "\\\\%s", dcerpc_server_name(s->conns[i].pipe));
+               cp.in.computer_name =
+                       cli_credentials_get_workstation(s->conns[i].wks_creds);
+               cp.in.credential = &credential;
+               cp.in.query_level = 1;
+               cp.in.return_authenticator = &return_authenticator;
+               cp.out.return_authenticator = &return_authenticator;
+               cp.out.capabilities = &capabilities;
 
-       start = timeval_current();
-       end = timeval_add(&start, s->timelimit, 0);
+               creds_state = cli_credentials_get_netlogon_creds(
+                       s->conns[i].wks_creds);
+               netlogon_creds_client_authenticator(creds_state, &credential);
 
-       while (NT_STATUS_IS_OK(s->error) && !timeval_expired(&end)) {
-               int ev_ret = tevent_loop_once(torture->ev);
-               torture_assert(torture, ev_ret == 0, "tevent_loop_once failed");
-       }
-       torture_assert_ntstatus_ok(torture, s->error, "Failed some request");
-       s->stopped = true;
-       talloc_free(s->conns);
+               torture_assert_ntstatus_ok(torture, dcerpc_netr_LogonGetCapabilities_r(
+                                       s->conns[i].pipe->binding_handle,
+                                       torture, &cp),
+                                       "LogonGetCapabilities failed");
+               torture_assert_ntstatus_ok(torture, cp.out.result,
+                                          "LogonGetCapabilities failed");
 
-       for (i=0; i < s->nprocs; i++) {
-               s->total += s->conns[i].total;
+               if (!netlogon_creds_client_check(creds_state,
+                                       &cp.out.return_authenticator->cred)) {
+                       torture_comment(torture, "Credential chaining failed\n");
+               }
        }
-
-       torture_comment(torture,
-                       "Total ops[%llu] (%u ops/s)\n",
-                       (unsigned long long)s->total,
-                       (unsigned)s->total/s->timelimit);
-
+}}
        torture_leave_domain(torture, s->join_ctx1);
-       torture_leave_domain(torture, s->join_ctx2);
        return true;
 }