diff options
Diffstat (limited to 'source4/torture/rpc')
-rw-r--r-- | source4/torture/rpc/rpc.c | 1 | ||||
-rw-r--r-- | source4/torture/rpc/samr.c | 407 |
2 files changed, 382 insertions, 26 deletions
diff --git a/source4/torture/rpc/rpc.c b/source4/torture/rpc/rpc.c index 48a488741f..19b223beba 100644 --- a/source4/torture/rpc/rpc.c +++ b/source4/torture/rpc/rpc.c @@ -409,6 +409,7 @@ NTSTATUS torture_rpc_init(void) torture_suite_add_suite(suite, torture_rpc_samr_accessmask(suite)); torture_suite_add_suite(suite, torture_rpc_samr_passwords_pwdlastset(suite)); torture_suite_add_suite(suite, torture_rpc_samr_user_privileges(suite)); + torture_suite_add_suite(suite, torture_rpc_samr_large_dc(suite)); torture_suite_add_suite(suite, torture_rpc_epmapper(suite)); torture_suite_add_suite(suite, torture_rpc_initshutdown(suite)); torture_suite_add_suite(suite, torture_rpc_oxidresolve(suite)); diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c index 692dddf73b..92ce66fef2 100644 --- a/source4/torture/rpc/samr.c +++ b/source4/torture/rpc/samr.c @@ -48,7 +48,10 @@ enum torture_samr_choice { 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, @@ -3999,9 +4002,11 @@ static bool test_DeleteAlias(struct dcerpc_pipe *p, } static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx, - struct policy_handle *domain_handle, + struct policy_handle *domain_handle, + const char *alias_name, struct policy_handle *alias_handle, - const struct dom_sid *domain_sid) + const struct dom_sid *domain_sid, + bool test_alias) { NTSTATUS status; struct samr_CreateDomAlias r; @@ -4009,7 +4014,7 @@ static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx uint32_t rid; bool ret = true; - init_lsa_String(&name, TEST_ALIASNAME); + init_lsa_String(&name, alias_name); r.in.domain_handle = domain_handle; r.in.alias_name = &name; r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; @@ -4043,6 +4048,10 @@ static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx return false; } + if (!test_alias) { + return ret; + } + if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) { ret = false; } @@ -4217,10 +4226,12 @@ static bool test_ChangePassword(struct dcerpc_pipe *p, static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx, struct policy_handle *domain_handle, + const char *user_name, struct policy_handle *user_handle_out, struct dom_sid *domain_sid, enum torture_samr_choice which_ops, - struct cli_credentials *machine_credentials) + struct cli_credentials *machine_credentials, + bool test_user) { TALLOC_CTX *user_ctx; @@ -4239,7 +4250,7 @@ static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx, struct policy_handle user_handle; user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context"); - init_lsa_String(&name, TEST_ACCOUNT_NAME); + init_lsa_String(&name, user_name); r.in.domain_handle = domain_handle; r.in.account_name = &name; @@ -4269,11 +4280,21 @@ static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx, } status = dcerpc_samr_CreateUser(p, user_ctx, &r); } + if (!NT_STATUS_IS_OK(status)) { talloc_free(user_ctx); printf("CreateUser failed - %s\n", nt_errstr(status)); return false; - } else { + } + + if (!test_user) { + if (user_handle_out) { + *user_handle_out = user_handle; + } + return ret; + } + + { q.in.user_handle = &user_handle; q.in.level = 16; q.out.info = &info; @@ -4869,8 +4890,9 @@ static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx, return ret; } -static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context *tctx, - struct policy_handle *handle) +static bool test_EnumDomainUsers_all(struct dcerpc_pipe *p, + struct torture_context *tctx, + struct policy_handle *handle) { NTSTATUS status = STATUS_MORE_ENTRIES; struct samr_EnumDomainUsers r; @@ -4998,9 +5020,9 @@ static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_con return true; } -static bool test_EnumDomainGroups(struct dcerpc_pipe *p, - struct torture_context *tctx, - struct policy_handle *handle) +static bool test_EnumDomainGroups_all(struct dcerpc_pipe *p, + struct torture_context *tctx, + struct policy_handle *handle) { NTSTATUS status; struct samr_EnumDomainGroups r; @@ -5038,9 +5060,9 @@ static bool test_EnumDomainGroups(struct dcerpc_pipe *p, return ret; } -static bool test_EnumDomainAliases(struct dcerpc_pipe *p, - struct torture_context *tctx, - struct policy_handle *handle) +static bool test_EnumDomainAliases_all(struct dcerpc_pipe *p, + struct torture_context *tctx, + struct policy_handle *handle) { NTSTATUS status; struct samr_EnumDomainAliases r; @@ -5931,10 +5953,12 @@ static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *t static bool test_CreateDomainGroup(struct dcerpc_pipe *p, - struct torture_context *tctx, + struct torture_context *tctx, struct policy_handle *domain_handle, + const char *group_name, struct policy_handle *group_handle, - struct dom_sid *domain_sid) + struct dom_sid *domain_sid, + bool test_group) { NTSTATUS status; struct samr_CreateDomainGroup r; @@ -5942,7 +5966,7 @@ static bool test_CreateDomainGroup(struct dcerpc_pipe *p, struct lsa_String name; bool ret = true; - init_lsa_String(&name, TEST_GROUPNAME); + init_lsa_String(&name, group_name); r.in.domain_handle = domain_handle; r.in.name = &name; @@ -5984,6 +6008,10 @@ static bool test_CreateDomainGroup(struct dcerpc_pipe *p, } torture_assert_ntstatus_ok(tctx, status, "CreateDomainGroup"); + if (!test_group) { + return ret; + } + if (!test_AddGroupMember(p, tctx, domain_handle, group_handle)) { printf("CreateDomainGroup failed - %s\n", nt_errstr(status)); ret = false; @@ -6016,7 +6044,235 @@ static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p, 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 = ACB_NORMAL; + 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; + + /* 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++) { + + struct policy_handle handle; + const char *name = NULL; + + ZERO_STRUCT(handle); + + 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, &handle, 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, &handle, 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, &handle, domain_sid, false); + break; + default: + return false; + } + if (!policy_handle_empty(&handle)) { + ret &= test_samr_handle_Close(p, tctx, &handle); + 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; + } + + torture_assert_int_equal(tctx, num_enum, num_anounced + num_created, + "unexpected number of results returned in enum call"); +#if 0 + /* 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; + } + + torture_assert_int_equal(tctx, num_disp, num_anounced + num_created, + "unexpected number of results returned in dispinfo call"); +#endif + return ret; +} static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx, struct policy_handle *handle); @@ -6060,7 +6316,7 @@ static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx, 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, &user_handle, sid, which_ops, NULL); + ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, which_ops, NULL, true); /* This test needs 'complex' users to validate */ ret &= test_QueryDisplayInfo(p, tctx, &domain_handle); if (!ret) { @@ -6071,13 +6327,18 @@ static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx, if (!torture_setting_bool(tctx, "samba3", false)) { ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, machine_credentials); } - ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops, machine_credentials); + ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, which_ops, machine_credentials, true); if (!ret) { 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); + break; case TORTURE_SAMR_OTHER: - ret &= test_CreateUser(p, tctx, &domain_handle, &user_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("Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid)); } @@ -6085,14 +6346,14 @@ static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx, ret &= test_QuerySecurity(p, tctx, &domain_handle); } ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle); - ret &= test_CreateAlias(p, tctx, &domain_handle, &alias_handle, sid); - ret &= test_CreateDomainGroup(p, tctx, &domain_handle, &group_handle, sid); + ret &= test_CreateAlias(p, tctx, &domain_handle, TEST_ALIASNAME, &alias_handle, sid, true); + ret &= test_CreateDomainGroup(p, tctx, &domain_handle, TEST_GROUPNAME, &group_handle, sid, true); ret &= test_QueryDomainInfo(p, tctx, &domain_handle); ret &= test_QueryDomainInfo2(p, tctx, &domain_handle); - ret &= test_EnumDomainUsers(p, tctx, &domain_handle); + ret &= test_EnumDomainUsers_all(p, tctx, &domain_handle); ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle); - ret &= test_EnumDomainGroups(p, tctx, &domain_handle); - ret &= test_EnumDomainAliases(p, tctx, &domain_handle); + ret &= test_EnumDomainGroups_all(p, tctx, &domain_handle); + ret &= test_EnumDomainAliases_all(p, tctx, &domain_handle); ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle); ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle); ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle); @@ -6504,3 +6765,97 @@ struct torture_suite *torture_rpc_samr_user_privileges(TALLOC_CTX *mem_ctx) 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; +} |