diff options
Diffstat (limited to 'source4/torture')
-rw-r--r-- | source4/torture/libnet/libnet_domain.c | 6 | ||||
-rw-r--r-- | source4/torture/libnet/libnet_group.c | 9 | ||||
-rw-r--r-- | source4/torture/libnet/libnet_user.c | 9 | ||||
-rw-r--r-- | source4/torture/libnet/utils.c | 18 | ||||
-rw-r--r-- | source4/torture/rpc/samba3rpc.c | 53 | ||||
-rw-r--r-- | source4/torture/rpc/samr.c | 527 | ||||
-rw-r--r-- | source4/torture/rpc/samr_accessmask.c | 29 | ||||
-rw-r--r-- | source4/torture/rpc/samsync.c | 149 | ||||
-rw-r--r-- | source4/torture/rpc/schannel.c | 2 | ||||
-rw-r--r-- | source4/torture/rpc/testjoin.c | 17 |
10 files changed, 548 insertions, 271 deletions
diff --git a/source4/torture/libnet/libnet_domain.c b/source4/torture/libnet/libnet_domain.c index 7d5be368c2..3c28d1a019 100644 --- a/source4/torture/libnet/libnet_domain.c +++ b/source4/torture/libnet/libnet_domain.c @@ -35,12 +35,13 @@ static bool test_opendomain_samr(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle *handle, struct lsa_String *domname, - uint32_t *access_mask, struct dom_sid **sid) + uint32_t *access_mask, struct dom_sid **sid_p) { NTSTATUS status; struct policy_handle h, domain_handle; struct samr_Connect r1; struct samr_LookupDomain r2; + struct dom_sid2 *sid = NULL; struct samr_OpenDomain r3; printf("connecting\n"); @@ -59,6 +60,7 @@ static bool test_opendomain_samr(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, r2.in.connect_handle = &h; r2.in.domain_name = domname; + r2.out.sid = &sid; printf("domain lookup on %s\n", domname->string); @@ -70,7 +72,7 @@ static bool test_opendomain_samr(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, r3.in.connect_handle = &h; r3.in.access_mask = *access_mask; - r3.in.sid = *sid = r2.out.sid; + r3.in.sid = *sid_p = *r2.out.sid; r3.out.domain_handle = &domain_handle; printf("opening domain\n"); diff --git a/source4/torture/libnet/libnet_group.c b/source4/torture/libnet/libnet_group.c index 12b8167a86..9c9ecfd525 100644 --- a/source4/torture/libnet/libnet_group.c +++ b/source4/torture/libnet/libnet_group.c @@ -42,12 +42,15 @@ static bool test_cleanup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct lsa_String names[2]; uint32_t rid; struct policy_handle group_handle; + struct samr_Ids rids, types; names[0].string = groupname; r1.in.domain_handle = domain_handle; r1.in.num_names = 1; r1.in.names = names; + r1.out.rids = &rids; + r1.out.types = &types; printf("group account lookup '%s'\n", groupname); @@ -57,7 +60,7 @@ static bool test_cleanup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, return false; } - rid = r1.out.rids.ids[0]; + rid = r1.out.rids->ids[0]; r2.in.domain_handle = domain_handle; r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; @@ -139,6 +142,7 @@ static bool test_opendomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle h, domain_handle; struct samr_Connect r1; struct samr_LookupDomain r2; + struct dom_sid2 *sid = NULL; struct samr_OpenDomain r3; printf("connecting\n"); @@ -155,6 +159,7 @@ static bool test_opendomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, r2.in.connect_handle = &h; r2.in.domain_name = domname; + r2.out.sid = &sid; printf("domain lookup on %s\n", domname->string); @@ -166,7 +171,7 @@ static bool test_opendomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, r3.in.connect_handle = &h; r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - r3.in.sid = r2.out.sid; + r3.in.sid = *r2.out.sid; r3.out.domain_handle = &domain_handle; printf("opening domain\n"); diff --git a/source4/torture/libnet/libnet_user.c b/source4/torture/libnet/libnet_user.c index 6d3e682976..18007dccad 100644 --- a/source4/torture/libnet/libnet_user.c +++ b/source4/torture/libnet/libnet_user.c @@ -40,12 +40,15 @@ static bool test_cleanup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct lsa_String names[2]; uint32_t rid; struct policy_handle user_handle; + struct samr_Ids rids, types; names[0].string = username; r1.in.domain_handle = domain_handle; r1.in.num_names = 1; r1.in.names = names; + r1.out.rids = &rids; + r1.out.types = &types; printf("user account lookup '%s'\n", username); @@ -55,7 +58,7 @@ static bool test_cleanup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, return false; } - rid = r1.out.rids.ids[0]; + rid = r1.out.rids->ids[0]; r2.in.domain_handle = domain_handle; r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; @@ -92,6 +95,7 @@ static bool test_opendomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle h, domain_handle; struct samr_Connect r1; struct samr_LookupDomain r2; + struct dom_sid2 *sid = NULL; struct samr_OpenDomain r3; printf("connecting\n"); @@ -108,6 +112,7 @@ static bool test_opendomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, r2.in.connect_handle = &h; r2.in.domain_name = domname; + r2.out.sid = &sid; printf("domain lookup on %s\n", domname->string); @@ -119,7 +124,7 @@ static bool test_opendomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, r3.in.connect_handle = &h; r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - r3.in.sid = r2.out.sid; + r3.in.sid = *r2.out.sid; r3.out.domain_handle = &domain_handle; printf("opening domain\n"); diff --git a/source4/torture/libnet/utils.c b/source4/torture/libnet/utils.c index 54c5f2c29c..942540c80e 100644 --- a/source4/torture/libnet/utils.c +++ b/source4/torture/libnet/utils.c @@ -32,12 +32,13 @@ bool test_opendomain(struct torture_context *tctx, struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle *handle, struct lsa_String *domname, - struct dom_sid2 *sid) + struct dom_sid2 *sid_p) { NTSTATUS status; struct policy_handle h, domain_handle; struct samr_Connect r1; struct samr_LookupDomain r2; + struct dom_sid2 *sid = NULL; struct samr_OpenDomain r3; torture_comment(tctx, "connecting\n"); @@ -51,6 +52,7 @@ bool test_opendomain(struct torture_context *tctx, r2.in.connect_handle = &h; r2.in.domain_name = domname; + r2.out.sid = &sid; torture_comment(tctx, "domain lookup on %s\n", domname->string); @@ -59,7 +61,7 @@ bool test_opendomain(struct torture_context *tctx, r3.in.connect_handle = &h; r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - r3.in.sid = r2.out.sid; + r3.in.sid = *r2.out.sid; r3.out.domain_handle = &domain_handle; torture_comment(tctx, "opening domain\n"); @@ -68,7 +70,7 @@ bool test_opendomain(struct torture_context *tctx, torture_assert_ntstatus_ok(tctx, status, "OpenDomain failed"); *handle = domain_handle; - *sid = *r2.out.sid; + *sid_p = **r2.out.sid; return true; } @@ -84,19 +86,22 @@ bool test_user_cleanup(struct torture_context *tctx, struct dcerpc_pipe *p, struct lsa_String names[2]; uint32_t rid; struct policy_handle user_handle; + struct samr_Ids rids, types; names[0].string = name; r1.in.domain_handle = domain_handle; r1.in.num_names = 1; r1.in.names = names; + r1.out.rids = &rids; + r1.out.types = &types; torture_comment(tctx, "user account lookup '%s'\n", name); status = dcerpc_samr_LookupNames(p, mem_ctx, &r1); torture_assert_ntstatus_ok(tctx, status, "LookupNames failed"); - rid = r1.out.rids.ids[0]; + rid = r1.out.rids->ids[0]; r2.in.domain_handle = domain_handle; r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; @@ -174,12 +179,15 @@ bool test_group_cleanup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct lsa_String names[2]; uint32_t rid; struct policy_handle group_handle; + struct samr_Ids rids, types; names[0].string = name; r1.in.domain_handle = domain_handle; r1.in.num_names = 1; r1.in.names = names; + r1.out.rids = &rids; + r1.out.types = &types; printf("group account lookup '%s'\n", name); @@ -189,7 +197,7 @@ bool test_group_cleanup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, return false; } - rid = r1.out.rids.ids[0]; + rid = r1.out.rids->ids[0]; r2.in.domain_handle = domain_handle; r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; diff --git a/source4/torture/rpc/samba3rpc.c b/source4/torture/rpc/samba3rpc.c index c2b849127f..1148262dfe 100644 --- a/source4/torture/rpc/samba3rpc.c +++ b/source4/torture/rpc/samba3rpc.c @@ -355,7 +355,7 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli, char **domain, struct dcerpc_pipe **result_pipe, struct policy_handle **result_handle, - struct dom_sid **sid) + struct dom_sid **sid_p) { struct dcerpc_pipe *samr_pipe; NTSTATUS status; @@ -365,7 +365,10 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli, struct samr_Connect2 conn; struct samr_EnumDomains enumdom; uint32_t resume_handle = 0; + uint32_t num_entries = 0; + struct samr_SamArray *sam = NULL; struct samr_LookupDomain l; + struct dom_sid2 *sid = NULL; int dom_idx; struct lsa_String domain_name; struct lsa_String user_name; @@ -423,6 +426,8 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli, enumdom.in.resume_handle = &resume_handle; enumdom.in.buf_size = (uint32_t)-1; enumdom.out.resume_handle = &resume_handle; + enumdom.out.num_entries = &num_entries; + enumdom.out.sam = &sam; status = dcerpc_samr_EnumDomains(samr_pipe, mem_ctx, &enumdom); if (!NT_STATUS_IS_OK(status)) { @@ -430,20 +435,21 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli, goto fail; } - if (enumdom.out.num_entries != 2) { + if (*enumdom.out.num_entries != 2) { d_printf("samr_EnumDomains returned %d entries, expected 2\n", - enumdom.out.num_entries); + *enumdom.out.num_entries); status = NT_STATUS_UNSUCCESSFUL; goto fail; } - dom_idx = strequal(enumdom.out.sam->entries[0].name.string, + dom_idx = strequal(sam->entries[0].name.string, "builtin") ? 1:0; l.in.connect_handle = &conn_handle; - domain_name.string = enumdom.out.sam->entries[dom_idx].name.string; + domain_name.string = sam->entries[dom_idx].name.string; *domain = talloc_strdup(mem_ctx, domain_name.string); l.in.domain_name = &domain_name; + l.out.sid = &sid; status = dcerpc_samr_LookupDomain(samr_pipe, mem_ctx, &l); if (!NT_STATUS_IS_OK(status)) { @@ -453,7 +459,7 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli, o.in.connect_handle = &conn_handle; o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - o.in.sid = l.out.sid; + o.in.sid = *l.out.sid; o.out.domain_handle = &domain_handle; status = dcerpc_samr_OpenDomain(samr_pipe, mem_ctx, &o); @@ -477,10 +483,13 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli, if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) { struct samr_LookupNames ln; struct samr_OpenUser ou; + struct samr_Ids rids, types; ln.in.domain_handle = &domain_handle; ln.in.num_names = 1; ln.in.names = &user_name; + ln.out.rids = &rids; + ln.out.types = &types; status = dcerpc_samr_LookupNames(samr_pipe, mem_ctx, &ln); if (!NT_STATUS_IS_OK(status)) { @@ -491,7 +500,7 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli, ou.in.domain_handle = &domain_handle; ou.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - user_rid = ou.in.rid = ln.out.rids.ids[0]; + user_rid = ou.in.rid = ln.out.rids->ids[0]; ou.out.user_handle = user_handle; status = dcerpc_samr_OpenUser(samr_pipe, mem_ctx, &ou); @@ -509,8 +518,8 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli, *result_pipe = samr_pipe; *result_handle = user_handle; - if (sid != NULL) { - *sid = dom_sid_add_rid(mem_ctx, l.out.sid, user_rid); + if (sid_p != NULL) { + *sid_p = dom_sid_add_rid(mem_ctx, *l.out.sid, user_rid); } return NT_STATUS_OK; @@ -555,6 +564,7 @@ static bool create_user(TALLOC_CTX *mem_ctx, struct smbcli_state *cli, struct samr_SetUserInfo sui; struct samr_QueryUserInfo qui; union samr_UserInfo u_info; + union samr_UserInfo *info; DATA_BLOB session_key; @@ -597,6 +607,7 @@ static bool create_user(TALLOC_CTX *mem_ctx, struct smbcli_state *cli, qui.in.user_handle = wks_handle; qui.in.level = 21; + qui.out.info = &info; status = dcerpc_samr_QueryUserInfo(samr_pipe, tmp_ctx, &qui); if (!NT_STATUS_IS_OK(status)) { @@ -604,14 +615,14 @@ static bool create_user(TALLOC_CTX *mem_ctx, struct smbcli_state *cli, goto done; } - qui.out.info->info21.allow_password_change = 0; - qui.out.info->info21.force_password_change = 0; - qui.out.info->info21.account_name.string = NULL; - qui.out.info->info21.rid = 0; - qui.out.info->info21.acct_expiry = 0; - qui.out.info->info21.fields_present = 0x81827fa; /* copy usrmgr.exe */ + info->info21.allow_password_change = 0; + info->info21.force_password_change = 0; + info->info21.account_name.string = NULL; + info->info21.rid = 0; + info->info21.acct_expiry = 0; + info->info21.fields_present = 0x81827fa; /* copy usrmgr.exe */ - u_info.info21 = qui.out.info->info21; + u_info.info21 = info->info21; sui.in.user_handle = wks_handle; sui.in.info = &u_info; sui.in.level = 21; @@ -721,9 +732,11 @@ static bool join3(struct smbcli_state *cli, { struct samr_QueryUserInfo q; + union samr_UserInfo *info; q.in.user_handle = wks_handle; q.in.level = 21; + q.out.info = &info; status = dcerpc_samr_QueryUserInfo(samr_pipe, mem_ctx, &q); if (!NT_STATUS_IS_OK(status)) { @@ -732,7 +745,7 @@ static bool join3(struct smbcli_state *cli, goto done; } - last_password_change = q.out.info->info21.last_password_change; + last_password_change = info->info21.last_password_change; } cli_credentials_set_domain(wks_creds, dom_name, CRED_SPECIFIED); @@ -830,9 +843,11 @@ static bool join3(struct smbcli_state *cli, { struct samr_QueryUserInfo q; + union samr_UserInfo *info; q.in.user_handle = wks_handle; q.in.level = 21; + q.out.info = &info; status = dcerpc_samr_QueryUserInfo(samr_pipe, mem_ctx, &q); if (!NT_STATUS_IS_OK(status)) { @@ -843,7 +858,7 @@ static bool join3(struct smbcli_state *cli, if (use_level25) { if (last_password_change - == q.out.info->info21.last_password_change) { + == info->info21.last_password_change) { d_printf("(%s) last_password_change unchanged " "during join, level25 must change " "it\n", __location__); @@ -852,7 +867,7 @@ static bool join3(struct smbcli_state *cli, } else { if (last_password_change - != q.out.info->info21.last_password_change) { + != info->info21.last_password_change) { d_printf("(%s) last_password_change changed " "during join, level24 doesn't " "change it\n", __location__); diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c index 23c288bfcc..87690178a7 100644 --- a/source4/torture/rpc/samr.c +++ b/source4/torture/rpc/samr.c @@ -59,6 +59,13 @@ static void init_lsa_String(struct lsa_String *string, const char *s) string->string = s; } +static void init_lsa_BinaryString(struct lsa_BinaryString *string, const char *s, uint32_t length) +{ + string->length = length; + string->size = length; + string->array = (uint16_t *)discard_const(s); +} + bool test_samr_handle_Close(struct dcerpc_pipe *p, struct torture_context *tctx, struct policy_handle *handle) { @@ -131,18 +138,20 @@ static bool test_QuerySecurity(struct dcerpc_pipe *p, NTSTATUS status; struct samr_QuerySecurity r; struct samr_SetSecurity s; + struct sec_desc_buf *sdbuf = NULL; r.in.handle = handle; r.in.sec_info = 7; + r.out.sdbuf = &sdbuf; status = dcerpc_samr_QuerySecurity(p, tctx, &r); torture_assert_ntstatus_ok(tctx, status, "QuerySecurity"); - torture_assert(tctx, r.out.sdbuf != NULL, "sdbuf is NULL"); + torture_assert(tctx, sdbuf != NULL, "sdbuf is NULL"); s.in.handle = handle; s.in.sec_info = 7; - s.in.sdbuf = r.out.sdbuf; + s.in.sdbuf = sdbuf; if (torture_setting_bool(tctx, "samba4", false)) { torture_skip(tctx, "skipping SetSecurity test against Samba4\n"); @@ -168,6 +177,7 @@ static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx struct samr_QueryUserInfo q; struct samr_QueryUserInfo q0; union samr_UserInfo u; + union samr_UserInfo *info; bool ret = true; const char *test_account_name; @@ -184,7 +194,7 @@ static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx s2.in.info = &u; q.in.user_handle = handle; - q.out.info = &u; + q.out.info = &info; q0 = q; #define TESTCALL(call, r) \ @@ -204,6 +214,14 @@ static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx break; \ } +#define MEM_EQUAL(s1, s2, length, field) \ + if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \ + torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \ + #field, (const char *)s2, __location__); \ + ret = false; \ + break; \ + } + #define INT_EQUAL(i1, i2, field) \ if (i1 != i2) { \ torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \ @@ -218,7 +236,7 @@ static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx TESTCALL(QueryUserInfo, q) \ s.in.level = lvl1; \ s2.in.level = lvl1; \ - u = *q.out.info; \ + u = *info; \ if (lvl1 == 21) { \ ZERO_STRUCT(u.info21); \ u.info21.fields_present = fpval; \ @@ -228,21 +246,45 @@ static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx TESTCALL(SetUserInfo2, s2) \ init_lsa_String(&u.info ## lvl1.field1, ""); \ TESTCALL(QueryUserInfo, q); \ - u = *q.out.info; \ + u = *info; \ STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \ q.in.level = lvl2; \ TESTCALL(QueryUserInfo, q) \ - u = *q.out.info; \ + u = *info; \ STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \ } while (0) +#define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \ + torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \ + q.in.level = lvl1; \ + TESTCALL(QueryUserInfo, q) \ + s.in.level = lvl1; \ + s2.in.level = lvl1; \ + u = *info; \ + if (lvl1 == 21) { \ + ZERO_STRUCT(u.info21); \ + u.info21.fields_present = fpval; \ + } \ + init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \ + TESTCALL(SetUserInfo, s) \ + TESTCALL(SetUserInfo2, s2) \ + init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \ + TESTCALL(QueryUserInfo, q); \ + u = *info; \ + MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \ + q.in.level = lvl2; \ + TESTCALL(QueryUserInfo, q) \ + u = *info; \ + MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \ + } while (0) + #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \ torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \ q.in.level = lvl1; \ TESTCALL(QueryUserInfo, q) \ s.in.level = lvl1; \ s2.in.level = lvl1; \ - u = *q.out.info; \ + u = *info; \ if (lvl1 == 21) { \ uint8_t *bits = u.info21.logon_hours.bits; \ ZERO_STRUCT(u.info21); \ @@ -257,11 +299,11 @@ static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx TESTCALL(SetUserInfo2, s2) \ u.info ## lvl1.field1 = 0; \ TESTCALL(QueryUserInfo, q); \ - u = *q.out.info; \ + u = *info; \ INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \ q.in.level = lvl2; \ TESTCALL(QueryUserInfo, q) \ - u = *q.out.info; \ + u = *info; \ INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \ } while (0) @@ -359,10 +401,10 @@ static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14", SAMR_FIELD_WORKSTATIONS); - TEST_USERINFO_STRING(20, parameters, 21, parameters, "xx20-21 parameters", 0); - TEST_USERINFO_STRING(21, parameters, 21, parameters, "xx21-21 parameters", + TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0); + TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters", SAMR_FIELD_PARAMETERS); - TEST_USERINFO_STRING(21, parameters, 20, parameters, "xx21-20 parameters", + TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters", SAMR_FIELD_PARAMETERS); TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0); @@ -512,12 +554,14 @@ static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx DATA_BLOB session_key; char *newpass; struct samr_GetUserPwInfo pwp; + struct samr_PwInfo info; int policy_min_pw_len = 0; pwp.in.user_handle = handle; + pwp.out.info = &info; status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp); if (NT_STATUS_IS_OK(status)) { - policy_min_pw_len = pwp.out.info.min_password_length; + policy_min_pw_len = pwp.out.info->min_password_length; } newpass = samr_rand_pass(tctx, policy_min_pw_len); @@ -564,12 +608,14 @@ static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *t DATA_BLOB session_key; char *newpass; struct samr_GetUserPwInfo pwp; + struct samr_PwInfo info; int policy_min_pw_len = 0; pwp.in.user_handle = handle; + pwp.out.info = &info; status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp); if (NT_STATUS_IS_OK(status)) { - policy_min_pw_len = pwp.out.info.min_password_length; + policy_min_pw_len = pwp.out.info->min_password_length; } newpass = samr_rand_pass(tctx, policy_min_pw_len); @@ -643,12 +689,14 @@ static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tc char *newpass; struct MD5Context ctx; struct samr_GetUserPwInfo pwp; + struct samr_PwInfo info; int policy_min_pw_len = 0; pwp.in.user_handle = handle; + pwp.out.info = &info; status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp); if (NT_STATUS_IS_OK(status)) { - policy_min_pw_len = pwp.out.info.min_password_length; + policy_min_pw_len = pwp.out.info->min_password_length; } if (makeshort && policy_min_pw_len) { newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1); @@ -725,12 +773,14 @@ static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *t uint8_t confounder[16]; char *newpass; struct samr_GetUserPwInfo pwp; + struct samr_PwInfo info; int policy_min_pw_len = 0; pwp.in.user_handle = handle; + pwp.out.info = &info; status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp); if (NT_STATUS_IS_OK(status)) { - policy_min_pw_len = pwp.out.info.min_password_length; + policy_min_pw_len = pwp.out.info->min_password_length; } newpass = samr_rand_pass(tctx, policy_min_pw_len); @@ -796,6 +846,7 @@ static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tct NTSTATUS status; struct samr_SetAliasInfo r; struct samr_QueryAliasInfo q; + union samr_AliasInfo *info; uint16_t levels[] = {2, 3}; int i; bool ret = true; @@ -826,6 +877,7 @@ static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tct q.in.alias_handle = handle; q.in.level = levels[i]; + q.out.info = &info; status = dcerpc_samr_QueryAliasInfo(p, tctx, &q); if (!NT_STATUS_IS_OK(status)) { @@ -842,11 +894,13 @@ static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context struct policy_handle *user_handle) { struct samr_GetGroupsForUser r; + struct samr_RidWithAttributeArray *rids = NULL; NTSTATUS status; torture_comment(tctx, "testing GetGroupsForUser\n"); r.in.user_handle = user_handle; + r.out.rids = &rids; status = dcerpc_samr_GetGroupsForUser(p, tctx, &r); torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser"); @@ -860,8 +914,11 @@ static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tct { NTSTATUS status; struct samr_GetDomPwInfo r; + struct samr_PwInfo info; r.in.domain_name = domain_name; + r.out.info = &info; + torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string); status = dcerpc_samr_GetDomPwInfo(p, tctx, &r); @@ -893,10 +950,12 @@ static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tc { NTSTATUS status; struct samr_GetUserPwInfo r; + struct samr_PwInfo info; torture_comment(tctx, "Testing GetUserPwInfo\n"); r.in.user_handle = handle; + r.out.info = &info; status = dcerpc_samr_GetUserPwInfo(p, tctx, &r); torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo"); @@ -911,15 +970,18 @@ static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *t NTSTATUS status; struct samr_LookupNames n; struct lsa_String sname[2]; + struct samr_Ids rids, types; init_lsa_String(&sname[0], name); n.in.domain_handle = domain_handle; n.in.num_names = 1; n.in.names = sname; + n.out.rids = &rids; + n.out.types = &types; status = dcerpc_samr_LookupNames(p, tctx, &n); if (NT_STATUS_IS_OK(status)) { - *rid = n.out.rids.ids[0]; + *rid = n.out.rids->ids[0]; } else { return status; } @@ -1071,6 +1133,7 @@ static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_contex char *newpass; struct samr_GetUserPwInfo pwp; + struct samr_PwInfo info; int policy_min_pw_len = 0; status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle); @@ -1078,10 +1141,11 @@ static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_contex return false; } pwp.in.user_handle = &user_handle; + pwp.out.info = &info; status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp); if (NT_STATUS_IS_OK(status)) { - policy_min_pw_len = pwp.out.info.min_password_length; + policy_min_pw_len = pwp.out.info->min_password_length; } newpass = samr_rand_pass(tctx, policy_min_pw_len); @@ -1346,12 +1410,14 @@ static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_co uint8_t old_lm_hash[16], new_lm_hash[16]; struct samr_GetDomPwInfo dom_pw_info; + struct samr_PwInfo info; int policy_min_pw_len = 0; struct lsa_String domain_name; domain_name.string = ""; dom_pw_info.in.domain_name = &domain_name; + dom_pw_info.out.info = &info; torture_comment(tctx, "Testing OemChangePasswordUser2\n"); @@ -1362,7 +1428,7 @@ static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_co status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info); if (NT_STATUS_IS_OK(status)) { - policy_min_pw_len = dom_pw_info.out.info.min_password_length; + policy_min_pw_len = dom_pw_info.out.info->min_password_length; } newpass = samr_rand_pass(tctx, policy_min_pw_len); @@ -1515,11 +1581,13 @@ static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_conte uint8_t old_lm_hash[16], new_lm_hash[16]; struct samr_GetDomPwInfo dom_pw_info; + struct samr_PwInfo info; struct lsa_String domain_name; domain_name.string = ""; dom_pw_info.in.domain_name = &domain_name; + dom_pw_info.out.info = &info; torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name); @@ -1531,7 +1599,7 @@ static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_conte int policy_min_pw_len = 0; status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info); if (NT_STATUS_IS_OK(status)) { - policy_min_pw_len = dom_pw_info.out.info.min_password_length; + policy_min_pw_len = dom_pw_info.out.info->min_password_length; } newpass = samr_rand_pass(tctx, policy_min_pw_len); @@ -1594,6 +1662,8 @@ bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tct uint8_t old_nt_hash[16], new_nt_hash[16]; uint8_t old_lm_hash[16], new_lm_hash[16]; NTTIME t; + struct samr_DomInfo1 *dominfo = NULL; + struct samr_ChangeReject *reject = NULL; torture_comment(tctx, "Testing ChangePasswordUser3\n"); @@ -1641,6 +1711,8 @@ bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tct r.in.lm_password = &lm_pass; r.in.lm_verifier = &lm_verifier; r.in.password3 = NULL; + r.out.dominfo = &dominfo; + r.out.reject = &reject; status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r); if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) && @@ -1670,6 +1742,8 @@ bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tct r.in.lm_password = &lm_pass; r.in.lm_verifier = &lm_verifier; r.in.password3 = NULL; + r.out.dominfo = &dominfo; + r.out.reject = &reject; status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r); if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) && @@ -1712,21 +1786,23 @@ bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tct r.in.lm_password = &lm_pass; r.in.lm_verifier = &lm_verifier; r.in.password3 = NULL; + r.out.dominfo = &dominfo; + r.out.reject = &reject; unix_to_nt_time(&t, time(NULL)); status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r); if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) - && r.out.dominfo - && r.out.reject + && dominfo + && reject && handle_reject_reason - && (!null_nttime(last_password_change) || !r.out.dominfo->min_password_age)) { - if (r.out.dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) { + && (!null_nttime(last_password_change) || !dominfo->min_password_age)) { + if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) { - if (r.out.reject && (r.out.reject->reason != SAMR_REJECT_OTHER)) { + if (reject && (reject->reason != SAMR_REJECT_OTHER)) { printf("expected SAMR_REJECT_OTHER (%d), got %d\n", - SAMR_REJECT_OTHER, r.out.reject->reason); + SAMR_REJECT_OTHER, reject->reason); return false; } } @@ -1740,54 +1816,54 @@ bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tct Guenther */ - if ((r.out.dominfo->min_password_age > 0) && !null_nttime(last_password_change) && - (last_password_change + r.out.dominfo->min_password_age > t)) { + if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) && + (last_password_change + dominfo->min_password_age > t)) { - if (r.out.reject->reason != SAMR_REJECT_OTHER) { + if (reject->reason != SAMR_REJECT_OTHER) { printf("expected SAMR_REJECT_OTHER (%d), got %d\n", - SAMR_REJECT_OTHER, r.out.reject->reason); + SAMR_REJECT_OTHER, reject->reason); return false; } - } else if ((r.out.dominfo->min_password_length > 0) && - (strlen(newpass) < r.out.dominfo->min_password_length)) { + } else if ((dominfo->min_password_length > 0) && + (strlen(newpass) < dominfo->min_password_length)) { - if (r.out.reject->reason != SAMR_REJECT_TOO_SHORT) { + if (reject->reason != SAMR_REJECT_TOO_SHORT) { printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n", - SAMR_REJECT_TOO_SHORT, r.out.reject->reason); + SAMR_REJECT_TOO_SHORT, reject->reason); return false; } - } else if ((r.out.dominfo->password_history_length > 0) && + } else if ((dominfo->password_history_length > 0) && strequal(oldpass, newpass)) { - if (r.out.reject->reason != SAMR_REJECT_IN_HISTORY) { + if (reject->reason != SAMR_REJECT_IN_HISTORY) { printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n", - SAMR_REJECT_IN_HISTORY, r.out.reject->reason); + SAMR_REJECT_IN_HISTORY, reject->reason); return false; } - } else if (r.out.dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) { + } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) { - if (r.out.reject->reason != SAMR_REJECT_COMPLEXITY) { + if (reject->reason != SAMR_REJECT_COMPLEXITY) { printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n", - SAMR_REJECT_COMPLEXITY, r.out.reject->reason); + SAMR_REJECT_COMPLEXITY, reject->reason); return false; } } - if (r.out.reject->reason == SAMR_REJECT_TOO_SHORT) { + if (reject->reason == SAMR_REJECT_TOO_SHORT) { /* retry with adjusted size */ return test_ChangePasswordUser3(p, tctx, account_string, - r.out.dominfo->min_password_length, + dominfo->min_password_length, password, NULL, 0, false); } } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) { - if (r.out.reject && r.out.reject->reason != SAMR_REJECT_OTHER) { + if (reject && reject->reason != SAMR_REJECT_OTHER) { printf("expected SAMR_REJECT_OTHER (%d), got %d\n", - SAMR_REJECT_OTHER, r.out.reject->reason); + SAMR_REJECT_OTHER, reject->reason); return false; } /* Perhaps the server has a 'min password age' set? */ @@ -1823,6 +1899,8 @@ bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_contex char *oldpass; uint8_t old_nt_hash[16], new_nt_hash[16]; NTTIME t; + struct samr_DomInfo1 *dominfo = NULL; + struct samr_ChangeReject *reject = NULL; new_random_pass = samr_very_rand_pass(tctx, 128); @@ -1889,15 +1967,17 @@ bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_contex r.in.lm_password = NULL; r.in.lm_verifier = NULL; r.in.password3 = NULL; + r.out.dominfo = &dominfo; + r.out.reject = &reject; unix_to_nt_time(&t, time(NULL)); status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r); if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) { - if (r.out.reject && r.out.reject->reason != SAMR_REJECT_OTHER) { + if (reject && reject->reason != SAMR_REJECT_OTHER) { printf("expected SAMR_REJECT_OTHER (%d), got %d\n", - SAMR_REJECT_OTHER, r.out.reject->reason); + SAMR_REJECT_OTHER, reject->reason); return false; } /* Perhaps the server has a 'min password age' set? */ @@ -1925,15 +2005,17 @@ bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_contex r.in.lm_password = NULL; r.in.lm_verifier = NULL; r.in.password3 = NULL; + r.out.dominfo = &dominfo; + r.out.reject = &reject; unix_to_nt_time(&t, time(NULL)); status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r); if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) { - if (r.out.reject && r.out.reject->reason != SAMR_REJECT_OTHER) { + if (reject && reject->reason != SAMR_REJECT_OTHER) { printf("expected SAMR_REJECT_OTHER (%d), got %d\n", - SAMR_REJECT_OTHER, r.out.reject->reason); + SAMR_REJECT_OTHER, reject->reason); return false; } /* Perhaps the server has a 'min password age' set? */ @@ -2061,6 +2143,7 @@ static bool test_user_ops(struct dcerpc_pipe *p, { char *password = NULL; struct samr_QueryUserInfo q; + union samr_UserInfo *info; NTSTATUS status; bool ret = true; @@ -2176,6 +2259,7 @@ static bool test_user_ops(struct dcerpc_pipe *p, q.in.user_handle = user_handle; q.in.level = 5; + q.out.info = &info; status = dcerpc_samr_QueryUserInfo(p, tctx, &q); if (!NT_STATUS_IS_OK(status)) { @@ -2184,15 +2268,15 @@ static bool test_user_ops(struct dcerpc_pipe *p, ret = false; } else { uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED); - if ((q.out.info->info5.acct_flags) != expected_flags) { + if ((info->info5.acct_flags) != expected_flags) { printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n", - q.out.info->info5.acct_flags, + info->info5.acct_flags, expected_flags); ret = false; } - if (q.out.info->info5.rid != rid) { + if (info->info5.rid != rid) { printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n", - q.out.info->info5.rid, rid); + info->info5.rid, rid); } } @@ -2481,6 +2565,7 @@ static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, /* set samr_SetDomainInfo level 1 with min_length 5 */ { struct samr_QueryDomainInfo r; + union samr_DomainInfo *info = NULL; struct samr_SetDomainInfo s; uint16_t len_old, len; uint32_t pwd_prop_old; @@ -2491,6 +2576,7 @@ static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, r.in.domain_handle = domain_handle; r.in.level = 1; + r.out.info = &info; printf("testing samr_QueryDomainInfo level 1\n"); status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r); @@ -2500,7 +2586,7 @@ static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, s.in.domain_handle = domain_handle; s.in.level = 1; - s.in.info = r.out.info; + s.in.info = info; /* remember the old min length, so we can reset it */ len_old = s.in.info->info1.min_password_length; @@ -2540,13 +2626,17 @@ static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, NTSTATUS status; struct samr_OpenUser r; struct samr_QueryUserInfo q; + union samr_UserInfo *info; struct samr_LookupNames n; struct policy_handle user_handle; + struct samr_Ids rids, types; n.in.domain_handle = domain_handle; n.in.num_names = 1; n.in.names = talloc_array(mem_ctx, struct lsa_String, 1); n.in.names[0].string = acct_name; + n.out.rids = &rids; + n.out.types = &types; status = dcerpc_samr_LookupNames(p, mem_ctx, &n); if (!NT_STATUS_IS_OK(status)) { @@ -2556,17 +2646,18 @@ static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, r.in.domain_handle = domain_handle; r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - r.in.rid = n.out.rids.ids[0]; + r.in.rid = n.out.rids->ids[0]; r.out.user_handle = &user_handle; status = dcerpc_samr_OpenUser(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { - printf("OpenUser(%u) failed - %s\n", n.out.rids.ids[0], nt_errstr(status)); + printf("OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(status)); return false; } q.in.user_handle = &user_handle; q.in.level = 5; + q.out.info = &info; status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q); if (!NT_STATUS_IS_OK(status)) { @@ -2577,7 +2668,7 @@ static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, printf("calling test_ChangePasswordUser3 with too early password change\n"); if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, - q.out.info->info5.last_password_change, true)) { + info->info5.last_password_change, true)) { ret = false; } } @@ -2607,6 +2698,7 @@ static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx, NTSTATUS status; struct samr_CreateUser r; struct samr_QueryUserInfo q; + union samr_UserInfo *info; struct samr_DeleteUser d; uint32_t rid; @@ -2654,6 +2746,7 @@ static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx, } else { q.in.user_handle = &user_handle; q.in.level = 16; + q.out.info = &info; status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q); if (!NT_STATUS_IS_OK(status)) { @@ -2661,9 +2754,9 @@ static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx, q.in.level, nt_errstr(status)); ret = false; } else { - if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) { + if ((info->info16.acct_flags & acct_flags) != acct_flags) { printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n", - q.out.info->info16.acct_flags, + info->info16.acct_flags, acct_flags); ret = false; } @@ -2705,6 +2798,7 @@ static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx NTSTATUS status; struct samr_CreateUser2 r; struct samr_QueryUserInfo q; + union samr_UserInfo *info; struct samr_DeleteUser d; struct policy_handle user_handle; uint32_t rid; @@ -2783,6 +2877,7 @@ static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx if (NT_STATUS_IS_OK(status)) { q.in.user_handle = &user_handle; q.in.level = 5; + q.out.info = &info; status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q); if (!NT_STATUS_IS_OK(status)) { @@ -2794,31 +2889,31 @@ static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx if (acct_flags == ACB_NORMAL) { expected_flags |= ACB_PW_EXPIRED; } - if ((q.out.info->info5.acct_flags) != expected_flags) { + if ((info->info5.acct_flags) != expected_flags) { printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n", - q.out.info->info5.acct_flags, + info->info5.acct_flags, expected_flags); ret = false; } switch (acct_flags) { case ACB_SVRTRUST: - if (q.out.info->info5.primary_gid != DOMAIN_RID_DCS) { + if (info->info5.primary_gid != DOMAIN_RID_DCS) { printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n", - DOMAIN_RID_DCS, q.out.info->info5.primary_gid); + DOMAIN_RID_DCS, info->info5.primary_gid); ret = false; } break; case ACB_WSTRUST: - if (q.out.info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) { + if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) { printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n", - DOMAIN_RID_DOMAIN_MEMBERS, q.out.info->info5.primary_gid); + DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid); ret = false; } break; case ACB_NORMAL: - if (q.out.info->info5.primary_gid != DOMAIN_RID_USERS) { + if (info->info5.primary_gid != DOMAIN_RID_USERS) { printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n", - DOMAIN_RID_USERS, q.out.info->info5.primary_gid); + DOMAIN_RID_USERS, info->info5.primary_gid); ret = false; } break; @@ -2852,6 +2947,7 @@ static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, { NTSTATUS status; struct samr_QueryAliasInfo r; + union samr_AliasInfo *info; uint16_t levels[] = {1, 2, 3}; int i; bool ret = true; @@ -2861,6 +2957,7 @@ static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, r.in.alias_handle = handle; r.in.level = levels[i]; + r.out.info = &info; status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { @@ -2878,6 +2975,7 @@ static bool test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, { NTSTATUS status; struct samr_QueryGroupInfo r; + union samr_GroupInfo *info; uint16_t levels[] = {1, 2, 3, 4, 5}; int i; bool ret = true; @@ -2887,6 +2985,7 @@ static bool test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, r.in.group_handle = handle; r.in.level = levels[i]; + r.out.info = &info; status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { @@ -2904,11 +3003,13 @@ static bool test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, { NTSTATUS status; struct samr_QueryGroupMember r; + struct samr_RidTypeArray *rids = NULL; bool ret = true; printf("Testing QueryGroupMember\n"); r.in.group_handle = handle; + r.out.rids = &rids; status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { @@ -2925,6 +3026,7 @@ static bool test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, { NTSTATUS status; struct samr_QueryGroupInfo r; + union samr_GroupInfo *info; struct samr_SetGroupInfo s; uint16_t levels[] = {1, 2, 3, 4}; uint16_t set_ok[] = {0, 1, 1, 1}; @@ -2936,6 +3038,7 @@ static bool test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, r.in.group_handle = handle; r.in.level = levels[i]; + r.out.info = &info; status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { @@ -2948,7 +3051,7 @@ static bool test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, s.in.group_handle = handle; s.in.level = levels[i]; - s.in.info = r.out.info; + s.in.info = *r.out.info; #if 0 /* disabled this, as it changes the name only from the point of view of samr, @@ -2990,6 +3093,7 @@ static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, { NTSTATUS status; struct samr_QueryUserInfo r; + union samr_UserInfo *info; uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 20, 21}; int i; @@ -3000,6 +3104,7 @@ static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, r.in.user_handle = handle; r.in.level = levels[i]; + r.out.info = &info; status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { @@ -3017,6 +3122,7 @@ static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, { NTSTATUS status; struct samr_QueryUserInfo2 r; + union samr_UserInfo *info; uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 20, 21}; int i; @@ -3027,6 +3133,7 @@ static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, r.in.user_handle = handle; r.in.level = levels[i]; + r.out.info = &info; status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { @@ -3174,6 +3281,7 @@ static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx, NTSTATUS status; struct samr_OpenUser r; struct samr_QueryUserInfo q; + union samr_UserInfo *info; struct policy_handle user_handle; bool ret = true; @@ -3192,6 +3300,7 @@ static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx, q.in.user_handle = &user_handle; q.in.level = 16; + q.out.info = &info; status = dcerpc_samr_QueryUserInfo(p, tctx, &q); if (!NT_STATUS_IS_OK(status)) { @@ -3199,9 +3308,9 @@ static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx, nt_errstr(status)); ret = false; } else { - if ((acct_flag_mask & q.out.info->info16.acct_flags) == 0) { + if ((acct_flag_mask & info->info16.acct_flags) == 0) { printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n", - acct_flag_mask, q.out.info->info16.acct_flags, rid); + acct_flag_mask, info->info16.acct_flags, rid); ret = false; } } @@ -3223,6 +3332,11 @@ static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context * bool ret = true; struct samr_LookupNames n; struct samr_LookupRids lr ; + struct lsa_Strings names; + struct samr_Ids rids, types; + struct samr_SamArray *sam = NULL; + uint32_t num_entries = 0; + uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST, ACB_DISABLED, ACB_NORMAL | ACB_DISABLED, ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST, @@ -3236,6 +3350,8 @@ static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context * r.in.acct_flags = mask = masks[mask_idx]; r.in.max_size = (uint32_t)-1; r.out.resume_handle = &resume_handle; + r.out.num_entries = &num_entries; + r.out.sam = &sam; status = dcerpc_samr_EnumDomainUsers(p, tctx, &r); if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && @@ -3244,18 +3360,18 @@ static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context * return false; } - torture_assert(tctx, r.out.sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL"); + torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL"); - if (r.out.sam->count == 0) { + if (sam->count == 0) { continue; } - for (i=0;i<r.out.sam->count;i++) { + for (i=0;i<sam->count;i++) { if (mask) { - if (!check_mask(p, tctx, handle, r.out.sam->entries[i].idx, mask)) { + if (!check_mask(p, tctx, handle, sam->entries[i].idx, mask)) { ret = false; } - } else if (!test_OpenUser(p, tctx, handle, r.out.sam->entries[i].idx)) { + } else if (!test_OpenUser(p, tctx, handle, sam->entries[i].idx)) { ret = false; } } @@ -3263,10 +3379,12 @@ static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context * printf("Testing LookupNames\n"); n.in.domain_handle = handle; - n.in.num_names = r.out.sam->count; - n.in.names = talloc_array(tctx, struct lsa_String, r.out.sam->count); - for (i=0;i<r.out.sam->count;i++) { - n.in.names[i].string = r.out.sam->entries[i].name.string; + n.in.num_names = sam->count; + n.in.names = talloc_array(tctx, struct lsa_String, sam->count); + n.out.rids = &rids; + n.out.types = &types; + for (i=0;i<sam->count;i++) { + n.in.names[i].string = sam->entries[i].name.string; } status = dcerpc_samr_LookupNames(p, tctx, &n); if (!NT_STATUS_IS_OK(status)) { @@ -3277,10 +3395,12 @@ static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context * printf("Testing LookupRids\n"); lr.in.domain_handle = handle; - lr.in.num_rids = r.out.sam->count; - lr.in.rids = talloc_array(tctx, uint32_t, r.out.sam->count); - for (i=0;i<r.out.sam->count;i++) { - lr.in.rids[i] = r.out.sam->entries[i].idx; + lr.in.num_rids = sam->count; + lr.in.rids = talloc_array(tctx, uint32_t, sam->count); + lr.out.names = &names; + lr.out.types = &types; + for (i=0;i<sam->count;i++) { + lr.in.rids[i] = sam->entries[i].idx; } status = dcerpc_samr_LookupRids(p, tctx, &lr); torture_assert_ntstatus_ok(tctx, status, "LookupRids"); @@ -3337,6 +3457,8 @@ static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, NTSTATUS status; struct samr_EnumDomainGroups r; uint32_t resume_handle=0; + struct samr_SamArray *sam = NULL; + uint32_t num_entries = 0; int i; bool ret = true; @@ -3346,6 +3468,8 @@ static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, r.in.resume_handle = &resume_handle; r.in.max_size = (uint32_t)-1; r.out.resume_handle = &resume_handle; + r.out.num_entries = &num_entries; + r.out.sam = &sam; status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { @@ -3353,12 +3477,12 @@ static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, return false; } - if (!r.out.sam) { + if (!sam) { return false; } - for (i=0;i<r.out.sam->count;i++) { - if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) { + for (i=0;i<sam->count;i++) { + if (!test_OpenGroup(p, mem_ctx, handle, sam->entries[i].idx)) { ret = false; } } @@ -3372,6 +3496,8 @@ static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, NTSTATUS status; struct samr_EnumDomainAliases r; uint32_t resume_handle=0; + struct samr_SamArray *sam = NULL; + uint32_t num_entries = 0; int i; bool ret = true; @@ -3379,7 +3505,9 @@ static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, r.in.domain_handle = handle; r.in.resume_handle = &resume_handle; - r.in.acct_flags = (uint32_t)-1; + r.in.max_size = (uint32_t)-1; + r.out.sam = &sam; + r.out.num_entries = &num_entries; r.out.resume_handle = &resume_handle; status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r); @@ -3388,12 +3516,12 @@ static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, return false; } - if (!r.out.sam) { + if (!sam) { return false; } - for (i=0;i<r.out.sam->count;i++) { - if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) { + for (i=0;i<sam->count;i++) { + if (!test_OpenAlias(p, mem_ctx, handle, sam->entries[i].idx)) { ret = false; } } @@ -3409,14 +3537,19 @@ static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *m bool ret = true; uint16_t levels[] = {1, 2, 3, 4, 5}; uint16_t ok_lvl[] = {1, 1, 1, 0, 0}; + struct lsa_String name; + uint32_t idx = 0; int i; for (i=0;i<ARRAY_SIZE(levels);i++) { printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]); + init_lsa_String(&name, TEST_ACCOUNT_NAME); + r.in.domain_handle = handle; r.in.level = levels[i]; - init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME); + r.in.name = &name; + r.out.idx = &idx; status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r); @@ -3428,7 +3561,7 @@ static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *m ret = false; } - init_lsa_String(&r.in.name, "zzzzzzzz"); + init_lsa_String(&name, "zzzzzzzz"); status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r); @@ -3450,14 +3583,19 @@ static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX * bool ret = true; uint16_t levels[] = {1, 2, 3, 4, 5}; uint16_t ok_lvl[] = {1, 1, 1, 0, 0}; + struct lsa_String name; + uint32_t idx = 0; int i; for (i=0;i<ARRAY_SIZE(levels);i++) { printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]); + init_lsa_String(&name, TEST_ACCOUNT_NAME); + r.in.domain_handle = handle; r.in.level = levels[i]; - init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME); + r.in.name = &name; + r.out.idx = &idx; status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r); if (ok_lvl[i] && @@ -3468,7 +3606,7 @@ static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX * ret = false; } - init_lsa_String(&r.in.name, "zzzzzzzz"); + init_lsa_String(&name, "zzzzzzzz"); status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r); if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) { @@ -3502,6 +3640,7 @@ static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ct { struct samr_OpenUser r; struct samr_QueryUserInfo q; + union samr_UserInfo *info; struct policy_handle user_handle; int i, ret = true; NTSTATUS status; @@ -3510,16 +3649,16 @@ static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ct for (i = 0; ; i++) { switch (querydisplayinfo->in.level) { case 1: - if (i >= querydisplayinfo->out.info.info1.count) { + if (i >= querydisplayinfo->out.info->info1.count) { return ret; } - r.in.rid = querydisplayinfo->out.info.info1.entries[i].rid; + r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid; break; case 2: - if (i >= querydisplayinfo->out.info.info2.count) { + if (i >= querydisplayinfo->out.info->info2.count) { return ret; } - r.in.rid = querydisplayinfo->out.info.info2.entries[i].rid; + r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid; break; case 3: /* Groups */ @@ -3543,6 +3682,7 @@ static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ct q.in.user_handle = &user_handle; q.in.level = 21; + q.out.info = &info; status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q); if (!NT_STATUS_IS_OK(status)) { printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status)); @@ -3551,41 +3691,41 @@ static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ct switch (querydisplayinfo->in.level) { case 1: - if (seen_testuser && strcmp(q.out.info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) { + if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) { *seen_testuser = true; } - STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].full_name, - q.out.info->info21.full_name, q.out.info->info21.account_name); - STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].account_name, - q.out.info->info21.account_name, q.out.info->info21.account_name); - STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].description, - q.out.info->info21.description, q.out.info->info21.account_name); - INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].rid, - q.out.info->info21.rid, q.out.info->info21.account_name); - INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].acct_flags, - q.out.info->info21.acct_flags, q.out.info->info21.account_name); + STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name, + info->info21.full_name, info->info21.account_name); + STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name, + info->info21.account_name, info->info21.account_name); + STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description, + info->info21.description, info->info21.account_name); + INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid, + info->info21.rid, info->info21.account_name); + INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags, + info->info21.acct_flags, info->info21.account_name); break; case 2: - STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].account_name, - q.out.info->info21.account_name, q.out.info->info21.account_name); - STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].description, - q.out.info->info21.description, q.out.info->info21.account_name); - INT_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].rid, - q.out.info->info21.rid, q.out.info->info21.account_name); - INT_EQUAL_QUERY((querydisplayinfo->out.info.info2.entries[i].acct_flags & ~ACB_NORMAL), - q.out.info->info21.acct_flags, q.out.info->info21.account_name); + STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name, + info->info21.account_name, info->info21.account_name); + STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description, + info->info21.description, info->info21.account_name); + INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid, + info->info21.rid, info->info21.account_name); + INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL), + info->info21.acct_flags, info->info21.account_name); - if (!(querydisplayinfo->out.info.info2.entries[i].acct_flags & ACB_NORMAL)) { + if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) { printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n", - q.out.info->info21.account_name.string); + info->info21.account_name.string); } - if (!(q.out.info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) { + if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) { printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n", - q.out.info->info21.account_name.string, - querydisplayinfo->out.info.info2.entries[i].acct_flags, - q.out.info->info21.acct_flags); + info->info21.account_name.string, + querydisplayinfo->out.info->info2.entries[i].acct_flags, + info->info21.acct_flags); return false; } @@ -3605,10 +3745,15 @@ static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, NTSTATUS status; struct samr_QueryDisplayInfo r; struct samr_QueryDomainInfo dom_info; + union samr_DomainInfo *info = NULL; bool ret = true; uint16_t levels[] = {1, 2, 3, 4, 5}; int i; bool seen_testuser = false; + uint32_t total_size; + uint32_t returned_size; + union samr_DispInfo disp_info; + for (i=0;i<ARRAY_SIZE(levels);i++) { printf("Testing QueryDisplayInfo level %u\n", levels[i]); @@ -3620,6 +3765,9 @@ static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, r.in.level = levels[i]; r.in.max_entries = 2; r.in.buf_size = (uint32_t)-1; + r.out.total_size = &total_size; + r.out.returned_size = &returned_size; + r.out.info = &disp_info; status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r); if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) { @@ -3632,27 +3780,29 @@ static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, if (!test_each_DisplayInfo_user(p, mem_ctx, &r, &seen_testuser)) { ret = false; } - r.in.start_idx += r.out.info.info1.count; + r.in.start_idx += r.out.info->info1.count; break; case 2: if (!test_each_DisplayInfo_user(p, mem_ctx, &r, NULL)) { ret = false; } - r.in.start_idx += r.out.info.info2.count; + r.in.start_idx += r.out.info->info2.count; break; case 3: - r.in.start_idx += r.out.info.info3.count; + r.in.start_idx += r.out.info->info3.count; break; case 4: - r.in.start_idx += r.out.info.info4.count; + r.in.start_idx += r.out.info->info4.count; break; case 5: - r.in.start_idx += r.out.info.info5.count; + r.in.start_idx += r.out.info->info5.count; break; } } dom_info.in.domain_handle = handle; dom_info.in.level = 2; + dom_info.out.info = &info; + /* Check number of users returned is correct */ status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &dom_info); if (!NT_STATUS_IS_OK(status)) { @@ -3664,17 +3814,17 @@ static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, switch (r.in.level) { case 1: case 4: - if (dom_info.out.info->general.num_users < r.in.start_idx) { + if (info->general.num_users < r.in.start_idx) { printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n", - r.in.start_idx, dom_info.out.info->general.num_groups, - dom_info.out.info->general.domain_name.string); + r.in.start_idx, info->general.num_groups, + info->general.domain_name.string); ret = false; } if (!seen_testuser) { struct policy_handle user_handle; if (NT_STATUS_IS_OK(test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle))) { printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n", - dom_info.out.info->general.domain_name.string); + info->general.domain_name.string); ret = false; test_samr_handle_Close(p, mem_ctx, &user_handle); } @@ -3682,10 +3832,10 @@ static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, break; case 3: case 5: - if (dom_info.out.info->general.num_groups != r.in.start_idx) { + if (info->general.num_groups != r.in.start_idx) { printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n", - r.in.start_idx, dom_info.out.info->general.num_groups, - dom_info.out.info->general.domain_name.string); + r.in.start_idx, info->general.num_groups, + info->general.domain_name.string); ret = false; } @@ -3705,6 +3855,9 @@ static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, bool ret = true; uint16_t levels[] = {1, 2, 3, 4, 5}; int i; + uint32_t total_size; + uint32_t returned_size; + union samr_DispInfo info; for (i=0;i<ARRAY_SIZE(levels);i++) { printf("Testing QueryDisplayInfo2 level %u\n", levels[i]); @@ -3714,6 +3867,9 @@ static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, r.in.start_idx = 0; r.in.max_entries = 1000; r.in.buf_size = (uint32_t)-1; + r.out.total_size = &total_size; + r.out.returned_size = &returned_size; + r.out.info = &info; status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { @@ -3734,6 +3890,9 @@ static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context bool ret = true; uint16_t levels[] = {1, 2, 3, 4, 5}; int i; + uint32_t total_size; + uint32_t returned_size; + union samr_DispInfo info; for (i=0;i<ARRAY_SIZE(levels);i++) { torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]); @@ -3743,6 +3902,9 @@ static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context r.in.start_idx = 0; r.in.max_entries = 1000; r.in.buf_size = (uint32_t)-1; + r.out.total_size = &total_size; + r.out.returned_size = &returned_size; + r.out.info = &info; status = dcerpc_samr_QueryDisplayInfo3(p, tctx, &r); if (!NT_STATUS_IS_OK(status)) { @@ -3762,6 +3924,9 @@ static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *me NTSTATUS status; struct samr_QueryDisplayInfo r; bool ret = true; + uint32_t total_size; + uint32_t returned_size; + union samr_DispInfo info; printf("Testing QueryDisplayInfo continuation\n"); @@ -3770,14 +3935,17 @@ static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *me r.in.start_idx = 0; r.in.max_entries = 1; r.in.buf_size = (uint32_t)-1; + r.out.total_size = &total_size; + r.out.returned_size = &returned_size; + r.out.info = &info; do { status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r); - if (NT_STATUS_IS_OK(status) && r.out.returned_size != 0) { - if (r.out.info.info1.entries[0].idx != r.in.start_idx + 1) { + if (NT_STATUS_IS_OK(status) && *r.out.returned_size != 0) { + if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) { printf("expected idx %d but got %d\n", r.in.start_idx + 1, - r.out.info.info1.entries[0].idx); + r.out.info->info1.entries[0].idx); break; } } @@ -3791,7 +3959,7 @@ static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *me r.in.start_idx++; } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) || NT_STATUS_IS_OK(status)) && - r.out.returned_size != 0); + *r.out.returned_size != 0); return ret; } @@ -3801,6 +3969,7 @@ static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context * { NTSTATUS status; struct samr_QueryDomainInfo r; + union samr_DomainInfo *info = NULL; struct samr_SetDomainInfo s; uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13}; uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0}; @@ -3827,6 +3996,7 @@ static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context * r.in.domain_handle = handle; r.in.level = levels[i]; + r.out.info = &info; status = dcerpc_samr_QueryDomainInfo(p, tctx, &r); if (!NT_STATUS_IS_OK(status)) { @@ -3838,40 +4008,40 @@ static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context * switch (levels[i]) { case 2: - if (strcmp(r.out.info->general.oem_information.string, domain_comment) != 0) { + 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], r.out.info->general.oem_information.string, domain_comment); + levels[i], info->general.oem_information.string, domain_comment); ret = false; } - if (!r.out.info->general.primary.string) { + if (!info->general.primary.string) { printf("QueryDomainInfo level %u returned no PDC name\n", levels[i]); ret = false; - } else if (r.out.info->general.role == SAMR_ROLE_DOMAIN_PDC) { - if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), r.out.info->general.primary.string) != 0) { + } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) { + if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) { printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n", - levels[i], r.out.info->general.primary.string, dcerpc_server_name(p)); + levels[i], info->general.primary.string, dcerpc_server_name(p)); } } break; case 4: - if (strcmp(r.out.info->oem.oem_information.string, domain_comment) != 0) { + 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], r.out.info->oem.oem_information.string, domain_comment); + levels[i], info->oem.oem_information.string, domain_comment); ret = false; } break; case 6: - if (!r.out.info->info6.primary.string) { + if (!info->info6.primary.string) { printf("QueryDomainInfo level %u returned no PDC name\n", levels[i]); ret = false; } break; case 11: - if (strcmp(r.out.info->general2.general.oem_information.string, domain_comment) != 0) { + if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) { printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n", - levels[i], r.out.info->general2.general.oem_information.string, domain_comment); + levels[i], info->general2.general.oem_information.string, domain_comment); ret = false; } break; @@ -3881,7 +4051,7 @@ static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context * s.in.domain_handle = handle; s.in.level = levels[i]; - s.in.info = r.out.info; + s.in.info = info; status = dcerpc_samr_SetDomainInfo(p, tctx, &s); if (set_ok[i]) { @@ -3918,6 +4088,7 @@ static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context { NTSTATUS status; struct samr_QueryDomainInfo2 r; + union samr_DomainInfo *info = NULL; uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13}; int i; bool ret = true; @@ -3927,6 +4098,7 @@ static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context r.in.domain_handle = handle; r.in.level = levels[i]; + r.out.info = &info; status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r); if (!NT_STATUS_IS_OK(status)) { @@ -3949,8 +4121,13 @@ static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx, struct samr_QueryDisplayInfo q2; NTSTATUS status; uint32_t resume_handle=0; + struct samr_SamArray *sam = NULL; + uint32_t num_entries = 0; int i; bool ret = true; + uint32_t total_size; + uint32_t returned_size; + union samr_DispInfo info; int num_names = 0; const char **names = NULL; @@ -3961,6 +4138,8 @@ static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx, q1.in.resume_handle = &resume_handle; q1.in.max_size = 5; q1.out.resume_handle = &resume_handle; + q1.out.num_entries = &num_entries; + q1.out.sam = &sam; status = STATUS_MORE_ENTRIES; while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) { @@ -3970,22 +4149,25 @@ static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx, !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) break; - for (i=0; i<q1.out.num_entries; i++) { + for (i=0; i<*q1.out.num_entries; i++) { add_string_to_array(tctx, - q1.out.sam->entries[i].name.string, + sam->entries[i].name.string, &names, &num_names); } } torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups"); - torture_assert(tctx, q1.out.sam, "EnumDomainGroups failed to return q1.out.sam"); + torture_assert(tctx, sam, "EnumDomainGroups failed to return sam"); q2.in.domain_handle = handle; q2.in.level = 5; q2.in.start_idx = 0; q2.in.max_entries = 5; q2.in.buf_size = (uint32_t)-1; + q2.out.total_size = &total_size; + q2.out.returned_size = &returned_size; + q2.out.info = &info; status = STATUS_MORE_ENTRIES; while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) { @@ -3995,9 +4177,9 @@ static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx, !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) break; - for (i=0; i<q2.out.info.info5.count; i++) { + for (i=0; i<q2.out.info->info5.count; i++) { int j; - const char *name = q2.out.info.info5.entries[i].account_name.string; + const char *name = q2.out.info->info5.entries[i].account_name.string; bool found = false; for (j=0; j<num_names; j++) { if (names[j] == NULL) @@ -4015,7 +4197,7 @@ static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx, ret = false; } } - q2.in.start_idx += q2.out.info.info5.count; + q2.in.start_idx += q2.out.info->info5.count; } if (!NT_STATUS_IS_OK(status)) { @@ -4076,7 +4258,7 @@ static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx, struct samr_RidToSid r; NTSTATUS status; bool ret = true; - struct dom_sid *calc_sid; + struct dom_sid *calc_sid, *out_sid; int rids[] = { 0, 42, 512, 10200 }; int i; @@ -4086,6 +4268,7 @@ static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx, calc_sid = dom_sid_dup(tctx, domain_sid); r.in.domain_handle = domain_handle; r.in.rid = rids[i]; + r.out.sid = &out_sid; status = dcerpc_samr_RidToSid(p, tctx, &r); if (!NT_STATUS_IS_OK(status)) { @@ -4094,9 +4277,9 @@ static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx, } else { calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]); - if (!dom_sid_equal(calc_sid, r.out.sid)) { + if (!dom_sid_equal(calc_sid, out_sid)) { printf("RidToSid for %d failed - got %s, expected %s\n", rids[i], - dom_sid_string(tctx, r.out.sid), + dom_sid_string(tctx, out_sid), dom_sid_string(tctx, calc_sid)); ret = false; } @@ -4112,10 +4295,12 @@ static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, struct torture_con struct samr_GetBootKeyInformation r; NTSTATUS status; bool ret = true; + uint32_t unknown = 0; torture_comment(tctx, "Testing GetBootKeyInformation\n"); r.in.domain_handle = domain_handle; + r.out.unknown = &unknown; status = dcerpc_samr_GetBootKeyInformation(p, tctx, &r); if (!NT_STATUS_IS_OK(status)) { @@ -4134,6 +4319,7 @@ static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *t struct samr_AddGroupMember r; struct samr_DeleteGroupMember d; struct samr_QueryGroupMember q; + struct samr_RidTypeArray *rids = NULL; struct samr_SetMemberAttributesOfGroup s; uint32_t rid; @@ -4173,6 +4359,7 @@ static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *t } q.in.group_handle = group_handle; + q.out.rids = &rids; status = dcerpc_samr_QueryGroupMember(p, tctx, &q); torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember"); @@ -4388,6 +4575,7 @@ static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tct { NTSTATUS status; struct samr_LookupDomain r; + struct dom_sid2 *sid = NULL; struct lsa_String n1; struct lsa_String n2; bool ret = true; @@ -4397,6 +4585,7 @@ static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tct /* check for correct error codes */ r.in.connect_handle = handle; r.in.domain_name = &n2; + r.out.sid = &sid; n2.string = NULL; status = dcerpc_samr_LookupDomain(p, tctx, &r); @@ -4419,7 +4608,7 @@ static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tct ret = false; } - if (!test_OpenDomain(p, tctx, handle, r.out.sid, which_ops)) { + if (!test_OpenDomain(p, tctx, handle, *r.out.sid, which_ops)) { ret = false; } @@ -4433,6 +4622,8 @@ static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx NTSTATUS status; struct samr_EnumDomains r; uint32_t resume_handle = 0; + uint32_t num_entries = 0; + struct samr_SamArray *sam = NULL; int i; bool ret = true; @@ -4440,17 +4631,19 @@ static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx r.in.resume_handle = &resume_handle; r.in.buf_size = (uint32_t)-1; r.out.resume_handle = &resume_handle; + r.out.num_entries = &num_entries; + r.out.sam = &sam; status = dcerpc_samr_EnumDomains(p, tctx, &r); torture_assert_ntstatus_ok(tctx, status, "EnumDomains"); - if (!r.out.sam) { + if (!*r.out.sam) { return false; } - for (i=0;i<r.out.sam->count;i++) { + for (i=0;i<sam->count;i++) { if (!test_LookupDomain(p, tctx, handle, - r.out.sam->entries[i].name.string, which_ops)) { + sam->entries[i].name.string, which_ops)) { ret = false; } } @@ -4473,6 +4666,7 @@ static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx, struct samr_Connect5 r5; union samr_ConnectInfo info; struct policy_handle h; + uint32_t level_out = 0; bool ret = true, got_handle = false; torture_comment(tctx, "testing samr_Connect\n"); @@ -4553,9 +4747,10 @@ static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx, r5.in.system_name = ""; r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - r5.in.level = 1; - r5.in.info = &info; - r5.out.info = &info; + r5.in.level_in = 1; + r5.out.level_out = &level_out; + r5.in.info_in = &info; + r5.out.info_out = &info; r5.out.connect_handle = &h; status = dcerpc_samr_Connect5(p, tctx, &r5); diff --git a/source4/torture/rpc/samr_accessmask.c b/source4/torture/rpc/samr_accessmask.c index bfff8c9267..9a8e442019 100644 --- a/source4/torture/rpc/samr_accessmask.c +++ b/source4/torture/rpc/samr_accessmask.c @@ -52,13 +52,15 @@ static NTSTATUS torture_samr_Connect5(struct torture_context *tctx, NTSTATUS status; struct samr_Connect5 r5; union samr_ConnectInfo info; + uint32_t level_out = 0; info.info1.client_version = 0; info.info1.unknown2 = 0; r5.in.system_name = ""; - r5.in.level = 1; - r5.in.info = &info; - r5.out.info = &info; + r5.in.level_in = 1; + r5.in.info_in = &info; + r5.out.info_out = &info; + r5.out.level_out = &level_out; r5.out.connect_handle = h; r5.in.access_mask = mask; @@ -147,6 +149,8 @@ static bool test_samr_accessmask_EnumDomains(struct torture_context *tctx, int i; uint32_t mask; uint32_t resume_handle = 0; + struct samr_SamArray *sam = NULL; + uint32_t num_entries = 0; printf("testing which bits in Connect5 accessmask allows us to EnumDomains\n"); mask = 1; @@ -170,6 +174,8 @@ static bool test_samr_accessmask_EnumDomains(struct torture_context *tctx, ed.in.resume_handle = &resume_handle; ed.in.buf_size = (uint32_t)-1; ed.out.resume_handle = &resume_handle; + ed.out.num_entries = &num_entries; + ed.out.sam = &sam; status = dcerpc_samr_EnumDomains(p, tctx, &ed); if (!NT_STATUS_IS_OK(status)) { @@ -195,6 +201,8 @@ static bool test_samr_accessmask_EnumDomains(struct torture_context *tctx, ed.in.resume_handle = &resume_handle; ed.in.buf_size = (uint32_t)-1; ed.out.resume_handle = &resume_handle; + ed.out.num_entries = &num_entries; + ed.out.sam = &sam; status = dcerpc_samr_EnumDomains(p, tctx, &ed); if(!NT_STATUS_EQUAL(NT_STATUS_ACCESS_DENIED, status)) { @@ -236,7 +244,7 @@ static bool test_samr_connect_user_acl(struct torture_context *tctx, struct samr_SetSecurity ss; struct security_ace ace; struct security_descriptor *sd; - struct sec_desc_buf sdb; + struct sec_desc_buf sdb, *sdbuf = NULL; bool ret = true; int sd_size; struct dcerpc_pipe *test_p; @@ -255,6 +263,7 @@ static bool test_samr_connect_user_acl(struct torture_context *tctx, /* get the current ACL for the SAMR policy handle */ qs.in.handle = &ch; qs.in.sec_info = SECINFO_DACL; + qs.out.sdbuf = &sdbuf; status = dcerpc_samr_QuerySecurity(p, tctx, &qs); if (!NT_STATUS_IS_OK(status)) { printf("QuerySecurity failed - %s\n", nt_errstr(status)); @@ -262,13 +271,13 @@ static bool test_samr_connect_user_acl(struct torture_context *tctx, } /* how big is the security descriptor? */ - sd_size = qs.out.sdbuf->sd_size; + sd_size = sdbuf->sd_size; /* add an ACE to the security descriptor to deny the user the * 'connect to server' right */ - sd = qs.out.sdbuf->sd; + sd = sdbuf->sd; ace.type = SEC_ACE_TYPE_ACCESS_DENIED; ace.flags = 0; ace.access_mask = SAMR_ACCESS_CONNECT_TO_SERVER; @@ -314,7 +323,7 @@ static bool test_samr_connect_user_acl(struct torture_context *tctx, printf("QuerySecurity failed - %s\n", nt_errstr(status)); ret = false; } - if (sd_size != qs.out.sdbuf->sd_size) { + if (sd_size != sdbuf->sd_size) { printf("security descriptor changed\n"); ret = false; } @@ -387,6 +396,7 @@ static bool test_samr_accessmask_LookupDomain(struct torture_context *tctx, { NTSTATUS status; struct samr_LookupDomain ld; + struct dom_sid2 *sid = NULL; struct policy_handle ch; struct lsa_String dn; int i; @@ -412,6 +422,7 @@ static bool test_samr_accessmask_LookupDomain(struct torture_context *tctx, ld.in.connect_handle = &ch; ld.in.domain_name = &dn; + ld.out.sid = &sid; dn.string = lp_workgroup(tctx->lp_ctx); status = dcerpc_samr_LookupDomain(p, tctx, &ld); @@ -471,6 +482,7 @@ static bool test_samr_accessmask_OpenDomain(struct torture_context *tctx, { NTSTATUS status; struct samr_LookupDomain ld; + struct dom_sid2 *sid = NULL; struct samr_OpenDomain od; struct policy_handle ch; struct policy_handle dh; @@ -488,6 +500,7 @@ static bool test_samr_accessmask_OpenDomain(struct torture_context *tctx, ld.in.connect_handle = &ch; ld.in.domain_name = &dn; + ld.out.sid = &sid; dn.string = lp_workgroup(tctx->lp_ctx); status = dcerpc_samr_LookupDomain(p, tctx, &ld); if (!NT_STATUS_IS_OK(status)) { @@ -517,7 +530,7 @@ static bool test_samr_accessmask_OpenDomain(struct torture_context *tctx, od.in.connect_handle = &ch; od.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - od.in.sid = ld.out.sid; + od.in.sid = *ld.out.sid; od.out.domain_handle = &dh; status = dcerpc_samr_OpenDomain(p, tctx, &od); diff --git a/source4/torture/rpc/samsync.c b/source4/torture/rpc/samsync.c index 12ddc934c9..a3fc6f740f 100644 --- a/source4/torture/rpc/samsync.c +++ b/source4/torture/rpc/samsync.c @@ -151,17 +151,19 @@ struct samsync_trusted_domain { static struct policy_handle *samsync_open_domain(TALLOC_CTX *mem_ctx, struct samsync_state *samsync_state, const char *domain, - struct dom_sid **sid) + struct dom_sid **sid_p) { struct lsa_String name; struct samr_OpenDomain o; struct samr_LookupDomain l; + struct dom_sid2 *sid = NULL; struct policy_handle *domain_handle = talloc(mem_ctx, struct policy_handle); NTSTATUS nt_status; name.string = domain; l.in.connect_handle = samsync_state->connect_handle; l.in.domain_name = &name; + l.out.sid = &sid; nt_status = dcerpc_samr_LookupDomain(samsync_state->p_samr, mem_ctx, &l); if (!NT_STATUS_IS_OK(nt_status)) { @@ -171,11 +173,11 @@ static struct policy_handle *samsync_open_domain(TALLOC_CTX *mem_ctx, o.in.connect_handle = samsync_state->connect_handle; o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - o.in.sid = l.out.sid; + o.in.sid = *l.out.sid; o.out.domain_handle = domain_handle; if (sid) { - *sid = l.out.sid; + *sid_p = *l.out.sid; } nt_status = dcerpc_samr_OpenDomain(samsync_state->p_samr, mem_ctx, &o); @@ -192,10 +194,12 @@ static struct sec_desc_buf *samsync_query_samr_sec_desc(TALLOC_CTX *mem_ctx, struct policy_handle *handle) { struct samr_QuerySecurity r; + struct sec_desc_buf *sdbuf = NULL; NTSTATUS status; r.in.handle = handle; r.in.sec_info = 0x7; + r.out.sdbuf = &sdbuf; status = dcerpc_samr_QuerySecurity(samsync_state->p_samr, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { @@ -203,7 +207,7 @@ static struct sec_desc_buf *samsync_query_samr_sec_desc(TALLOC_CTX *mem_ctx, return NULL; } - return r.out.sdbuf; + return sdbuf; } static struct sec_desc_buf *samsync_query_lsa_sec_desc(TALLOC_CTX *mem_ctx, @@ -260,6 +264,15 @@ static struct sec_desc_buf *samsync_query_lsa_sec_desc(TALLOC_CTX *mem_ctx, } \ } while (0) +#define TEST_BINARY_STRING_EQUAL(s1, s2) do {\ + if (!((!s1.array || s1.array[0]=='\0') && (!s2.array || s2.array[0]=='\0')) \ + && memcmp(s1.array, s2.array, s1.length * 2) != 0) {\ + printf("%s: string mismatch: " #s1 ":%s != " #s2 ": %s\n", \ + __location__, (const char *)s1.array, (const char *)s2.array);\ + ret = false;\ + } \ +} while (0) + #define TEST_SID_EQUAL(s1, s2) do {\ if (!dom_sid_equal(s1, s2)) {\ printf("%s: dom_sid mismatch: " #s1 ":%s != " #s2 ": %s\n", \ @@ -294,6 +307,7 @@ static bool samsync_handle_domain(TALLOC_CTX *mem_ctx, struct samsync_state *sam struct netr_DELTA_DOMAIN *domain = delta->delta_union.domain; struct dom_sid *dom_sid; struct samr_QueryDomainInfo q[14]; /* q[0] will be unused simple for clarity */ + union samr_DomainInfo *info[14]; uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13}; NTSTATUS nt_status; int i; @@ -341,8 +355,10 @@ static bool samsync_handle_domain(TALLOC_CTX *mem_ctx, struct samsync_state *sam (long long)samsync_state->seq_num[database_id]); for (i=0;i<ARRAY_SIZE(levels);i++) { + q[levels[i]].in.domain_handle = samsync_state->domain_handle[database_id]; q[levels[i]].in.level = levels[i]; + q[levels[i]].out.info = &info[levels[i]]; nt_status = dcerpc_samr_QueryDomainInfo(samsync_state->p_samr, mem_ctx, &q[levels[i]]); @@ -353,23 +369,23 @@ static bool samsync_handle_domain(TALLOC_CTX *mem_ctx, struct samsync_state *sam } } - TEST_STRING_EQUAL(q[5].out.info->info5.domain_name, domain->domain_name); + TEST_STRING_EQUAL(info[5]->info5.domain_name, domain->domain_name); - TEST_STRING_EQUAL(q[2].out.info->general.oem_information, domain->oem_information); - TEST_STRING_EQUAL(q[4].out.info->oem.oem_information, domain->oem_information); - TEST_TIME_EQUAL(q[2].out.info->general.force_logoff_time, domain->force_logoff_time); - TEST_TIME_EQUAL(q[3].out.info->info3.force_logoff_time, domain->force_logoff_time); + TEST_STRING_EQUAL(info[2]->general.oem_information, domain->oem_information); + TEST_STRING_EQUAL(info[4]->oem.oem_information, domain->oem_information); + TEST_TIME_EQUAL(info[2]->general.force_logoff_time, domain->force_logoff_time); + TEST_TIME_EQUAL(info[3]->info3.force_logoff_time, domain->force_logoff_time); - TEST_TIME_EQUAL(q[1].out.info->info1.min_password_length, domain->min_password_length); - TEST_TIME_EQUAL(q[1].out.info->info1.password_history_length, domain->password_history_length); - TEST_TIME_EQUAL(q[1].out.info->info1.max_password_age, domain->max_password_age); - TEST_TIME_EQUAL(q[1].out.info->info1.min_password_age, domain->min_password_age); + TEST_TIME_EQUAL(info[1]->info1.min_password_length, domain->min_password_length); + TEST_TIME_EQUAL(info[1]->info1.password_history_length, domain->password_history_length); + TEST_TIME_EQUAL(info[1]->info1.max_password_age, domain->max_password_age); + TEST_TIME_EQUAL(info[1]->info1.min_password_age, domain->min_password_age); - TEST_UINT64_EQUAL(q[8].out.info->info8.sequence_num, + TEST_UINT64_EQUAL(info[8]->info8.sequence_num, domain->sequence_num); - TEST_TIME_EQUAL(q[8].out.info->info8.domain_create_time, + TEST_TIME_EQUAL(info[8]->info8.domain_create_time, domain->domain_create_time); - TEST_TIME_EQUAL(q[13].out.info->info13.domain_create_time, + TEST_TIME_EQUAL(info[13]->info13.domain_create_time, domain->domain_create_time); TEST_SEC_DESC_EQUAL(domain->sdbuf, samr, samsync_state->domain_handle[database_id]); @@ -425,9 +441,12 @@ static bool samsync_handle_user(struct torture_context *tctx, TALLOC_CTX *mem_ct struct samr_OpenUser r; struct samr_QueryUserInfo q; + union samr_UserInfo *info; struct policy_handle user_handle; struct samr_GetGroupsForUser getgroups; + struct samr_RidWithAttributeArray *rids; + if (!samsync_state->domain_name || !samsync_state->domain_handle[database_id]) { printf("SamSync needs domain information before the users\n"); return false; @@ -446,6 +465,7 @@ static bool samsync_handle_user(struct torture_context *tctx, TALLOC_CTX *mem_ct q.in.user_handle = &user_handle; q.in.level = 21; + q.out.info = &info; TEST_SEC_DESC_EQUAL(user->sdbuf, samr, &user_handle); @@ -457,6 +477,7 @@ static bool samsync_handle_user(struct torture_context *tctx, TALLOC_CTX *mem_ct } getgroups.in.user_handle = &user_handle; + getgroups.out.rids = &rids; nt_status = dcerpc_samr_GetGroupsForUser(samsync_state->p_samr, mem_ctx, &getgroups); if (!NT_STATUS_IS_OK(nt_status)) { @@ -480,67 +501,67 @@ static bool samsync_handle_user(struct torture_context *tctx, TALLOC_CTX *mem_ct return false; } - TEST_STRING_EQUAL(q.out.info->info21.account_name, user->account_name); - TEST_STRING_EQUAL(q.out.info->info21.full_name, user->full_name); - TEST_INT_EQUAL(q.out.info->info21.rid, user->rid); - TEST_INT_EQUAL(q.out.info->info21.primary_gid, user->primary_gid); - TEST_STRING_EQUAL(q.out.info->info21.home_directory, user->home_directory); - TEST_STRING_EQUAL(q.out.info->info21.home_drive, user->home_drive); - TEST_STRING_EQUAL(q.out.info->info21.logon_script, user->logon_script); - TEST_STRING_EQUAL(q.out.info->info21.description, user->description); - TEST_STRING_EQUAL(q.out.info->info21.workstations, user->workstations); + TEST_STRING_EQUAL(info->info21.account_name, user->account_name); + TEST_STRING_EQUAL(info->info21.full_name, user->full_name); + TEST_INT_EQUAL(info->info21.rid, user->rid); + TEST_INT_EQUAL(info->info21.primary_gid, user->primary_gid); + TEST_STRING_EQUAL(info->info21.home_directory, user->home_directory); + TEST_STRING_EQUAL(info->info21.home_drive, user->home_drive); + TEST_STRING_EQUAL(info->info21.logon_script, user->logon_script); + TEST_STRING_EQUAL(info->info21.description, user->description); + TEST_STRING_EQUAL(info->info21.workstations, user->workstations); - TEST_TIME_EQUAL(q.out.info->info21.last_logon, user->last_logon); - TEST_TIME_EQUAL(q.out.info->info21.last_logoff, user->last_logoff); + TEST_TIME_EQUAL(info->info21.last_logon, user->last_logon); + TEST_TIME_EQUAL(info->info21.last_logoff, user->last_logoff); - TEST_INT_EQUAL(q.out.info->info21.logon_hours.units_per_week, + TEST_INT_EQUAL(info->info21.logon_hours.units_per_week, user->logon_hours.units_per_week); if (ret) { - if (memcmp(q.out.info->info21.logon_hours.bits, user->logon_hours.bits, - q.out.info->info21.logon_hours.units_per_week/8) != 0) { + if (memcmp(info->info21.logon_hours.bits, user->logon_hours.bits, + info->info21.logon_hours.units_per_week/8) != 0) { printf("Logon hours mismatch\n"); ret = false; } } - TEST_INT_EQUAL(q.out.info->info21.bad_password_count, + TEST_INT_EQUAL(info->info21.bad_password_count, user->bad_password_count); - TEST_INT_EQUAL(q.out.info->info21.logon_count, + TEST_INT_EQUAL(info->info21.logon_count, user->logon_count); - TEST_TIME_EQUAL(q.out.info->info21.last_password_change, + TEST_TIME_EQUAL(info->info21.last_password_change, user->last_password_change); - TEST_TIME_EQUAL(q.out.info->info21.acct_expiry, + TEST_TIME_EQUAL(info->info21.acct_expiry, user->acct_expiry); - TEST_INT_EQUAL((q.out.info->info21.acct_flags & ~ACB_PW_EXPIRED), user->acct_flags); + TEST_INT_EQUAL((info->info21.acct_flags & ~ACB_PW_EXPIRED), user->acct_flags); if (user->acct_flags & ACB_PWNOEXP) { - if (q.out.info->info21.acct_flags & ACB_PW_EXPIRED) { + if (info->info21.acct_flags & ACB_PW_EXPIRED) { printf("ACB flags mismatch: both expired and no expiry!\n"); ret = false; } - if (q.out.info->info21.force_password_change != (NTTIME)0x7FFFFFFFFFFFFFFFULL) { + if (info->info21.force_password_change != (NTTIME)0x7FFFFFFFFFFFFFFFULL) { printf("ACB flags mismatch: no password expiry, but force password change 0x%016llx (%lld) != 0x%016llx (%lld)\n", - (unsigned long long)q.out.info->info21.force_password_change, - (unsigned long long)q.out.info->info21.force_password_change, + (unsigned long long)info->info21.force_password_change, + (unsigned long long)info->info21.force_password_change, (unsigned long long)0x7FFFFFFFFFFFFFFFULL, (unsigned long long)0x7FFFFFFFFFFFFFFFULL ); ret = false; } } - TEST_INT_EQUAL(q.out.info->info21.nt_password_set, user->nt_password_present); - TEST_INT_EQUAL(q.out.info->info21.lm_password_set, user->lm_password_present); - TEST_INT_EQUAL(q.out.info->info21.password_expired, user->password_expired); + TEST_INT_EQUAL(info->info21.nt_password_set, user->nt_password_present); + TEST_INT_EQUAL(info->info21.lm_password_set, user->lm_password_present); + TEST_INT_EQUAL(info->info21.password_expired, user->password_expired); - TEST_STRING_EQUAL(q.out.info->info21.comment, user->comment); - TEST_STRING_EQUAL(q.out.info->info21.parameters, user->parameters); + TEST_STRING_EQUAL(info->info21.comment, user->comment); + TEST_BINARY_STRING_EQUAL(info->info21.parameters, user->parameters); - TEST_INT_EQUAL(q.out.info->info21.country_code, user->country_code); - TEST_INT_EQUAL(q.out.info->info21.code_page, user->code_page); + TEST_INT_EQUAL(info->info21.country_code, user->country_code); + TEST_INT_EQUAL(info->info21.code_page, user->code_page); - TEST_STRING_EQUAL(q.out.info->info21.profile_path, user->profile_path); + TEST_STRING_EQUAL(info->info21.profile_path, user->profile_path); if (user->lm_password_present) { sam_rid_crypt(rid, user->lmpassword.hash, lm_hash.hash, 0); @@ -619,7 +640,7 @@ static bool samsync_handle_user(struct torture_context *tctx, TALLOC_CTX *mem_ct return true; } } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_PASSWORD_EXPIRED)) { - if (q.out.info->info21.acct_flags & ACB_PW_EXPIRED) { + if (info->info21.acct_flags & ACB_PW_EXPIRED) { return true; } } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD)) { @@ -654,7 +675,7 @@ static bool samsync_handle_user(struct torture_context *tctx, TALLOC_CTX *mem_ct TEST_TIME_EQUAL(user->last_logon, info3->base.last_logon); TEST_TIME_EQUAL(user->acct_expiry, info3->base.acct_expiry); TEST_TIME_EQUAL(user->last_password_change, info3->base.last_password_change); - TEST_TIME_EQUAL(q.out.info->info21.force_password_change, info3->base.force_password_change); + TEST_TIME_EQUAL(info->info21.force_password_change, info3->base.force_password_change); /* Does the concept of a logoff time ever really * exist? (not in any sensible way, according to the @@ -667,28 +688,28 @@ static bool samsync_handle_user(struct torture_context *tctx, TALLOC_CTX *mem_ct TEST_TIME_EQUAL(user->last_logoff, info3->base.last_logoff); } - TEST_INT_EQUAL(getgroups.out.rids->count, info3->base.groups.count); - if (getgroups.out.rids->count == info3->base.groups.count) { + TEST_INT_EQUAL(rids->count, info3->base.groups.count); + if (rids->count == info3->base.groups.count) { int i, j; - int count = getgroups.out.rids->count; - bool *matched = talloc_zero_array(mem_ctx, bool, getgroups.out.rids->count); + int count = rids->count; + bool *matched = talloc_zero_array(mem_ctx, bool, rids->count); for (i = 0; i < count; i++) { for (j = 0; j < count; j++) { - if ((getgroups.out.rids->rids[i].rid == + if ((rids->rids[i].rid == info3->base.groups.rids[j].rid) - && (getgroups.out.rids->rids[i].attributes == + && (rids->rids[i].attributes == info3->base.groups.rids[j].attributes)) { matched[i] = true; } } } - for (i = 0; i < getgroups.out.rids->count; i++) { + for (i = 0; i < rids->count; i++) { if (matched[i] == false) { ret = false; printf("Could not find group RID %u found in getgroups in NETLOGON reply\n", - getgroups.out.rids->rids[i].rid); + rids->rids[i].rid); } } } @@ -711,6 +732,7 @@ static bool samsync_handle_alias(TALLOC_CTX *mem_ctx, struct samsync_state *sams struct samr_OpenAlias r; struct samr_QueryAliasInfo q; + union samr_AliasInfo *info; struct policy_handle alias_handle; if (!samsync_state->domain_name || !samsync_state->domain_handle[database_id]) { @@ -731,6 +753,7 @@ static bool samsync_handle_alias(TALLOC_CTX *mem_ctx, struct samsync_state *sams q.in.alias_handle = &alias_handle; q.in.level = 1; + q.out.info = &info; TEST_SEC_DESC_EQUAL(alias->sdbuf, samr, &alias_handle); @@ -745,8 +768,8 @@ static bool samsync_handle_alias(TALLOC_CTX *mem_ctx, struct samsync_state *sams return false; } - TEST_STRING_EQUAL(q.out.info->all.name, alias->alias_name); - TEST_STRING_EQUAL(q.out.info->all.description, alias->description); + TEST_STRING_EQUAL(info->all.name, alias->alias_name); + TEST_STRING_EQUAL(info->all.description, alias->description); return ret; } @@ -760,6 +783,7 @@ static bool samsync_handle_group(TALLOC_CTX *mem_ctx, struct samsync_state *sams struct samr_OpenGroup r; struct samr_QueryGroupInfo q; + union samr_GroupInfo *info; struct policy_handle group_handle; if (!samsync_state->domain_name || !samsync_state->domain_handle[database_id]) { @@ -780,6 +804,7 @@ static bool samsync_handle_group(TALLOC_CTX *mem_ctx, struct samsync_state *sams q.in.group_handle = &group_handle; q.in.level = 1; + q.out.info = &info; TEST_SEC_DESC_EQUAL(group->sdbuf, samr, &group_handle); @@ -794,9 +819,9 @@ static bool samsync_handle_group(TALLOC_CTX *mem_ctx, struct samsync_state *sams return false; } - TEST_STRING_EQUAL(q.out.info->all.name, group->group_name); - TEST_INT_EQUAL(q.out.info->all.attributes, group->attributes); - TEST_STRING_EQUAL(q.out.info->all.description, group->description); + TEST_STRING_EQUAL(info->all.name, group->group_name); + TEST_INT_EQUAL(info->all.attributes, group->attributes); + TEST_STRING_EQUAL(info->all.description, group->description); return ret; } diff --git a/source4/torture/rpc/schannel.c b/source4/torture/rpc/schannel.c index ca1655729b..451990a71b 100644 --- a/source4/torture/rpc/schannel.c +++ b/source4/torture/rpc/schannel.c @@ -128,6 +128,7 @@ static bool test_samr_ops(struct torture_context *tctx, { NTSTATUS status; struct samr_GetDomPwInfo r; + struct samr_PwInfo info; struct samr_Connect connect; struct samr_OpenDomain opendom; int i; @@ -137,6 +138,7 @@ static bool test_samr_ops(struct torture_context *tctx, name.string = lp_workgroup(tctx->lp_ctx); r.in.domain_name = &name; + r.out.info = &info; connect.in.system_name = 0; connect.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; diff --git a/source4/torture/rpc/testjoin.c b/source4/torture/rpc/testjoin.c index 3408a1924c..3b56d5b0ad 100644 --- a/source4/torture/rpc/testjoin.c +++ b/source4/torture/rpc/testjoin.c @@ -59,6 +59,7 @@ static NTSTATUS DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle user_handle; uint32_t rid; struct samr_LookupNames n; + struct samr_Ids rids, types; struct lsa_String sname; struct samr_OpenUser r; @@ -67,10 +68,12 @@ static NTSTATUS DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, n.in.domain_handle = handle; n.in.num_names = 1; n.in.names = &sname; + n.out.rids = &rids; + n.out.types = &types; status = dcerpc_samr_LookupNames(p, mem_ctx, &n); if (NT_STATUS_IS_OK(status)) { - rid = n.out.rids.ids[0]; + rid = n.out.rids->ids[0]; } else { return status; } @@ -113,7 +116,9 @@ struct test_join *torture_create_testuser(struct torture_context *torture, struct samr_CreateUser2 r; struct samr_OpenDomain o; struct samr_LookupDomain l; + struct dom_sid2 *sid = NULL; struct samr_GetUserPwInfo pwp; + struct samr_PwInfo info; struct samr_SetUserInfo s; union samr_UserInfo u; struct policy_handle handle; @@ -172,6 +177,7 @@ struct test_join *torture_create_testuser(struct torture_context *torture, name.string = domain; l.in.connect_handle = &handle; l.in.domain_name = &name; + l.out.sid = &sid; status = dcerpc_samr_LookupDomain(join->p, join, &l); if (!NT_STATUS_IS_OK(status)) { @@ -179,14 +185,14 @@ struct test_join *torture_create_testuser(struct torture_context *torture, goto failed; } - talloc_steal(join, l.out.sid); - join->dom_sid = l.out.sid; + talloc_steal(join, *l.out.sid); + join->dom_sid = *l.out.sid; join->dom_netbios_name = talloc_strdup(join, domain); if (!join->dom_netbios_name) goto failed; o.in.connect_handle = &handle; o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - o.in.sid = l.out.sid; + o.in.sid = *l.out.sid; o.out.domain_handle = &domain_handle; status = dcerpc_samr_OpenDomain(join->p, join, &o); @@ -224,10 +230,11 @@ again: join->user_sid = dom_sid_add_rid(join, join->dom_sid, rid); pwp.in.user_handle = &join->user_handle; + pwp.out.info = &info; status = dcerpc_samr_GetUserPwInfo(join->p, join, &pwp); if (NT_STATUS_IS_OK(status)) { - policy_min_pw_len = pwp.out.info.min_password_length; + policy_min_pw_len = pwp.out.info->min_password_length; } random_pw = generate_random_str(join, MAX(8, policy_min_pw_len)); |