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, 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, 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);
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];
}
-{ int n; for (n=0; n < 5; n++) {
- for (i=0; i < s->nprocs; i++) {
- struct netr_LogonSamLogon lg;
+ 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);
struct netlogon_creds_CredentialState *creds_state;
+ struct dcerpc_pipe *net_pipe;
struct netr_Authenticator credential, return_authenticator;
- 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;
- }
+ struct samr_Password new_password;
- 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");
+ status = dcerpc_pipe_connect_b(s, &net_pipe, s->b,
+ &ndr_table_netlogon,
+ s->wks_creds1,
+ torture->ev, torture->lp_ctx);
- ninfo.lm.data = lm_resp.data;
- ninfo.lm.length = lm_resp.length;
+ torture_assert_ntstatus_ok(torture, status,
+ "dcerpc_pipe_connect_b failed");
- ninfo.nt.data = nt_resp.data;
- ninfo.nt.length = nt_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.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);
+ E_md4hash(password, new_password.hash);
creds_state = cli_credentials_get_netlogon_creds(
- s->conns[i].wks_creds);
+ s->wks_creds1);
+ netlogon_creds_des_encrypt(creds_state, &new_password);
netlogon_creds_client_authenticator(creds_state, &credential);
- netlogon_creds_encrypt_samlogon_logon(creds_state,
- lg.in.logon_level,
- lg.in.logon);
+ 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");
- 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,
- &lg.out.return_authenticator->cred)) {
+ &pwset.out.return_authenticator->cred)) {
torture_comment(torture, "Credential chaining failed\n");
}
- torture_assert_ntstatus_ok(torture, lg.out.result,
- "LogonSamLogon failed");
+ 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);
}
- 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;
- creds_state = cli_credentials_get_netlogon_creds(
- s->conns[i].wks_creds);
- netlogon_creds_client_authenticator(creds_state, &credential);
+ 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, dcerpc_netr_LogonGetCapabilities_r(
- s->conns[i].pipe->binding_handle,
- torture, &cp),
- "LogonGetCapabilities failed");
- torture_assert_ntstatus_ok(torture, cp.out.result,
- "LogonGetCapabilities failed");
+ start = timeval_current();
+ end = timeval_add(&start, s->timelimit, 0);
- if (!netlogon_creds_client_check(creds_state,
- &cp.out.return_authenticator->cred)) {
- torture_comment(torture, "Credential chaining failed\n");
- }
+ 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);
+
+ for (i=0; i < s->nprocs; i++) {
+ s->total += s->conns[i].total;
+ }
+
+ 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;
}