[SCM] Samba Shared Repository - branch v4-0-test updated - release-4-0-0alpha3-1542-gfc3bc3c

Volker Lendecke vlendec at samba.org
Fri May 16 18:19:39 GMT 2008


The branch, v4-0-test has been updated
       via  fc3bc3c4a85b0e0ba853f3208a4e934a733cfdc4 (commit)
       via  f75f95931c15d57b3111db4dff589be06710aea7 (commit)
       via  901426c24c74390f7b1c78bb7a07c020b6ef73eb (commit)
      from  b3d024676426000380ad86a2a4b83e7b21478978 (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v4-0-test


- Log -----------------------------------------------------------------
commit fc3bc3c4a85b0e0ba853f3208a4e934a733cfdc4
Author: Volker Lendecke <vl at samba.org>
Date:   Fri May 16 15:51:27 2008 +0200

    Make rpc-bench-schannel1 use two wks accounts if --option=torture:multijoin=true

commit f75f95931c15d57b3111db4dff589be06710aea7
Author: Volker Lendecke <vl at samba.org>
Date:   Fri May 16 15:44:14 2008 +0200

    Fix two C++ warnings

commit 901426c24c74390f7b1c78bb7a07c020b6ef73eb
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue May 13 09:10:25 2008 +0200

    torture: add RPC-BENCH-SCHANNEL1 test
    
    This tests SamLogonEx() calls on multiple (smb) connections
    in parallel. Sadly the smb connect needs to be serialized
    because of the reset on zero VC style behavior of windows.
    
    Call it like this:
    bin/smbtorture -U administrator%test ncacn_np:w2k3-101 -W W2K3 RPC-BENCH-SCHANNEL
    or
    bin/smbtorture -U administrator%test ncacn_np:w2k3-101 -W W2K3 -k no RPC-BENCH-SCHANNEL \
    	--option="torture:nprocs=4" --option="torture:timelimit=1" \
    	--extra-user SUB1\\sub1user%testsecret --extra-user SUB1\\sub1user%testsecret
    or ...
    
    Later we should add more tests, maybe using only one smb connection
    and different netlogon pipes.
    
    We should also test using the DCERPC_PFC_FLAG_CONC_MPX flag and just one
    rpc connection.
    
    DCERPC_PFC_FLAG_CONC_MPX /* supports concurrent multiplexing of a single connection.*/
    
    metze

-----------------------------------------------------------------------

Summary of changes:
 source/torture/rpc/rpc.c      |    1 +
 source/torture/rpc/schannel.c |  285 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 286 insertions(+), 0 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source/torture/rpc/rpc.c b/source/torture/rpc/rpc.c
index fdb88b1..acc1220 100644
--- a/source/torture/rpc/rpc.c
+++ b/source/torture/rpc/rpc.c
@@ -399,6 +399,7 @@ NTSTATUS torture_rpc_init(void)
 	torture_suite_add_simple_test(suite, "SAMSYNC", torture_rpc_samsync);
 	torture_suite_add_simple_test(suite, "SCHANNEL", torture_rpc_schannel);
 	torture_suite_add_simple_test(suite, "SCHANNEL2", torture_rpc_schannel2);
+	torture_suite_add_simple_test(suite, "BENCH-SCHANNEL1", torture_rpc_schannel_bench1);
 	torture_suite_add_suite(suite, torture_rpc_srvsvc(suite));
 	torture_suite_add_suite(suite, torture_rpc_svcctl(suite));
 	torture_suite_add_suite(suite, torture_rpc_samr_accessmask(suite));
diff --git a/source/torture/rpc/schannel.c b/source/torture/rpc/schannel.c
index c89b71b..f0279f0 100644
--- a/source/torture/rpc/schannel.c
+++ b/source/torture/rpc/schannel.c
@@ -33,6 +33,8 @@
 #include "param/param.h"
 #include "librpc/rpc/dcerpc_proto.h"
 #include "auth/gensec/gensec.h"
+#include "libcli/composite/composite.h"
+#include "lib/events/events.h"
 
 #define TEST_MACHINE_NAME "schannel"
 
@@ -484,3 +486,286 @@ bool torture_rpc_schannel2(struct torture_context *torture)
 	return true;
 }
 
+struct torture_schannel_bench;
+
+struct torture_schannel_bench_conn {
+	struct torture_schannel_bench *s;
+	int index;
+	struct cli_credentials *wks_creds;
+	struct dcerpc_pipe *pipe;
+	struct netr_LogonSamLogonEx r;
+	struct netr_NetworkInfo ninfo;
+	TALLOC_CTX *tmp;
+	uint64_t total;
+	uint32_t count;
+};
+
+struct torture_schannel_bench {
+	struct torture_context *tctx;
+	bool progress;
+	int timelimit;
+	int nprocs;
+	int nconns;
+	struct torture_schannel_bench_conn *conns;
+	struct test_join *join_ctx1;
+	struct cli_credentials *wks_creds1;
+	struct test_join *join_ctx2;
+	struct cli_credentials *wks_creds2;
+	struct cli_credentials *user1_creds;
+	struct cli_credentials *user2_creds;
+	struct dcerpc_binding *b;
+	NTSTATUS error;
+	uint64_t total;
+	uint32_t count;
+	bool stopped;
+};
+
+static void torture_schannel_bench_connected(struct composite_context *c)
+{
+	struct torture_schannel_bench_conn *conn =
+		(struct torture_schannel_bench_conn *)c->async.private_data;
+	struct torture_schannel_bench *s = talloc_get_type(conn->s,
+					   struct torture_schannel_bench);
+
+	s->error = dcerpc_pipe_connect_b_recv(c, s->conns, &conn->pipe);
+	torture_comment(s->tctx, "conn[%u]: %s\n", conn->index, nt_errstr(s->error));
+	if (NT_STATUS_IS_OK(s->error)) {
+		s->nconns++;
+	}
+}
+
+static void torture_schannel_bench_recv(struct rpc_request *req);
+
+static bool torture_schannel_bench_start(struct torture_schannel_bench_conn *conn)
+{
+	struct torture_schannel_bench *s = conn->s;
+	NTSTATUS status;
+	DATA_BLOB names_blob, chal, lm_resp, nt_resp;
+	int flags = CLI_CRED_NTLM_AUTH;
+	struct rpc_request *req;
+	struct cli_credentials *user_creds;
+
+	if (conn->total % 2) {
+		user_creds = s->user1_creds;
+	} else {
+		user_creds = s->user2_creds;
+	}
+
+	if (lp_client_lanman_auth(s->tctx->lp_ctx)) {
+		flags |= CLI_CRED_LANMAN_AUTH;
+	}
+
+	if (lp_client_ntlmv2_auth(s->tctx->lp_ctx)) {
+		flags |= CLI_CRED_NTLMv2_AUTH;
+	}
+
+	talloc_free(conn->tmp);
+	conn->tmp = talloc_new(s);
+	ZERO_STRUCT(conn->ninfo);
+	ZERO_STRUCT(conn->r);
+
+	cli_credentials_get_ntlm_username_domain(user_creds, conn->tmp,
+						 &conn->ninfo.identity_info.account_name.string,
+						 &conn->ninfo.identity_info.domain_name.string);
+
+	generate_random_buffer(conn->ninfo.challenge,
+			       sizeof(conn->ninfo.challenge));
+	chal = data_blob_const(conn->ninfo.challenge,
+			       sizeof(conn->ninfo.challenge));
+
+	names_blob = NTLMv2_generate_names_blob(conn->tmp, lp_iconv_convenience(s->tctx->lp_ctx),
+						cli_credentials_get_workstation(conn->wks_creds),
+						cli_credentials_get_domain(conn->wks_creds));
+
+	status = cli_credentials_get_ntlm_response(user_creds, conn->tmp,
+						   &flags,
+						   chal,
+						   names_blob,
+						   &lm_resp, &nt_resp,
+						   NULL, NULL);
+	torture_assert_ntstatus_ok(s->tctx, status,
+				   "cli_credentials_get_ntlm_response failed");
+
+	conn->ninfo.lm.data = lm_resp.data;
+	conn->ninfo.lm.length = lm_resp.length;
+
+	conn->ninfo.nt.data = nt_resp.data;
+	conn->ninfo.nt.length = nt_resp.length;
+
+	conn->ninfo.identity_info.parameter_control = 0;
+	conn->ninfo.identity_info.logon_id_low = 0;
+	conn->ninfo.identity_info.logon_id_high = 0;
+	conn->ninfo.identity_info.workstation.string = cli_credentials_get_workstation(conn->wks_creds);
+
+	conn->r.in.server_name = talloc_asprintf(conn->tmp, "\\\\%s", dcerpc_server_name(conn->pipe));
+	conn->r.in.computer_name = cli_credentials_get_workstation(conn->wks_creds);
+	conn->r.in.logon_level = 2;
+	conn->r.in.logon.network = &conn->ninfo;
+	conn->r.in.flags = 0;
+	conn->r.in.validation_level = 2;
+
+	req = dcerpc_netr_LogonSamLogonEx_send(conn->pipe, conn->tmp, &conn->r);
+	torture_assert(s->tctx, req, "Failed to setup LogonSamLogonEx request");
+
+	req->async.callback = torture_schannel_bench_recv;
+	req->async.private_data = conn;
+
+	return true;
+}
+
+static void torture_schannel_bench_recv(struct rpc_request *req)
+{
+	bool ret;
+	struct torture_schannel_bench_conn *conn =
+		(struct torture_schannel_bench_conn *)req->async.private_data;
+	struct torture_schannel_bench *s = talloc_get_type(conn->s,
+					   struct torture_schannel_bench);
+
+	s->error = dcerpc_ndr_request_recv(req);
+	if (!NT_STATUS_IS_OK(s->error)) {
+		return;
+	}
+
+	conn->total++;
+	conn->count++;
+
+	if (s->stopped) {
+		return;
+	}
+
+	ret = torture_schannel_bench_start(conn);
+	if (!ret) {
+		s->error = NT_STATUS_INTERNAL_ERROR;
+	}
+}
+
+/*
+  test multiple schannel connection in parallel
+ */
+bool torture_rpc_schannel_bench1(struct torture_context *torture)
+{
+	bool ret = true;
+	NTSTATUS status;
+	const char *binding = torture_setting_string(torture, "binding", NULL);
+	struct torture_schannel_bench *s;
+	struct timeval start;
+	struct timeval end;
+	int i;
+	const char *tmp;
+
+	s = talloc_zero(torture, struct torture_schannel_bench);
+	s->tctx = torture;
+	s->progress = torture_setting_bool(torture, "progress", true);
+	s->timelimit = torture_setting_int(torture, "timelimit", 10);
+	s->nprocs = torture_setting_int(torture, "nprocs", 4);
+	s->conns = talloc_zero_array(s, struct torture_schannel_bench_conn, s->nprocs);
+
+	s->user1_creds = (struct cli_credentials *)talloc_memdup(s,
+								 cmdline_credentials,
+								 sizeof(*s->user1_creds));
+	tmp = torture_setting_string(s->tctx, "extra_user1", NULL);
+	if (tmp) {
+		cli_credentials_parse_string(s->user1_creds, tmp, CRED_SPECIFIED);
+	}
+	s->user2_creds = (struct cli_credentials *)talloc_memdup(s,
+								 cmdline_credentials,
+								 sizeof(*s->user1_creds));
+	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++) {
+		s->conns[i].s = s;
+		s->conns[i].index = i;
+		s->conns[i].wks_creds = (struct cli_credentials *)talloc_memdup(
+			s->conns, s->wks_creds1,sizeof(*s->wks_creds1));
+		if ((i % 2) && (torture_setting_bool(torture, "multijoin", false))) {
+			memcpy(s->conns[i].wks_creds, s->wks_creds2,
+			       talloc_get_size(s->conns[i].wks_creds));
+		}
+		s->conns[i].wks_creds->netlogon_creds = NULL;
+	}
+
+	status = dcerpc_parse_binding(s, binding, &s->b);
+	torture_assert_ntstatus_ok(torture, status, "Bad binding string");
+	s->b->flags &= ~DCERPC_AUTH_OPTIONS;
+	s->b->flags |= DCERPC_SCHANNEL | DCERPC_SIGN;
+
+	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 = event_loop_once(torture->ev);
+		torture_assert(torture, ev_ret == 0, "event_loop_once failed");
+#endif
+	}
+	torture_assert_ntstatus_ok(torture, s->error, "Failed establish a connect");
+
+	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");
+	}
+
+	start = timeval_current();
+	end = timeval_add(&start, s->timelimit, 0);
+
+	while (NT_STATUS_IS_OK(s->error) && !timeval_expired(&end)) {
+		int ev_ret = event_loop_once(torture->ev);
+		torture_assert(torture, ev_ret == 0, "event_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(s->join_ctx1);
+	torture_leave_domain(s->join_ctx2);
+	return true;
+}


-- 
Samba Shared Repository


More information about the samba-cvs mailing list