TORTURE_SAMR_PASSWORDS_PWDLASTSET,
TORTURE_SAMR_USER_ATTRIBUTES,
TORTURE_SAMR_USER_PRIVILEGES,
- TORTURE_SAMR_OTHER
+ TORTURE_SAMR_OTHER,
+ TORTURE_SAMR_MANY_ACCOUNTS,
+ TORTURE_SAMR_MANY_GROUPS,
+ TORTURE_SAMR_MANY_ALIASES
};
static bool test_QueryUserInfo(struct dcerpc_pipe *p,
return true;
}
-static bool test_SamLogon_Creds(struct dcerpc_pipe *p, struct torture_context *tctx,
- struct cli_credentials *machine_credentials,
- struct cli_credentials *test_credentials,
- struct netlogon_creds_CredentialState *creds,
- NTSTATUS expected_result)
+static bool test_SamLogon(struct torture_context *tctx,
+ struct dcerpc_pipe *p,
+ struct cli_credentials *test_credentials,
+ NTSTATUS expected_result)
{
NTSTATUS status;
- struct netr_LogonSamLogon r;
- struct netr_Authenticator auth, auth2;
+ struct netr_LogonSamLogonEx r;
union netr_LogonLevel logon;
union netr_Validation validation;
uint8_t authoritative;
struct netr_NetworkInfo ninfo;
DATA_BLOB names_blob, chal, lm_resp, nt_resp;
int flags = CLI_CRED_NTLM_AUTH;
+ uint32_t samlogon_flags = 0;
if (lp_client_lanman_auth(tctx->lp_ctx)) {
flags |= CLI_CRED_LANMAN_AUTH;
chal = data_blob_const(ninfo.challenge,
sizeof(ninfo.challenge));
- names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(machine_credentials),
- cli_credentials_get_domain(machine_credentials));
+ names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(test_credentials),
+ cli_credentials_get_domain(test_credentials));
status = cli_credentials_get_ntlm_response(test_credentials, tctx,
&flags,
MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
ninfo.identity_info.logon_id_low = 0;
ninfo.identity_info.logon_id_high = 0;
- ninfo.identity_info.workstation.string = cli_credentials_get_workstation(machine_credentials);
+ ninfo.identity_info.workstation.string = cli_credentials_get_workstation(test_credentials);
logon.network = &ninfo;
r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
- r.in.computer_name = cli_credentials_get_workstation(machine_credentials);
- r.in.credential = &auth;
- r.in.return_authenticator = &auth2;
- r.in.logon_level = 2;
+ r.in.computer_name = cli_credentials_get_workstation(test_credentials);
+ r.in.logon_level = NetlogonNetworkInformation;
r.in.logon = &logon;
+ r.in.flags = &samlogon_flags;
+ r.out.flags = &samlogon_flags;
r.out.validation = &validation;
r.out.authoritative = &authoritative;
d_printf("Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
- ZERO_STRUCT(auth2);
- netlogon_creds_client_authenticator(creds, &auth);
-
- r.in.validation_level = 2;
+ r.in.validation_level = 6;
- status = dcerpc_netr_LogonSamLogon(p, tctx, &r);
+ status = dcerpc_netr_LogonSamLogonEx(p, tctx, &r);
+ if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
+ r.in.validation_level = 3;
+ status = dcerpc_netr_LogonSamLogonEx(p, tctx, &r);
+ }
if (!NT_STATUS_IS_OK(status)) {
- torture_assert_ntstatus_equal(tctx, status, expected_result, "LogonSamLogon failed");
+ torture_assert_ntstatus_equal(tctx, status, expected_result, "LogonSamLogonEx failed");
return true;
} else {
- torture_assert_ntstatus_ok(tctx, status, "LogonSamLogon failed");
+ torture_assert_ntstatus_ok(tctx, status, "LogonSamLogonEx failed");
}
- torture_assert(tctx, netlogon_creds_client_check(creds, &r.out.return_authenticator->cred),
- "Credential chaining failed");
-
return true;
}
-static bool test_SamLogon(struct torture_context *tctx,
- struct dcerpc_pipe *p,
- struct cli_credentials *machine_credentials,
- struct cli_credentials *test_credentials,
- NTSTATUS expected_result)
-{
- struct netlogon_creds_CredentialState *creds;
-
- if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
- return false;
- }
-
- return test_SamLogon_Creds(p, tctx, machine_credentials, test_credentials,
- creds, expected_result);
-}
-
static bool test_SamLogon_with_creds(struct torture_context *tctx,
struct dcerpc_pipe *p,
struct cli_credentials *machine_creds,
test_credentials = cli_credentials_init(tctx);
cli_credentials_set_workstation(test_credentials,
- TEST_ACCOUNT_NAME_PWD, CRED_SPECIFIED);
+ cli_credentials_get_workstation(machine_creds), CRED_SPECIFIED);
cli_credentials_set_domain(test_credentials,
- lp_workgroup(tctx->lp_ctx), CRED_SPECIFIED);
+ cli_credentials_get_domain(machine_creds), CRED_SPECIFIED);
cli_credentials_set_username(test_credentials,
acct_name, CRED_SPECIFIED);
cli_credentials_set_password(test_credentials,
password, CRED_SPECIFIED);
- cli_credentials_set_secure_channel_type(test_credentials, SEC_CHAN_BDC);
- printf("testing samlogon as %s@%s password: %s\n",
- acct_name, TEST_ACCOUNT_NAME_PWD, password);
+ printf("testing samlogon as %s password: %s\n",
+ acct_name, password);
- if (!test_SamLogon(tctx, p, machine_creds, test_credentials,
+ if (!test_SamLogon(tctx, p, test_credentials,
expected_samlogon_result)) {
torture_warning(tctx, "new password did not work\n");
ret = false;
struct cli_credentials *machine_credentials)
{
int s = 0, q = 0, f = 0, l = 0, z = 0;
+ struct dcerpc_binding *b;
bool ret = true;
- int delay = 500000;
+ int delay = 50000;
bool set_levels[] = { false, true };
bool query_levels[] = { false, true };
- uint32_t levels[] = { 18, 21, 23, 24, 25, 26 };
+ uint32_t levels[] = { 18, 21, 26, 23, 24, 25 }; /* Second half only used when TEST_ALL_LEVELS defined */
uint32_t nonzeros[] = { 1, 24 };
uint32_t fields_present[] = {
0,
struct dcerpc_pipe *np = NULL;
if (torture_setting_bool(tctx, "samba3", false)) {
- delay = 1000000;
+ delay = 999999;
printf("Samba3 has second granularity, setting delay to: %d\n",
delay);
}
- status = torture_rpc_connection(tctx, &np, &ndr_table_netlogon);
+ status = torture_rpc_binding(tctx, &b);
if (!NT_STATUS_IS_OK(status)) {
- return false;
+ ret = false;
+ return ret;
+ }
+
+ /* We have to use schannel, otherwise the SamLogonEx fails
+ * with INTERNAL_ERROR */
+
+ b->flags &= ~DCERPC_AUTH_OPTIONS;
+ b->flags |= DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_128;
+
+ status = dcerpc_pipe_connect_b(tctx, &np, b,
+ &ndr_table_netlogon,
+ machine_credentials, tctx->ev, tctx->lp_ctx);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ d_printf("RPC pipe connect as domain member failed: %s\n", nt_errstr(status));
+ ret = false;
+ return ret;
}
/* set to 1 to enable testing for all possible opcode
(SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
combinations */
#if 0
+#define TEST_ALL_LEVELS 1
#define TEST_SET_LEVELS 1
#define TEST_QUERY_LEVELS 1
#endif
+#ifdef TEST_ALL_LEVELS
for (l=0; l<ARRAY_SIZE(levels); l++) {
+#else
+ for (l=0; l<(ARRAY_SIZE(levels))/2; l++) {
+#endif
for (z=0; z<ARRAY_SIZE(nonzeros); z++) {
for (f=0; f<ARRAY_SIZE(fields_present); f++) {
#ifdef TEST_SET_LEVELS
ret = false;
}
- if (torture_setting_bool(tctx, "samba4", false)) {
- printf("skipping MultipleMembers Alias tests against Samba4\n");
+ if (torture_setting_bool(tctx, "samba3", false) ||
+ torture_setting_bool(tctx, "samba4", false)) {
+ printf("skipping MultipleMembers Alias tests against Samba\n");
return ret;
}
{ ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
{ ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
{ ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
- { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
+ { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_ACCESS_DENIED },
{ ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
{ ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
{ 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
levels[i], info->general.oem_information.string, domain_comment);
- ret = false;
+ if (!torture_setting_bool(tctx, "samba3", false)) {
+ ret = false;
+ }
}
if (!info->general.primary.string) {
printf("QueryDomainInfo level %u returned no PDC name\n",
if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
levels[i], info->oem.oem_information.string, domain_comment);
- ret = false;
+ if (!torture_setting_bool(tctx, "samba3", false)) {
+ ret = false;
+ }
}
break;
case 6:
if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
levels[i], info->general2.general.oem_information.string, domain_comment);
- ret = false;
+ if (!torture_setting_bool(tctx, "samba3", false)) {
+ ret = false;
+ }
}
break;
}
if (torture_setting_bool(tctx, "samba4", false) ||
torture_setting_bool(tctx, "samba3", false)) {
- torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba4\n");
+ torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba\n");
} else {
/* this one is quite strange. I am using random inputs in the
hope of triggering an error that might give us a clue */
return true;
}
+static bool test_EnumDomainUsers(struct dcerpc_pipe *p,
+ struct torture_context *tctx,
+ struct policy_handle *domain_handle,
+ uint32_t *total_num_entries_p)
+{
+ NTSTATUS status;
+ struct samr_EnumDomainUsers r;
+ uint32_t resume_handle = 0;
+ uint32_t num_entries = 0;
+ uint32_t total_num_entries = 0;
+ struct samr_SamArray *sam;
+
+ r.in.domain_handle = domain_handle;
+ r.in.acct_flags = 0;
+ r.in.max_size = (uint32_t)-1;
+ r.in.resume_handle = &resume_handle;
+
+ r.out.sam = &sam;
+ r.out.num_entries = &num_entries;
+ r.out.resume_handle = &resume_handle;
+
+ printf("Testing EnumDomainUsers\n");
+
+ do {
+ status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
+ if (NT_STATUS_IS_ERR(status)) {
+ torture_assert_ntstatus_ok(tctx, status,
+ "failed to enumerate users");
+ }
+
+ total_num_entries += num_entries;
+ } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
+
+ if (total_num_entries_p) {
+ *total_num_entries_p = total_num_entries;
+ }
+
+ return true;
+}
+
+static bool test_EnumDomainGroups(struct dcerpc_pipe *p,
+ struct torture_context *tctx,
+ struct policy_handle *domain_handle,
+ uint32_t *total_num_entries_p)
+{
+ NTSTATUS status;
+ struct samr_EnumDomainGroups r;
+ uint32_t resume_handle = 0;
+ uint32_t num_entries = 0;
+ uint32_t total_num_entries = 0;
+ struct samr_SamArray *sam;
+
+ r.in.domain_handle = domain_handle;
+ r.in.max_size = (uint32_t)-1;
+ r.in.resume_handle = &resume_handle;
+
+ r.out.sam = &sam;
+ r.out.num_entries = &num_entries;
+ r.out.resume_handle = &resume_handle;
+
+ printf("Testing EnumDomainGroups\n");
+
+ do {
+ status = dcerpc_samr_EnumDomainGroups(p, tctx, &r);
+ if (NT_STATUS_IS_ERR(status)) {
+ torture_assert_ntstatus_ok(tctx, status,
+ "failed to enumerate groups");
+ }
+
+ total_num_entries += num_entries;
+ } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
+
+ if (total_num_entries_p) {
+ *total_num_entries_p = total_num_entries;
+ }
+
+ return true;
+}
+
+static bool test_EnumDomainAliases(struct dcerpc_pipe *p,
+ struct torture_context *tctx,
+ struct policy_handle *domain_handle,
+ uint32_t *total_num_entries_p)
+{
+ NTSTATUS status;
+ struct samr_EnumDomainAliases r;
+ uint32_t resume_handle = 0;
+ uint32_t num_entries = 0;
+ uint32_t total_num_entries = 0;
+ struct samr_SamArray *sam;
+
+ r.in.domain_handle = domain_handle;
+ r.in.max_size = (uint32_t)-1;
+ r.in.resume_handle = &resume_handle;
+
+ r.out.sam = &sam;
+ r.out.num_entries = &num_entries;
+ r.out.resume_handle = &resume_handle;
+
+ printf("Testing EnumDomainAliases\n");
+
+ do {
+ status = dcerpc_samr_EnumDomainAliases(p, tctx, &r);
+ if (NT_STATUS_IS_ERR(status)) {
+ torture_assert_ntstatus_ok(tctx, status,
+ "failed to enumerate aliases");
+ }
+
+ total_num_entries += num_entries;
+ } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
+
+ if (total_num_entries_p) {
+ *total_num_entries_p = total_num_entries;
+ }
+
+ return true;
+}
+
+static bool test_ManyObjects(struct dcerpc_pipe *p,
+ struct torture_context *tctx,
+ struct policy_handle *domain_handle,
+ struct dom_sid *domain_sid,
+ enum torture_samr_choice which_ops)
+{
+ uint32_t num_total = 1500;
+ uint32_t num_enum = 0;
+ uint32_t num_disp = 0;
+ uint32_t num_created = 0;
+ uint32_t num_anounced = 0;
+ bool ret = true;
+ NTSTATUS status;
+ uint32_t i;
+
+ struct policy_handle *handles = talloc_zero_array(tctx, struct policy_handle, num_total);
+
+ /* query */
+
+ {
+ struct samr_QueryDomainInfo2 r;
+ union samr_DomainInfo *info;
+ r.in.domain_handle = domain_handle;
+ r.in.level = 2;
+ r.out.info = &info;
+
+ status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
+ torture_assert_ntstatus_ok(tctx, status,
+ "failed to query domain info");
+
+ switch (which_ops) {
+ case TORTURE_SAMR_MANY_ACCOUNTS:
+ num_anounced = info->general.num_users;
+ break;
+ case TORTURE_SAMR_MANY_GROUPS:
+ num_anounced = info->general.num_groups;
+ break;
+ case TORTURE_SAMR_MANY_ALIASES:
+ num_anounced = info->general.num_aliases;
+ break;
+ default:
+ return false;
+ }
+ }
+
+ /* create */
+
+ for (i=0; i < num_total; i++) {
+
+ const char *name = NULL;
+
+ switch (which_ops) {
+ case TORTURE_SAMR_MANY_ACCOUNTS:
+ name = talloc_asprintf(tctx, "%s%04d", TEST_ACCOUNT_NAME, i);
+ ret &= test_CreateUser(p, tctx, domain_handle, name, &handles[i], domain_sid, 0, NULL, false);
+ break;
+ case TORTURE_SAMR_MANY_GROUPS:
+ name = talloc_asprintf(tctx, "%s%04d", TEST_GROUPNAME, i);
+ ret &= test_CreateDomainGroup(p, tctx, domain_handle, name, &handles[i], domain_sid, false);
+ break;
+ case TORTURE_SAMR_MANY_ALIASES:
+ name = talloc_asprintf(tctx, "%s%04d", TEST_ALIASNAME, i);
+ ret &= test_CreateAlias(p, tctx, domain_handle, name, &handles[i], domain_sid, false);
+ break;
+ default:
+ return false;
+ }
+ if (!policy_handle_empty(&handles[i])) {
+ num_created++;
+ }
+ }
+
+ /* enum */
+
+ switch (which_ops) {
+ case TORTURE_SAMR_MANY_ACCOUNTS:
+ ret &= test_EnumDomainUsers(p, tctx, domain_handle, &num_enum);
+ break;
+ case TORTURE_SAMR_MANY_GROUPS:
+ ret &= test_EnumDomainGroups(p, tctx, domain_handle, &num_enum);
+ break;
+ case TORTURE_SAMR_MANY_ALIASES:
+ ret &= test_EnumDomainAliases(p, tctx, domain_handle, &num_enum);
+ break;
+ default:
+ return false;
+ }
+
+ /* TODO: dispinfo */
+
+ switch (which_ops) {
+ case TORTURE_SAMR_MANY_ACCOUNTS:
+ break;
+ case TORTURE_SAMR_MANY_GROUPS:
+ break;
+ case TORTURE_SAMR_MANY_ALIASES:
+ break;
+ default:
+ return false;
+ }
+
+ /* delete */
+
+ for (i=0; i < num_total; i++) {
+
+ if (policy_handle_empty(&handles[i])) {
+ continue;
+ }
+
+ switch (which_ops) {
+ case TORTURE_SAMR_MANY_ACCOUNTS:
+ ret &= test_DeleteUser(p, tctx, &handles[i]);
+ break;
+ case TORTURE_SAMR_MANY_GROUPS:
+ ret &= test_DeleteDomainGroup(p, tctx, &handles[i]);
+ break;
+ case TORTURE_SAMR_MANY_ALIASES:
+ ret &= test_DeleteAlias(p, tctx, &handles[i]);
+ break;
+ default:
+ return false;
+ }
+ }
+
+ talloc_free(handles);
+
+#if 0
+ torture_assert_int_equal(tctx, num_disp, num_anounced + num_created,
+ "unexpected number of results returned in dispinfo call");
+#endif
+ if (which_ops == TORTURE_SAMR_MANY_ACCOUNTS && num_enum != num_anounced + num_created) {
+ torture_comment(tctx,
+ "unexpected number of results (%u) returned in enum call, expected %u\n",
+ num_enum, num_anounced + num_created);
+ }
+ return ret;
+}
static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
struct policy_handle *handle);
/* run the domain tests with the main handle closed - this tests
the servers reference counting */
- ret &= test_samr_handle_Close(p, tctx, handle);
+ torture_assert(tctx, test_samr_handle_Close(p, tctx, handle), "Failed to close SAMR handle");
switch (which_ops) {
- case TORTURE_SAMR_USER_ATTRIBUTES:
- case TORTURE_SAMR_USER_PRIVILEGES:
case TORTURE_SAMR_PASSWORDS:
+ case TORTURE_SAMR_USER_PRIVILEGES:
+ if (!torture_setting_bool(tctx, "samba3", false)) {
+ ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, NULL);
+ }
+ ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, which_ops, NULL, true);
+ if (!ret) {
+ printf("Testing PASSWORDS or PRIVILAGES on domain %s failed!\n", dom_sid_string(tctx, sid));
+ }
+ break;
+ case TORTURE_SAMR_USER_ATTRIBUTES:
if (!torture_setting_bool(tctx, "samba3", false)) {
ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, NULL);
}
/* This test needs 'complex' users to validate */
ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
if (!ret) {
- printf("Testing PASSWORDS or ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
+ printf("Testing ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
}
break;
case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
printf("Testing PASSWORDS PWDLASTSET on domain %s failed!\n", dom_sid_string(tctx, sid));
}
break;
+ case TORTURE_SAMR_MANY_ACCOUNTS:
+ case TORTURE_SAMR_MANY_GROUPS:
+ case TORTURE_SAMR_MANY_ALIASES:
+ ret &= test_ManyObjects(p, tctx, &domain_handle, sid, which_ops);
+ if (!ret) {
+ printf("Testing MANY-{ACCOUNTS,GROUPS,ALIASES} on domain %s failed!\n", dom_sid_string(tctx, sid));
+ }
+ break;
case TORTURE_SAMR_OTHER:
ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, which_ops, NULL, true);
if (!ret) {
ret = false;
}
- ret &= test_samr_handle_Close(p, tctx, &domain_handle);
+ torture_assert(tctx, test_samr_handle_Close(p, tctx, &domain_handle), "Failed to close SAMR domain handle");
+ torture_assert(tctx, test_Connect(p, tctx, handle), "Faile to re-connect SAMR handle");
/* reconnect the main handle */
- ret &= test_Connect(p, tctx, handle);
if (!ret) {
printf("Testing domain %s failed!\n", dom_sid_string(tctx, sid));
return suite;
}
+
+static bool torture_rpc_samr_many_accounts(struct torture_context *torture,
+ struct dcerpc_pipe *p2,
+ struct cli_credentials *machine_credentials)
+{
+ NTSTATUS status;
+ struct dcerpc_pipe *p;
+ bool ret = true;
+ struct policy_handle handle;
+
+ status = torture_rpc_connection(torture, &p, &ndr_table_samr);
+ if (!NT_STATUS_IS_OK(status)) {
+ return false;
+ }
+
+ ret &= test_Connect(p, torture, &handle);
+
+ ret &= test_EnumDomains(p, torture, &handle,
+ TORTURE_SAMR_MANY_ACCOUNTS,
+ machine_credentials);
+
+ ret &= test_samr_handle_Close(p, torture, &handle);
+
+ return ret;
+}
+
+static bool torture_rpc_samr_many_groups(struct torture_context *torture,
+ struct dcerpc_pipe *p2,
+ struct cli_credentials *machine_credentials)
+{
+ NTSTATUS status;
+ struct dcerpc_pipe *p;
+ bool ret = true;
+ struct policy_handle handle;
+
+ status = torture_rpc_connection(torture, &p, &ndr_table_samr);
+ if (!NT_STATUS_IS_OK(status)) {
+ return false;
+ }
+
+ ret &= test_Connect(p, torture, &handle);
+
+ ret &= test_EnumDomains(p, torture, &handle,
+ TORTURE_SAMR_MANY_GROUPS,
+ machine_credentials);
+
+ ret &= test_samr_handle_Close(p, torture, &handle);
+
+ return ret;
+}
+
+static bool torture_rpc_samr_many_aliases(struct torture_context *torture,
+ struct dcerpc_pipe *p2,
+ struct cli_credentials *machine_credentials)
+{
+ NTSTATUS status;
+ struct dcerpc_pipe *p;
+ bool ret = true;
+ struct policy_handle handle;
+
+ status = torture_rpc_connection(torture, &p, &ndr_table_samr);
+ if (!NT_STATUS_IS_OK(status)) {
+ return false;
+ }
+
+ ret &= test_Connect(p, torture, &handle);
+
+ ret &= test_EnumDomains(p, torture, &handle,
+ TORTURE_SAMR_MANY_ALIASES,
+ machine_credentials);
+
+ ret &= test_samr_handle_Close(p, torture, &handle);
+
+ return ret;
+}
+
+struct torture_suite *torture_rpc_samr_large_dc(TALLOC_CTX *mem_ctx)
+{
+ struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-LARGE-DC");
+ struct torture_rpc_tcase *tcase;
+
+ tcase = torture_suite_add_machine_rpc_iface_tcase(suite, "samr",
+ &ndr_table_samr,
+ TEST_ACCOUNT_NAME);
+
+ torture_rpc_tcase_add_test_creds(tcase, "many_aliases",
+ torture_rpc_samr_many_aliases);
+ torture_rpc_tcase_add_test_creds(tcase, "many_groups",
+ torture_rpc_samr_many_groups);
+ torture_rpc_tcase_add_test_creds(tcase, "many_accounts",
+ torture_rpc_samr_many_accounts);
+
+ return suite;
+}