1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-22 13:34:15 +03:00

selftest: Test RPC handles and association groups from different connection

Add a test to check if a RPC handle can be used from a different connection
than the one where it was created, when the same association group is
requested in the bind operation of the second connection.

The association group handling is one of the differences between the S3
and S4 RPC server implementations provided by the implementation
callbacks after the merge.

Association groups work fine in the S4 implementation as the RPC server
runs in one process, except for the 'smbd' embedded services provided
by the S3 implementation like winreg (see lp_enforce_ad_dc_settings()).

In the S3 implementation, association groups should work in the same
process, but the merge introduced a bug where a new association group is
always created even when it already exists in the same process.

Signed-off-by: Samuel Cabrero <scabrero@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
This commit is contained in:
Samuel Cabrero 2020-06-19 16:31:39 +02:00 committed by Andrew Bartlett
parent de28d915d7
commit 1e559f9587
2 changed files with 127 additions and 0 deletions

View File

@ -0,0 +1 @@
^samba3.rpc.bind.assoc_group_handles_external\(nt4_dc\)

View File

@ -22,6 +22,7 @@
#include "includes.h"
#include "torture/rpc/torture_rpc.h"
#include "librpc/gen_ndr/ndr_lsa_c.h"
#include "librpc/gen_ndr/ndr_epmapper_c.h"
#include "lib/cmdline/popt_common.h"
static bool test_openpolicy(struct torture_context *tctx,
@ -73,6 +74,126 @@ static bool test_bind(struct torture_context *tctx,
return true;
}
/**
* Verifies a handle created in a connection is available on
* a second connection when the same association group is
* requested in the bind operation. The LSA interface can't be
* used because it runs in preforking mode in the selftests.
* Association groups should work when binding to interfaces
* running in the same process.
*/
static bool test_assoc_group_handles_external(struct torture_context *tctx,
const void *private_data)
{
struct dcerpc_binding *binding1 = NULL;
struct dcerpc_binding *binding2 = NULL;
struct dcerpc_pipe *p1 = NULL;
struct dcerpc_pipe *p2 = NULL;
struct epm_Lookup r;
struct epm_LookupHandleFree f;
struct policy_handle handle;
uint32_t assoc_group_id;
uint32_t num_ents = 0;
ZERO_STRUCT(handle);
/* Open first pipe and open a policy handle */
torture_assert_ntstatus_ok(tctx,
torture_rpc_binding(tctx, &binding1),
"failed to parse binding string");
dcerpc_binding_set_transport(binding1, NCACN_IP_TCP);
dcerpc_binding_set_string_option(binding1, "endpoint", "135");
torture_assert_ntstatus_ok(tctx,
dcerpc_pipe_connect_b(tctx, &p1, binding1,
&ndr_table_epmapper,
popt_get_cmdline_credentials(),
tctx->ev,
tctx->lp_ctx),
"failed to connect first pipe");
r.in.inquiry_type = RPC_C_EP_ALL_ELTS;
r.in.object = NULL;
r.in.interface_id = NULL;
r.in.vers_option = RPC_C_VERS_ALL;
r.in.entry_handle = &handle;
r.in.max_ents = 1;
r.out.entry_handle = &handle;
r.out.num_ents = &num_ents;
torture_assert_ntstatus_ok(tctx,
dcerpc_epm_Lookup_r(p1->binding_handle, tctx, &r),
"failed EPM Lookup");
torture_assert_int_equal(tctx,
r.out.result,
EPMAPPER_STATUS_OK,
"failed EPM Lookup");
/* Open second pipe, different association group. Handle not found */
torture_assert_ntstatus_ok(tctx,
torture_rpc_binding(tctx, &binding2),
"failed to parse binding string");
dcerpc_binding_set_transport(binding2, NCACN_IP_TCP);
dcerpc_binding_set_string_option(binding2, "endpoint", "135");
torture_assert_ntstatus_ok(tctx,
dcerpc_pipe_connect_b(tctx, &p2, binding2,
&ndr_table_epmapper,
popt_get_cmdline_credentials(),
tctx->ev,
tctx->lp_ctx),
"failed to connect second pipe");
torture_assert_ntstatus_equal(tctx,
dcerpc_epm_Lookup_r(p2->binding_handle, tctx, &r),
NT_STATUS_RPC_SS_CONTEXT_MISMATCH,
"Unexpected EPM Lookup success");
/* Open second pipe, same association group. Handle is found */
assoc_group_id = dcerpc_binding_get_assoc_group_id(p1->binding);
dcerpc_binding_set_assoc_group_id(binding2, assoc_group_id);
TALLOC_FREE(p2);
torture_assert_ntstatus_ok(tctx,
dcerpc_pipe_connect_b(tctx, &p2, binding2,
&ndr_table_epmapper,
popt_get_cmdline_credentials(),
tctx->ev,
tctx->lp_ctx),
"failed to connect second pipe");
torture_assert_ntstatus_ok(tctx,
dcerpc_epm_Lookup_r(p2->binding_handle, tctx, &r),
"failed EPM Lookup");
torture_assert_int_equal(tctx,
r.out.result,
EPMAPPER_STATUS_OK,
"failed EPM Lookup");
/* Cleanup */
f.in.entry_handle = &handle;
f.out.entry_handle = &handle;
torture_assert_ntstatus_ok(tctx,
dcerpc_epm_LookupHandleFree_r(p1->binding_handle, tctx, &f),
"failed EPM LookupHandleFree");
torture_assert_int_equal(tctx,
r.out.result,
EPMAPPER_STATUS_OK,
"failed EPM LookupHandleFree");
TALLOC_FREE(p1);
TALLOC_FREE(p2);
TALLOC_FREE(binding2);
TALLOC_FREE(binding1);
return true;
}
static void test_bind_op(struct torture_suite *suite,
const char *name,
uint32_t flags)
@ -115,5 +236,10 @@ struct torture_suite *torture_rpc_bind(TALLOC_CTX *mem_ctx)
test_bind_op(suite, talloc_asprintf(suite, "bigendian,%s", tests[i].test_name), tests[i].flags | DCERPC_PUSH_BIGENDIAN);
}
torture_suite_add_simple_tcase_const(suite,
"assoc_group_handles_external",
test_assoc_group_handles_external,
NULL);
return suite;
}