summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/torture/rpc/handles.c244
-rw-r--r--source4/torture/rpc/rpc.c4
2 files changed, 247 insertions, 1 deletions
diff --git a/source4/torture/rpc/handles.c b/source4/torture/rpc/handles.c
index 113eed0a0f..2dd9350dd7 100644
--- a/source4/torture/rpc/handles.c
+++ b/source4/torture/rpc/handles.c
@@ -44,6 +44,8 @@ static bool test_handles_lsa(struct torture_context *torture)
uint16_t system_name = '\\';
TALLOC_CTX *mem_ctx = talloc_new(torture);
+ torture_comment(torture, "RPC-HANDLE-LSARPC\n");
+
status = torture_rpc_connection(mem_ctx, &p1, &dcerpc_table_lsarpc);
torture_assert_ntstatus_ok(torture, status, "opening lsa pipe1");
@@ -97,6 +99,243 @@ static bool test_handles_lsa(struct torture_context *torture)
return true;
}
+static bool test_handles_lsa_shared(struct torture_context *torture)
+{
+ NTSTATUS status;
+ struct dcerpc_pipe *p1, *p2, *p3, *p4, *p5;
+ struct policy_handle handle;
+ struct policy_handle handle2;
+ struct lsa_ObjectAttribute attr;
+ struct lsa_QosInfo qos;
+ struct lsa_OpenPolicy r;
+ struct lsa_Close c;
+ struct lsa_QuerySecurity qsec;
+ uint16_t system_name = '\\';
+ TALLOC_CTX *mem_ctx = talloc_new(torture);
+ enum dcerpc_transport_t transport;
+ uint32_t assoc_group_id;
+
+ torture_comment(torture, "RPC-HANDLE-LSARPC-SHARED\n");
+
+ if (lp_parm_bool(-1, "torture", "samba4", False)) {
+ torture_comment(torture, "LSA shared-policy-handle test against Samba4 - skipping\n");
+ return true;
+ }
+
+ torture_comment(torture, "connect lsa pipe1\n");
+ status = torture_rpc_connection(mem_ctx, &p1, &dcerpc_table_lsarpc);
+ torture_assert_ntstatus_ok(torture, status, "opening lsa pipe1");
+
+ transport = p1->conn->transport.transport,
+ assoc_group_id = p1->assoc_group_id;
+
+ torture_comment(torture, "use assoc_group_id[0x%08X] for new connections\n", assoc_group_id);
+
+ torture_comment(torture, "connect lsa pipe2\n");
+ status = torture_rpc_connection_transport(mem_ctx, &p2, &dcerpc_table_lsarpc,
+ transport,
+ assoc_group_id);
+ torture_assert_ntstatus_ok(torture, status, "opening lsa pipe2");
+
+ qos.len = 0;
+ qos.impersonation_level = 2;
+ qos.context_mode = 1;
+ qos.effective_only = 0;
+
+ attr.len = 0;
+ attr.root_dir = NULL;
+ attr.object_name = NULL;
+ attr.attributes = 0;
+ attr.sec_desc = NULL;
+ attr.sec_qos = &qos;
+
+ r.in.system_name = &system_name;
+ r.in.attr = &attr;
+ r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+ r.out.handle = &handle;
+
+ torture_comment(torture, "open lsa policy handle\n");
+ status = dcerpc_lsa_OpenPolicy(p1, mem_ctx, &r);
+ if (!NT_STATUS_IS_OK(status)) {
+ torture_comment(torture, "lsa_OpenPolicy not supported - skipping\n");
+ talloc_free(mem_ctx);
+ return true;
+ }
+
+ /*
+ * connect p3 after the policy handle is opened
+ */
+ torture_comment(torture, "connect lsa pipe3 after the policy handle is opened\n");
+ status = torture_rpc_connection_transport(mem_ctx, &p3, &dcerpc_table_lsarpc,
+ transport,
+ assoc_group_id);
+ torture_assert_ntstatus_ok(torture, status, "opening lsa pipe3");
+
+ qsec.in.handle = &handle;
+ qsec.in.sec_info = 0;
+ c.in.handle = &handle;
+ c.out.handle = &handle2;
+
+ /*
+ * use policy handle on all 3 connections
+ */
+ torture_comment(torture, "use the policy handle on p1,p2,p3\n");
+ status = dcerpc_lsa_QuerySecurity(p1, mem_ctx, &qsec);
+ torture_assert_ntstatus_equal(torture, status, NT_STATUS_OK,
+ "use policy handle on p1");
+
+ status = dcerpc_lsa_QuerySecurity(p2, mem_ctx, &qsec);
+ torture_assert_ntstatus_equal(torture, status, NT_STATUS_OK,
+ "use policy handle on p2");
+
+ status = dcerpc_lsa_QuerySecurity(p3, mem_ctx, &qsec);
+ torture_assert_ntstatus_equal(torture, status, NT_STATUS_OK,
+ "use policy handle on p3");
+
+ /*
+ * close policy handle on connection 2 and the others get a fault
+ */
+ torture_comment(torture, "close the policy handle on p2 others get a fault\n");
+ status = dcerpc_lsa_Close(p2, mem_ctx, &c);
+ torture_assert_ntstatus_equal(torture, status, NT_STATUS_OK,
+ "closing policy handle on p2");
+
+ status = dcerpc_lsa_Close(p1, mem_ctx, &c);
+ torture_assert_ntstatus_equal(torture, status, NT_STATUS_NET_WRITE_FAULT,
+ "closing policy handle on p1 again");
+ torture_assert_int_equal(torture, p1->last_fault_code, DCERPC_FAULT_CONTEXT_MISMATCH,
+ "closing policy handle on p1 again");
+
+ status = dcerpc_lsa_Close(p3, mem_ctx, &c);
+ torture_assert_ntstatus_equal(torture, status, NT_STATUS_NET_WRITE_FAULT,
+ "closing policy handle on p3");
+ torture_assert_int_equal(torture, p1->last_fault_code, DCERPC_FAULT_CONTEXT_MISMATCH,
+ "closing policy handle on p3");
+
+ status = dcerpc_lsa_Close(p2, mem_ctx, &c);
+ torture_assert_ntstatus_equal(torture, status, NT_STATUS_NET_WRITE_FAULT,
+ "closing policy handle on p2 again");
+ torture_assert_int_equal(torture, p1->last_fault_code, DCERPC_FAULT_CONTEXT_MISMATCH,
+ "closing policy handle on p2 again");
+
+ /*
+ * open a new policy handle on p3
+ */
+ torture_comment(torture, "open a new policy handle on p3\n");
+ status = dcerpc_lsa_OpenPolicy(p3, mem_ctx, &r);
+ torture_assert_ntstatus_equal(torture, status, NT_STATUS_OK,
+ "open policy handle on p3");
+
+ /*
+ * use policy handle on all 3 connections
+ */
+ torture_comment(torture, "use the policy handle on p1,p2,p3\n");
+ status = dcerpc_lsa_QuerySecurity(p1, mem_ctx, &qsec);
+ torture_assert_ntstatus_equal(torture, status, NT_STATUS_OK,
+ "use policy handle on p1");
+
+ status = dcerpc_lsa_QuerySecurity(p2, mem_ctx, &qsec);
+ torture_assert_ntstatus_equal(torture, status, NT_STATUS_OK,
+ "use policy handle on p2");
+
+ status = dcerpc_lsa_QuerySecurity(p3, mem_ctx, &qsec);
+ torture_assert_ntstatus_equal(torture, status, NT_STATUS_OK,
+ "use policy handle on p3");
+
+ /*
+ * close policy handle on connection 2 and the others get a fault
+ */
+ torture_comment(torture, "close the policy handle on p2 others get a fault\n");
+ status = dcerpc_lsa_Close(p2, mem_ctx, &c);
+ torture_assert_ntstatus_equal(torture, status, NT_STATUS_OK,
+ "closing policy handle on p2");
+
+ status = dcerpc_lsa_Close(p1, mem_ctx, &c);
+ torture_assert_ntstatus_equal(torture, status, NT_STATUS_NET_WRITE_FAULT,
+ "closing policy handle on p1 again");
+ torture_assert_int_equal(torture, p1->last_fault_code, DCERPC_FAULT_CONTEXT_MISMATCH,
+ "closing policy handle on p1 again");
+
+ status = dcerpc_lsa_Close(p3, mem_ctx, &c);
+ torture_assert_ntstatus_equal(torture, status, NT_STATUS_NET_WRITE_FAULT,
+ "closing policy handle on p3");
+ torture_assert_int_equal(torture, p1->last_fault_code, DCERPC_FAULT_CONTEXT_MISMATCH,
+ "closing policy handle on p3");
+
+ status = dcerpc_lsa_Close(p2, mem_ctx, &c);
+ torture_assert_ntstatus_equal(torture, status, NT_STATUS_NET_WRITE_FAULT,
+ "closing policy handle on p2 again");
+ torture_assert_int_equal(torture, p1->last_fault_code, DCERPC_FAULT_CONTEXT_MISMATCH,
+ "closing policy handle on p2 again");
+
+ /*
+ * open a new policy handle
+ */
+ torture_comment(torture, "open a new policy handle on p1 and use it\n");
+ status = dcerpc_lsa_OpenPolicy(p1, mem_ctx, &r);
+ torture_assert_ntstatus_equal(torture, status, NT_STATUS_OK,
+ "open 2nd policy handle on p1");
+
+ status = dcerpc_lsa_QuerySecurity(p1, mem_ctx, &qsec);
+ torture_assert_ntstatus_equal(torture, status, NT_STATUS_OK,
+ "QuerySecurity handle on p1");
+
+ /* close first connection */
+ torture_comment(torture, "disconnect p1\n");
+ talloc_free(p1);
+ msleep(5);
+
+ /*
+ * and it's still available on p2,p3
+ */
+ torture_comment(torture, "use policy handle on p2,p3\n");
+ status = dcerpc_lsa_QuerySecurity(p2, mem_ctx, &qsec);
+ torture_assert_ntstatus_equal(torture, status, NT_STATUS_OK,
+ "QuerySecurity handle on p2 after p1 was disconnected");
+
+ status = dcerpc_lsa_QuerySecurity(p3, mem_ctx, &qsec);
+ torture_assert_ntstatus_equal(torture, status, NT_STATUS_OK,
+ "QuerySecurity handle on p3 after p1 was disconnected");
+
+ /*
+ * now open p4
+ * and use the handle on it
+ */
+ torture_comment(torture, "connect lsa pipe4 and use policy handle\n");
+ status = torture_rpc_connection_transport(mem_ctx, &p4, &dcerpc_table_lsarpc,
+ transport,
+ assoc_group_id);
+ torture_assert_ntstatus_ok(torture, status, "opening lsa pipe4");
+
+ status = dcerpc_lsa_QuerySecurity(p4, mem_ctx, &qsec);
+ torture_assert_ntstatus_equal(torture, status, NT_STATUS_OK,
+ "using policy handle on p4");
+
+ /*
+ * now close p2,p3,p4
+ * without closing the policy handle
+ */
+ torture_comment(torture, "disconnect p2,p3,p4\n");
+ talloc_free(p2);
+ talloc_free(p3);
+ talloc_free(p4);
+ msleep(10);
+
+ /*
+ * now open p5
+ */
+ torture_comment(torture, "connect lsa pipe5 - should fail\n");
+ status = torture_rpc_connection_transport(mem_ctx, &p5, &dcerpc_table_lsarpc,
+ transport,
+ assoc_group_id);
+ torture_assert_ntstatus_equal(torture, status, NT_STATUS_UNSUCCESSFUL,
+ "opening lsa pipe5");
+
+ talloc_free(mem_ctx);
+
+ return true;
+}
+
static bool test_handles_samr(struct torture_context *torture)
{
@@ -108,6 +347,8 @@ static bool test_handles_samr(struct torture_context *torture)
struct samr_Close c;
TALLOC_CTX *mem_ctx = talloc_new(torture);
+ torture_comment(torture, "RPC-HANDLE-SAMR\n");
+
status = torture_rpc_connection(mem_ctx, &p1, &dcerpc_table_samr);
torture_assert_ntstatus_ok(torture, status, "opening samr pipe1");
@@ -156,6 +397,8 @@ static bool test_handles_drsuapi(struct torture_context *torture)
struct drsuapi_DsUnbind c;
TALLOC_CTX *mem_ctx = talloc_new(torture);
+ torture_comment(torture, "RPC-HANDLE-DRSUAPI\n");
+
status = torture_rpc_connection(mem_ctx, &p1, &dcerpc_table_drsuapi);
torture_assert_ntstatus_ok(torture, status, "opening drsuapi pipe1");
@@ -205,6 +448,7 @@ struct torture_suite *torture_rpc_handles(void)
suite = torture_suite_create(talloc_autofree_context(), "HANDLES");
torture_suite_add_simple_test(suite, "lsarpc", test_handles_lsa);
+ torture_suite_add_simple_test(suite, "lsarpc-shared", test_handles_lsa_shared);
torture_suite_add_simple_test(suite, "samr", test_handles_samr);
torture_suite_add_simple_test(suite, "drsuapi", test_handles_drsuapi);
return suite;
diff --git a/source4/torture/rpc/rpc.c b/source4/torture/rpc/rpc.c
index 5348a87489..c3060d08d7 100644
--- a/source4/torture/rpc/rpc.c
+++ b/source4/torture/rpc/rpc.c
@@ -56,7 +56,8 @@ _PUBLIC_ NTSTATUS torture_rpc_connection(TALLOC_CTX *parent_ctx,
NTSTATUS torture_rpc_connection_transport(TALLOC_CTX *parent_ctx,
struct dcerpc_pipe **p,
const struct dcerpc_interface_table *table,
- enum dcerpc_transport_t transport)
+ enum dcerpc_transport_t transport,
+ uint32_t assoc_group_id)
{
NTSTATUS status;
const char *binding = lp_parm_string(-1, "torture", "binding");
@@ -77,6 +78,7 @@ NTSTATUS torture_rpc_connection_transport(TALLOC_CTX *parent_ctx,
}
b->transport = transport;
+ b->assoc_group_id = assoc_group_id;
status = dcerpc_pipe_connect_b(mem_ctx, p, b, table,
cmdline_credentials, NULL);