s4:torture/samr - Activate "ValidatePassword" test per default
[kai/samba.git] / source4 / torture / rpc / samr.c
1 /*
2    Unix SMB/CIFS implementation.
3    test suite for samr rpc operations
4
5    Copyright (C) Andrew Tridgell 2003
6    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
7    Copyright (C) Guenther Deschner 2008,2009
8
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.
21 */
22
23 #include "includes.h"
24 #include "torture/torture.h"
25 #include "system/time.h"
26 #include "librpc/gen_ndr/lsa.h"
27 #include "librpc/gen_ndr/ndr_netlogon.h"
28 #include "librpc/gen_ndr/ndr_netlogon_c.h"
29 #include "librpc/gen_ndr/ndr_samr_c.h"
30 #include "librpc/gen_ndr/ndr_lsa_c.h"
31 #include "../lib/crypto/crypto.h"
32 #include "libcli/auth/libcli_auth.h"
33 #include "libcli/security/security.h"
34 #include "torture/rpc/rpc.h"
35 #include "param/param.h"
36
37 #include <unistd.h>
38
39 #define TEST_ACCOUNT_NAME "samrtorturetest"
40 #define TEST_ACCOUNT_NAME_PWD "samrpwdlastset"
41 #define TEST_ALIASNAME "samrtorturetestalias"
42 #define TEST_GROUPNAME "samrtorturetestgroup"
43 #define TEST_MACHINENAME "samrtestmach$"
44 #define TEST_DOMAINNAME "samrtestdom$"
45
46 enum torture_samr_choice {
47         TORTURE_SAMR_PASSWORDS,
48         TORTURE_SAMR_PASSWORDS_PWDLASTSET,
49         TORTURE_SAMR_USER_ATTRIBUTES,
50         TORTURE_SAMR_USER_PRIVILEGES,
51         TORTURE_SAMR_OTHER,
52         TORTURE_SAMR_MANY_ACCOUNTS,
53         TORTURE_SAMR_MANY_GROUPS,
54         TORTURE_SAMR_MANY_ALIASES
55 };
56
57 static bool test_QueryUserInfo(struct dcerpc_pipe *p,
58                                struct torture_context *tctx,
59                                struct policy_handle *handle);
60
61 static bool test_QueryUserInfo2(struct dcerpc_pipe *p,
62                                 struct torture_context *tctx,
63                                 struct policy_handle *handle);
64
65 static bool test_QueryAliasInfo(struct dcerpc_pipe *p,
66                                 struct torture_context *tctx,
67                                 struct policy_handle *handle);
68
69 static bool test_ChangePassword(struct dcerpc_pipe *p,
70                                 struct torture_context *tctx,
71                                 const char *acct_name,
72                                 struct policy_handle *domain_handle, char **password);
73
74 static void init_lsa_String(struct lsa_String *string, const char *s)
75 {
76         string->string = s;
77 }
78
79 static void init_lsa_StringLarge(struct lsa_StringLarge *string, const char *s)
80 {
81         string->string = s;
82 }
83
84 static void init_lsa_BinaryString(struct lsa_BinaryString *string, const char *s, uint32_t length)
85 {
86         string->length = length;
87         string->size = length;
88         string->array = (uint16_t *)discard_const(s);
89 }
90
91 bool test_samr_handle_Close(struct dcerpc_pipe *p, struct torture_context *tctx,
92                                    struct policy_handle *handle)
93 {
94         NTSTATUS status;
95         struct samr_Close r;
96
97         r.in.handle = handle;
98         r.out.handle = handle;
99
100         status = dcerpc_samr_Close(p, tctx, &r);
101         torture_assert_ntstatus_ok(tctx, status, "Close");
102
103         return true;
104 }
105
106 static bool test_Shutdown(struct dcerpc_pipe *p, struct torture_context *tctx,
107                        struct policy_handle *handle)
108 {
109         NTSTATUS status;
110         struct samr_Shutdown r;
111
112         if (!torture_setting_bool(tctx, "dangerous", false)) {
113                 torture_skip(tctx, "samr_Shutdown disabled - enable dangerous tests to use\n");
114                 return true;
115         }
116
117         r.in.connect_handle = handle;
118
119         torture_comment(tctx, "testing samr_Shutdown\n");
120
121         status = dcerpc_samr_Shutdown(p, tctx, &r);
122         torture_assert_ntstatus_ok(tctx, status, "samr_Shutdown");
123
124         return true;
125 }
126
127 static bool test_SetDsrmPassword(struct dcerpc_pipe *p, struct torture_context *tctx,
128                                  struct policy_handle *handle)
129 {
130         NTSTATUS status;
131         struct samr_SetDsrmPassword r;
132         struct lsa_String string;
133         struct samr_Password hash;
134
135         if (!torture_setting_bool(tctx, "dangerous", false)) {
136                 torture_skip(tctx, "samr_SetDsrmPassword disabled - enable dangerous tests to use");
137         }
138
139         E_md4hash("TeSTDSRM123", hash.hash);
140
141         init_lsa_String(&string, "Administrator");
142
143         r.in.name = &string;
144         r.in.unknown = 0;
145         r.in.hash = &hash;
146
147         torture_comment(tctx, "testing samr_SetDsrmPassword\n");
148
149         status = dcerpc_samr_SetDsrmPassword(p, tctx, &r);
150         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_SUPPORTED, "samr_SetDsrmPassword");
151
152         return true;
153 }
154
155
156 static bool test_QuerySecurity(struct dcerpc_pipe *p,
157                                struct torture_context *tctx,
158                                struct policy_handle *handle)
159 {
160         NTSTATUS status;
161         struct samr_QuerySecurity r;
162         struct samr_SetSecurity s;
163         struct sec_desc_buf *sdbuf = NULL;
164
165         r.in.handle = handle;
166         r.in.sec_info = 7;
167         r.out.sdbuf = &sdbuf;
168
169         status = dcerpc_samr_QuerySecurity(p, tctx, &r);
170         torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
171
172         torture_assert(tctx, sdbuf != NULL, "sdbuf is NULL");
173
174         s.in.handle = handle;
175         s.in.sec_info = 7;
176         s.in.sdbuf = sdbuf;
177
178         if (torture_setting_bool(tctx, "samba4", false)) {
179                 torture_skip(tctx, "skipping SetSecurity test against Samba4\n");
180         }
181
182         status = dcerpc_samr_SetSecurity(p, tctx, &s);
183         torture_assert_ntstatus_ok(tctx, status, "SetSecurity");
184
185         status = dcerpc_samr_QuerySecurity(p, tctx, &r);
186         torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
187
188         return true;
189 }
190
191
192 static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
193                              struct policy_handle *handle, uint32_t base_acct_flags,
194                              const char *base_account_name)
195 {
196         NTSTATUS status;
197         struct samr_SetUserInfo s;
198         struct samr_SetUserInfo2 s2;
199         struct samr_QueryUserInfo q;
200         struct samr_QueryUserInfo q0;
201         union samr_UserInfo u;
202         union samr_UserInfo *info;
203         bool ret = true;
204         const char *test_account_name;
205
206         uint32_t user_extra_flags = 0;
207
208         if (!torture_setting_bool(tctx, "samba3", false)) {
209                 if (base_acct_flags == ACB_NORMAL) {
210                         /* When created, accounts are expired by default */
211                         user_extra_flags = ACB_PW_EXPIRED;
212                 }
213         }
214
215         s.in.user_handle = handle;
216         s.in.info = &u;
217
218         s2.in.user_handle = handle;
219         s2.in.info = &u;
220
221         q.in.user_handle = handle;
222         q.out.info = &info;
223         q0 = q;
224
225 #define TESTCALL(call, r) \
226                 status = dcerpc_samr_ ##call(p, tctx, &r); \
227                 if (!NT_STATUS_IS_OK(status)) { \
228                         torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
229                                r.in.level, nt_errstr(status), __location__); \
230                         ret = false; \
231                         break; \
232                 }
233
234 #define STRING_EQUAL(s1, s2, field) \
235                 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
236                         torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
237                                #field, s2, __location__); \
238                         ret = false; \
239                         break; \
240                 }
241
242 #define MEM_EQUAL(s1, s2, length, field) \
243                 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
244                         torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
245                                #field, (const char *)s2, __location__); \
246                         ret = false; \
247                         break; \
248                 }
249
250 #define INT_EQUAL(i1, i2, field) \
251                 if (i1 != i2) { \
252                         torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
253                                #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
254                         ret = false; \
255                         break; \
256                 }
257
258 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
259                 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
260                 q.in.level = lvl1; \
261                 TESTCALL(QueryUserInfo, q) \
262                 s.in.level = lvl1; \
263                 s2.in.level = lvl1; \
264                 u = *info; \
265                 if (lvl1 == 21) { \
266                         ZERO_STRUCT(u.info21); \
267                         u.info21.fields_present = fpval; \
268                 } \
269                 init_lsa_String(&u.info ## lvl1.field1, value); \
270                 TESTCALL(SetUserInfo, s) \
271                 TESTCALL(SetUserInfo2, s2) \
272                 init_lsa_String(&u.info ## lvl1.field1, ""); \
273                 TESTCALL(QueryUserInfo, q); \
274                 u = *info; \
275                 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
276                 q.in.level = lvl2; \
277                 TESTCALL(QueryUserInfo, q) \
278                 u = *info; \
279                 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
280         } while (0)
281
282 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
283                 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
284                 q.in.level = lvl1; \
285                 TESTCALL(QueryUserInfo, q) \
286                 s.in.level = lvl1; \
287                 s2.in.level = lvl1; \
288                 u = *info; \
289                 if (lvl1 == 21) { \
290                         ZERO_STRUCT(u.info21); \
291                         u.info21.fields_present = fpval; \
292                 } \
293                 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
294                 TESTCALL(SetUserInfo, s) \
295                 TESTCALL(SetUserInfo2, s2) \
296                 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
297                 TESTCALL(QueryUserInfo, q); \
298                 u = *info; \
299                 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
300                 q.in.level = lvl2; \
301                 TESTCALL(QueryUserInfo, q) \
302                 u = *info; \
303                 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
304         } while (0)
305
306 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
307                 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
308                 q.in.level = lvl1; \
309                 TESTCALL(QueryUserInfo, q) \
310                 s.in.level = lvl1; \
311                 s2.in.level = lvl1; \
312                 u = *info; \
313                 if (lvl1 == 21) { \
314                         uint8_t *bits = u.info21.logon_hours.bits; \
315                         ZERO_STRUCT(u.info21); \
316                         if (fpval == SAMR_FIELD_LOGON_HOURS) { \
317                                 u.info21.logon_hours.units_per_week = 168; \
318                                 u.info21.logon_hours.bits = bits; \
319                         } \
320                         u.info21.fields_present = fpval; \
321                 } \
322                 u.info ## lvl1.field1 = value; \
323                 TESTCALL(SetUserInfo, s) \
324                 TESTCALL(SetUserInfo2, s2) \
325                 u.info ## lvl1.field1 = 0; \
326                 TESTCALL(QueryUserInfo, q); \
327                 u = *info; \
328                 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
329                 q.in.level = lvl2; \
330                 TESTCALL(QueryUserInfo, q) \
331                 u = *info; \
332                 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
333         } while (0)
334
335 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
336         TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
337         } while (0)
338
339         q0.in.level = 12;
340         do { TESTCALL(QueryUserInfo, q0) } while (0);
341
342         TEST_USERINFO_STRING(2, comment,  1, comment, "xx2-1 comment", 0);
343         TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
344         TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
345                            SAMR_FIELD_COMMENT);
346
347         test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
348         TEST_USERINFO_STRING(7, account_name,  1, account_name, base_account_name, 0);
349         test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
350         TEST_USERINFO_STRING(7, account_name,  3, account_name, base_account_name, 0);
351         test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
352         TEST_USERINFO_STRING(7, account_name,  5, account_name, base_account_name, 0);
353         test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
354         TEST_USERINFO_STRING(7, account_name,  6, account_name, base_account_name, 0);
355         test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
356         TEST_USERINFO_STRING(7, account_name,  7, account_name, base_account_name, 0);
357         test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
358         TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
359         test_account_name = base_account_name;
360         TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
361                            SAMR_FIELD_ACCOUNT_NAME);
362
363         TEST_USERINFO_STRING(6, full_name,  1, full_name, "xx6-1 full_name", 0);
364         TEST_USERINFO_STRING(6, full_name,  3, full_name, "xx6-3 full_name", 0);
365         TEST_USERINFO_STRING(6, full_name,  5, full_name, "xx6-5 full_name", 0);
366         TEST_USERINFO_STRING(6, full_name,  6, full_name, "xx6-6 full_name", 0);
367         TEST_USERINFO_STRING(6, full_name,  8, full_name, "xx6-8 full_name", 0);
368         TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
369         TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
370         TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
371                            SAMR_FIELD_FULL_NAME);
372
373         TEST_USERINFO_STRING(6, full_name,  1, full_name, "", 0);
374         TEST_USERINFO_STRING(6, full_name,  3, full_name, "", 0);
375         TEST_USERINFO_STRING(6, full_name,  5, full_name, "", 0);
376         TEST_USERINFO_STRING(6, full_name,  6, full_name, "", 0);
377         TEST_USERINFO_STRING(6, full_name,  8, full_name, "", 0);
378         TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
379         TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
380         TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
381                            SAMR_FIELD_FULL_NAME);
382
383         TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
384         TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
385         TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
386         TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
387                            SAMR_FIELD_LOGON_SCRIPT);
388
389         TEST_USERINFO_STRING(12, profile_path,  3, profile_path, "xx12-3 profile_path", 0);
390         TEST_USERINFO_STRING(12, profile_path,  5, profile_path, "xx12-5 profile_path", 0);
391         TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
392         TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
393                            SAMR_FIELD_PROFILE_PATH);
394
395         TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
396         TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
397         TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
398         TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
399                              SAMR_FIELD_HOME_DIRECTORY);
400         TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
401                              SAMR_FIELD_HOME_DIRECTORY);
402
403         TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
404         TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
405         TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
406         TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
407                              SAMR_FIELD_HOME_DRIVE);
408         TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
409                              SAMR_FIELD_HOME_DRIVE);
410
411         TEST_USERINFO_STRING(13, description,  1, description, "xx13-1 description", 0);
412         TEST_USERINFO_STRING(13, description,  5, description, "xx13-5 description", 0);
413         TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
414         TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
415                            SAMR_FIELD_DESCRIPTION);
416
417         TEST_USERINFO_STRING(14, workstations,  3, workstations, "14workstation3", 0);
418         TEST_USERINFO_STRING(14, workstations,  5, workstations, "14workstation4", 0);
419         TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
420         TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
421                            SAMR_FIELD_WORKSTATIONS);
422         TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3",
423                            SAMR_FIELD_WORKSTATIONS);
424         TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5",
425                            SAMR_FIELD_WORKSTATIONS);
426         TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
427                            SAMR_FIELD_WORKSTATIONS);
428
429         TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
430         TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
431                            SAMR_FIELD_PARAMETERS);
432         TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
433                            SAMR_FIELD_PARAMETERS);
434         /* also empty user parameters are allowed */
435         TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "", 0);
436         TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "",
437                            SAMR_FIELD_PARAMETERS);
438         TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "",
439                            SAMR_FIELD_PARAMETERS);
440
441         /* Samba 3 cannot store country_code and copy_page atm. - gd */
442         if (!torture_setting_bool(tctx, "samba3", false)) {
443                 TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
444                 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
445                 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
446                                   SAMR_FIELD_COUNTRY_CODE);
447                 TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__,
448                                   SAMR_FIELD_COUNTRY_CODE);
449
450                 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
451                 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
452                                   SAMR_FIELD_CODE_PAGE);
453                 TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__,
454                                   SAMR_FIELD_CODE_PAGE);
455         }
456
457         if (!torture_setting_bool(tctx, "samba3", false)) {
458                 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
459                 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
460                 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
461                                   SAMR_FIELD_ACCT_EXPIRY);
462                 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
463                                   SAMR_FIELD_ACCT_EXPIRY);
464                 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
465                                   SAMR_FIELD_ACCT_EXPIRY);
466         } else {
467                 /* Samba 3 can only store seconds / time_t in passdb - gd */
468                 NTTIME nt;
469                 unix_to_nt_time(&nt, time(NULL) + __LINE__);
470                 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, nt, 0);
471                 unix_to_nt_time(&nt, time(NULL) + __LINE__);
472                 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, nt, 0);
473                 unix_to_nt_time(&nt, time(NULL) + __LINE__);
474                 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
475                 unix_to_nt_time(&nt, time(NULL) + __LINE__);
476                 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
477                 unix_to_nt_time(&nt, time(NULL) + __LINE__);
478                 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
479         }
480
481         TEST_USERINFO_INT(4, logon_hours.bits[3],  3, logon_hours.bits[3], 1, 0);
482         TEST_USERINFO_INT(4, logon_hours.bits[3],  5, logon_hours.bits[3], 2, 0);
483         TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
484         TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
485                           SAMR_FIELD_LOGON_HOURS);
486
487         TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
488                               (base_acct_flags  | ACB_DISABLED | ACB_HOMDIRREQ),
489                               (base_acct_flags  | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
490                               0);
491         TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
492                               (base_acct_flags  | ACB_DISABLED),
493                               (base_acct_flags  | ACB_DISABLED | user_extra_flags),
494                               0);
495
496         /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
497         TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
498                               (base_acct_flags  | ACB_DISABLED | ACB_PWNOEXP),
499                               (base_acct_flags  | ACB_DISABLED | ACB_PWNOEXP),
500                               0);
501         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
502                               (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
503                               (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
504                               0);
505
506
507         /* The 'autolock' flag doesn't stick - check this */
508         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
509                               (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
510                               (base_acct_flags | ACB_DISABLED | user_extra_flags),
511                               0);
512 #if 0
513         /* Removing the 'disabled' flag doesn't stick - check this */
514         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
515                               (base_acct_flags),
516                               (base_acct_flags | ACB_DISABLED | user_extra_flags),
517                               0);
518 #endif
519
520         /* Samba3 cannot store these atm */
521         if (!torture_setting_bool(tctx, "samba3", false)) {
522         /* The 'store plaintext' flag does stick */
523         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
524                               (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
525                               (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
526                               0);
527         /* The 'use DES' flag does stick */
528         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
529                               (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
530                               (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
531                               0);
532         /* The 'don't require kerberos pre-authentication flag does stick */
533         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
534                               (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
535                               (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
536                               0);
537         /* The 'no kerberos PAC required' flag sticks */
538         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
539                               (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
540                               (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
541                               0);
542         }
543         TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
544                               (base_acct_flags | ACB_DISABLED),
545                               (base_acct_flags | ACB_DISABLED | user_extra_flags),
546                               SAMR_FIELD_ACCT_FLAGS);
547
548 #if 0
549         /* these fail with win2003 - it appears you can't set the primary gid?
550            the set succeeds, but the gid isn't changed. Very weird! */
551         TEST_USERINFO_INT(9, primary_gid,  1, primary_gid, 513);
552         TEST_USERINFO_INT(9, primary_gid,  3, primary_gid, 513);
553         TEST_USERINFO_INT(9, primary_gid,  5, primary_gid, 513);
554         TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
555 #endif
556
557         return ret;
558 }
559
560 /*
561   generate a random password for password change tests
562 */
563 static char *samr_rand_pass_silent(TALLOC_CTX *mem_ctx, int min_len)
564 {
565         size_t len = MAX(8, min_len) + (random() % 6);
566         char *s = generate_random_str(mem_ctx, len);
567         return s;
568 }
569
570 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
571 {
572         char *s = samr_rand_pass_silent(mem_ctx, min_len);
573         printf("Generated password '%s'\n", s);
574         return s;
575
576 }
577
578 /*
579   generate a random password for password change tests
580 */
581 static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
582 {
583         int i;
584         DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
585         generate_random_buffer(password.data, password.length);
586
587         for (i=0; i < len; i++) {
588                 if (((uint16_t *)password.data)[i] == 0) {
589                         ((uint16_t *)password.data)[i] = 1;
590                 }
591         }
592
593         return password;
594 }
595
596 /*
597   generate a random password for password change tests (fixed length)
598 */
599 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
600 {
601         char *s = generate_random_str(mem_ctx, len);
602         printf("Generated password '%s'\n", s);
603         return s;
604 }
605
606 static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx,
607                              struct policy_handle *handle, char **password)
608 {
609         NTSTATUS status;
610         struct samr_SetUserInfo s;
611         union samr_UserInfo u;
612         bool ret = true;
613         DATA_BLOB session_key;
614         char *newpass;
615         struct samr_GetUserPwInfo pwp;
616         struct samr_PwInfo info;
617         int policy_min_pw_len = 0;
618         pwp.in.user_handle = handle;
619         pwp.out.info = &info;
620
621         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
622         if (NT_STATUS_IS_OK(status)) {
623                 policy_min_pw_len = pwp.out.info->min_password_length;
624         }
625         newpass = samr_rand_pass(tctx, policy_min_pw_len);
626
627         s.in.user_handle = handle;
628         s.in.info = &u;
629         s.in.level = 24;
630
631         encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
632         u.info24.password_expired = 0;
633
634         status = dcerpc_fetch_session_key(p, &session_key);
635         if (!NT_STATUS_IS_OK(status)) {
636                 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
637                        s.in.level, nt_errstr(status));
638                 return false;
639         }
640
641         arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
642
643         torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
644
645         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
646         if (!NT_STATUS_IS_OK(status)) {
647                 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
648                        s.in.level, nt_errstr(status));
649                 ret = false;
650         } else {
651                 *password = newpass;
652         }
653
654         return ret;
655 }
656
657
658 static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
659                                 struct policy_handle *handle, uint32_t fields_present,
660                                 char **password)
661 {
662         NTSTATUS status;
663         struct samr_SetUserInfo s;
664         union samr_UserInfo u;
665         bool ret = true;
666         DATA_BLOB session_key;
667         char *newpass;
668         struct samr_GetUserPwInfo pwp;
669         struct samr_PwInfo info;
670         int policy_min_pw_len = 0;
671         pwp.in.user_handle = handle;
672         pwp.out.info = &info;
673
674         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
675         if (NT_STATUS_IS_OK(status)) {
676                 policy_min_pw_len = pwp.out.info->min_password_length;
677         }
678         newpass = samr_rand_pass(tctx, policy_min_pw_len);
679
680         s.in.user_handle = handle;
681         s.in.info = &u;
682         s.in.level = 23;
683
684         ZERO_STRUCT(u);
685
686         u.info23.info.fields_present = fields_present;
687
688         encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
689
690         status = dcerpc_fetch_session_key(p, &session_key);
691         if (!NT_STATUS_IS_OK(status)) {
692                 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
693                        s.in.level, nt_errstr(status));
694                 return false;
695         }
696
697         arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
698
699         torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
700
701         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
702         if (!NT_STATUS_IS_OK(status)) {
703                 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
704                        s.in.level, nt_errstr(status));
705                 ret = false;
706         } else {
707                 *password = newpass;
708         }
709
710         encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
711
712         status = dcerpc_fetch_session_key(p, &session_key);
713         if (!NT_STATUS_IS_OK(status)) {
714                 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
715                        s.in.level, nt_errstr(status));
716                 return false;
717         }
718
719         /* This should break the key nicely */
720         session_key.length--;
721         arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
722
723         torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
724
725         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
726         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
727                 torture_warning(tctx, "SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
728                        s.in.level, nt_errstr(status));
729                 ret = false;
730         }
731
732         return ret;
733 }
734
735
736 static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
737                                struct policy_handle *handle, bool makeshort,
738                                char **password)
739 {
740         NTSTATUS status;
741         struct samr_SetUserInfo s;
742         union samr_UserInfo u;
743         bool ret = true;
744         DATA_BLOB session_key;
745         DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
746         uint8_t confounder[16];
747         char *newpass;
748         struct MD5Context ctx;
749         struct samr_GetUserPwInfo pwp;
750         struct samr_PwInfo info;
751         int policy_min_pw_len = 0;
752         pwp.in.user_handle = handle;
753         pwp.out.info = &info;
754
755         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
756         if (NT_STATUS_IS_OK(status)) {
757                 policy_min_pw_len = pwp.out.info->min_password_length;
758         }
759         if (makeshort && policy_min_pw_len) {
760                 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
761         } else {
762                 newpass = samr_rand_pass(tctx, policy_min_pw_len);
763         }
764
765         s.in.user_handle = handle;
766         s.in.info = &u;
767         s.in.level = 26;
768
769         encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
770         u.info26.password_expired = 0;
771
772         status = dcerpc_fetch_session_key(p, &session_key);
773         if (!NT_STATUS_IS_OK(status)) {
774                 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
775                        s.in.level, nt_errstr(status));
776                 return false;
777         }
778
779         generate_random_buffer((uint8_t *)confounder, 16);
780
781         MD5Init(&ctx);
782         MD5Update(&ctx, confounder, 16);
783         MD5Update(&ctx, session_key.data, session_key.length);
784         MD5Final(confounded_session_key.data, &ctx);
785
786         arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
787         memcpy(&u.info26.password.data[516], confounder, 16);
788
789         torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n");
790
791         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
792         if (!NT_STATUS_IS_OK(status)) {
793                 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
794                        s.in.level, nt_errstr(status));
795                 ret = false;
796         } else {
797                 *password = newpass;
798         }
799
800         /* This should break the key nicely */
801         confounded_session_key.data[0]++;
802
803         arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
804         memcpy(&u.info26.password.data[516], confounder, 16);
805
806         torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
807
808         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
809         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
810                 torture_warning(tctx, "SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
811                        s.in.level, nt_errstr(status));
812                 ret = false;
813         } else {
814                 *password = newpass;
815         }
816
817         return ret;
818 }
819
820 static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
821                                 struct policy_handle *handle, uint32_t fields_present,
822                                 char **password)
823 {
824         NTSTATUS status;
825         struct samr_SetUserInfo s;
826         union samr_UserInfo u;
827         bool ret = true;
828         DATA_BLOB session_key;
829         DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
830         struct MD5Context ctx;
831         uint8_t confounder[16];
832         char *newpass;
833         struct samr_GetUserPwInfo pwp;
834         struct samr_PwInfo info;
835         int policy_min_pw_len = 0;
836         pwp.in.user_handle = handle;
837         pwp.out.info = &info;
838
839         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
840         if (NT_STATUS_IS_OK(status)) {
841                 policy_min_pw_len = pwp.out.info->min_password_length;
842         }
843         newpass = samr_rand_pass(tctx, policy_min_pw_len);
844
845         s.in.user_handle = handle;
846         s.in.info = &u;
847         s.in.level = 25;
848
849         ZERO_STRUCT(u);
850
851         u.info25.info.fields_present = fields_present;
852
853         encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
854
855         status = dcerpc_fetch_session_key(p, &session_key);
856         if (!NT_STATUS_IS_OK(status)) {
857                 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
858                        s.in.level, nt_errstr(status));
859                 return false;
860         }
861
862         generate_random_buffer((uint8_t *)confounder, 16);
863
864         MD5Init(&ctx);
865         MD5Update(&ctx, confounder, 16);
866         MD5Update(&ctx, session_key.data, session_key.length);
867         MD5Final(confounded_session_key.data, &ctx);
868
869         arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
870         memcpy(&u.info25.password.data[516], confounder, 16);
871
872         torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex)\n");
873
874         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
875         if (!NT_STATUS_IS_OK(status)) {
876                 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
877                        s.in.level, nt_errstr(status));
878                 ret = false;
879         } else {
880                 *password = newpass;
881         }
882
883         /* This should break the key nicely */
884         confounded_session_key.data[0]++;
885
886         arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
887         memcpy(&u.info25.password.data[516], confounder, 16);
888
889         torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
890
891         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
892         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
893                 torture_warning(tctx, "SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
894                        s.in.level, nt_errstr(status));
895                 ret = false;
896         }
897
898         return ret;
899 }
900
901 static bool test_SetUserPass_18(struct dcerpc_pipe *p, struct torture_context *tctx,
902                                 struct policy_handle *handle, char **password)
903 {
904         NTSTATUS status;
905         struct samr_SetUserInfo s;
906         union samr_UserInfo u;
907         bool ret = true;
908         DATA_BLOB session_key;
909         char *newpass;
910         struct samr_GetUserPwInfo pwp;
911         struct samr_PwInfo info;
912         int policy_min_pw_len = 0;
913         uint8_t lm_hash[16], nt_hash[16];
914
915         pwp.in.user_handle = handle;
916         pwp.out.info = &info;
917
918         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
919         if (NT_STATUS_IS_OK(status)) {
920                 policy_min_pw_len = pwp.out.info->min_password_length;
921         }
922         newpass = samr_rand_pass(tctx, policy_min_pw_len);
923
924         s.in.user_handle = handle;
925         s.in.info = &u;
926         s.in.level = 18;
927
928         ZERO_STRUCT(u);
929
930         u.info18.nt_pwd_active = true;
931         u.info18.lm_pwd_active = true;
932
933         E_md4hash(newpass, nt_hash);
934         E_deshash(newpass, lm_hash);
935
936         status = dcerpc_fetch_session_key(p, &session_key);
937         if (!NT_STATUS_IS_OK(status)) {
938                 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
939                        s.in.level, nt_errstr(status));
940                 return false;
941         }
942
943         {
944                 DATA_BLOB in,out;
945                 in = data_blob_const(nt_hash, 16);
946                 out = data_blob_talloc_zero(tctx, 16);
947                 sess_crypt_blob(&out, &in, &session_key, true);
948                 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
949         }
950         {
951                 DATA_BLOB in,out;
952                 in = data_blob_const(lm_hash, 16);
953                 out = data_blob_talloc_zero(tctx, 16);
954                 sess_crypt_blob(&out, &in, &session_key, true);
955                 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
956         }
957
958         torture_comment(tctx, "Testing SetUserInfo level 18 (set password hash)\n");
959
960         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
961         if (!NT_STATUS_IS_OK(status)) {
962                 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
963                        s.in.level, nt_errstr(status));
964                 ret = false;
965         } else {
966                 *password = newpass;
967         }
968
969         return ret;
970 }
971
972 static bool test_SetUserPass_21(struct dcerpc_pipe *p, struct torture_context *tctx,
973                                 struct policy_handle *handle, uint32_t fields_present,
974                                 char **password)
975 {
976         NTSTATUS status;
977         struct samr_SetUserInfo s;
978         union samr_UserInfo u;
979         bool ret = true;
980         DATA_BLOB session_key;
981         char *newpass;
982         struct samr_GetUserPwInfo pwp;
983         struct samr_PwInfo info;
984         int policy_min_pw_len = 0;
985         uint8_t lm_hash[16], nt_hash[16];
986
987         pwp.in.user_handle = handle;
988         pwp.out.info = &info;
989
990         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
991         if (NT_STATUS_IS_OK(status)) {
992                 policy_min_pw_len = pwp.out.info->min_password_length;
993         }
994         newpass = samr_rand_pass(tctx, policy_min_pw_len);
995
996         s.in.user_handle = handle;
997         s.in.info = &u;
998         s.in.level = 21;
999
1000         E_md4hash(newpass, nt_hash);
1001         E_deshash(newpass, lm_hash);
1002
1003         ZERO_STRUCT(u);
1004
1005         u.info21.fields_present = fields_present;
1006
1007         if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1008                 u.info21.lm_owf_password.length = 16;
1009                 u.info21.lm_owf_password.size = 16;
1010                 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1011                 u.info21.lm_password_set = true;
1012         }
1013
1014         if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1015                 u.info21.nt_owf_password.length = 16;
1016                 u.info21.nt_owf_password.size = 16;
1017                 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1018                 u.info21.nt_password_set = true;
1019         }
1020
1021         status = dcerpc_fetch_session_key(p, &session_key);
1022         if (!NT_STATUS_IS_OK(status)) {
1023                 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
1024                        s.in.level, nt_errstr(status));
1025                 return false;
1026         }
1027
1028         if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1029                 DATA_BLOB in,out;
1030                 in = data_blob_const(u.info21.lm_owf_password.array,
1031                                      u.info21.lm_owf_password.length);
1032                 out = data_blob_talloc_zero(tctx, 16);
1033                 sess_crypt_blob(&out, &in, &session_key, true);
1034                 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1035         }
1036
1037         if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1038                 DATA_BLOB in,out;
1039                 in = data_blob_const(u.info21.nt_owf_password.array,
1040                                      u.info21.nt_owf_password.length);
1041                 out = data_blob_talloc_zero(tctx, 16);
1042                 sess_crypt_blob(&out, &in, &session_key, true);
1043                 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1044         }
1045
1046         torture_comment(tctx, "Testing SetUserInfo level 21 (set password hash)\n");
1047
1048         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1049         if (!NT_STATUS_IS_OK(status)) {
1050                 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
1051                        s.in.level, nt_errstr(status));
1052                 ret = false;
1053         } else {
1054                 *password = newpass;
1055         }
1056
1057         /* try invalid length */
1058         if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1059
1060                 u.info21.nt_owf_password.length++;
1061
1062                 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1063
1064                 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1065                         torture_warning(tctx, "SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1066                                s.in.level, nt_errstr(status));
1067                         ret = false;
1068                 }
1069         }
1070
1071         if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1072
1073                 u.info21.lm_owf_password.length++;
1074
1075                 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1076
1077                 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1078                         torture_warning(tctx, "SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1079                                s.in.level, nt_errstr(status));
1080                         ret = false;
1081                 }
1082         }
1083
1084         return ret;
1085 }
1086
1087 static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p,
1088                                       struct torture_context *tctx,
1089                                       struct policy_handle *handle,
1090                                       uint16_t level,
1091                                       uint32_t fields_present,
1092                                       char **password, uint8_t password_expired,
1093                                       bool use_setinfo2,
1094                                       bool *matched_expected_error)
1095 {
1096         NTSTATUS status;
1097         NTSTATUS expected_error = NT_STATUS_OK;
1098         struct samr_SetUserInfo s;
1099         struct samr_SetUserInfo2 s2;
1100         union samr_UserInfo u;
1101         bool ret = true;
1102         DATA_BLOB session_key;
1103         DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
1104         struct MD5Context ctx;
1105         uint8_t confounder[16];
1106         char *newpass;
1107         struct samr_GetUserPwInfo pwp;
1108         struct samr_PwInfo info;
1109         int policy_min_pw_len = 0;
1110         const char *comment = NULL;
1111         uint8_t lm_hash[16], nt_hash[16];
1112
1113         pwp.in.user_handle = handle;
1114         pwp.out.info = &info;
1115
1116         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1117         if (NT_STATUS_IS_OK(status)) {
1118                 policy_min_pw_len = pwp.out.info->min_password_length;
1119         }
1120         newpass = samr_rand_pass_silent(tctx, policy_min_pw_len);
1121
1122         if (use_setinfo2) {
1123                 s2.in.user_handle = handle;
1124                 s2.in.info = &u;
1125                 s2.in.level = level;
1126         } else {
1127                 s.in.user_handle = handle;
1128                 s.in.info = &u;
1129                 s.in.level = level;
1130         }
1131
1132         if (fields_present & SAMR_FIELD_COMMENT) {
1133                 comment = talloc_asprintf(tctx, "comment: %ld\n", time(NULL));
1134         }
1135
1136         ZERO_STRUCT(u);
1137
1138         switch (level) {
1139         case 18:
1140                 E_md4hash(newpass, nt_hash);
1141                 E_deshash(newpass, lm_hash);
1142
1143                 u.info18.nt_pwd_active = true;
1144                 u.info18.lm_pwd_active = true;
1145                 u.info18.password_expired = password_expired;
1146
1147                 memcpy(u.info18.lm_pwd.hash, lm_hash, 16);
1148                 memcpy(u.info18.nt_pwd.hash, nt_hash, 16);
1149
1150                 break;
1151         case 21:
1152                 E_md4hash(newpass, nt_hash);
1153                 E_deshash(newpass, lm_hash);
1154
1155                 u.info21.fields_present = fields_present;
1156                 u.info21.password_expired = password_expired;
1157                 u.info21.comment.string = comment;
1158
1159                 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1160                         u.info21.lm_owf_password.length = 16;
1161                         u.info21.lm_owf_password.size = 16;
1162                         u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1163                         u.info21.lm_password_set = true;
1164                 }
1165
1166                 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1167                         u.info21.nt_owf_password.length = 16;
1168                         u.info21.nt_owf_password.size = 16;
1169                         u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1170                         u.info21.nt_password_set = true;
1171                 }
1172
1173                 break;
1174         case 23:
1175                 u.info23.info.fields_present = fields_present;
1176                 u.info23.info.password_expired = password_expired;
1177                 u.info23.info.comment.string = comment;
1178
1179                 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
1180
1181                 break;
1182         case 24:
1183                 u.info24.password_expired = password_expired;
1184
1185                 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
1186
1187                 break;
1188         case 25:
1189                 u.info25.info.fields_present = fields_present;
1190                 u.info25.info.password_expired = password_expired;
1191                 u.info25.info.comment.string = comment;
1192
1193                 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
1194
1195                 break;
1196         case 26:
1197                 u.info26.password_expired = password_expired;
1198
1199                 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
1200
1201                 break;
1202         }
1203
1204         status = dcerpc_fetch_session_key(p, &session_key);
1205         if (!NT_STATUS_IS_OK(status)) {
1206                 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
1207                        s.in.level, nt_errstr(status));
1208                 return false;
1209         }
1210
1211         generate_random_buffer((uint8_t *)confounder, 16);
1212
1213         MD5Init(&ctx);
1214         MD5Update(&ctx, confounder, 16);
1215         MD5Update(&ctx, session_key.data, session_key.length);
1216         MD5Final(confounded_session_key.data, &ctx);
1217
1218         switch (level) {
1219         case 18:
1220                 {
1221                         DATA_BLOB in,out;
1222                         in = data_blob_const(u.info18.nt_pwd.hash, 16);
1223                         out = data_blob_talloc_zero(tctx, 16);
1224                         sess_crypt_blob(&out, &in, &session_key, true);
1225                         memcpy(u.info18.nt_pwd.hash, out.data, out.length);
1226                 }
1227                 {
1228                         DATA_BLOB in,out;
1229                         in = data_blob_const(u.info18.lm_pwd.hash, 16);
1230                         out = data_blob_talloc_zero(tctx, 16);
1231                         sess_crypt_blob(&out, &in, &session_key, true);
1232                         memcpy(u.info18.lm_pwd.hash, out.data, out.length);
1233                 }
1234
1235                 break;
1236         case 21:
1237                 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1238                         DATA_BLOB in,out;
1239                         in = data_blob_const(u.info21.lm_owf_password.array,
1240                                              u.info21.lm_owf_password.length);
1241                         out = data_blob_talloc_zero(tctx, 16);
1242                         sess_crypt_blob(&out, &in, &session_key, true);
1243                         u.info21.lm_owf_password.array = (uint16_t *)out.data;
1244                 }
1245                 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1246                         DATA_BLOB in,out;
1247                         in = data_blob_const(u.info21.nt_owf_password.array,
1248                                              u.info21.nt_owf_password.length);
1249                         out = data_blob_talloc_zero(tctx, 16);
1250                         sess_crypt_blob(&out, &in, &session_key, true);
1251                         u.info21.nt_owf_password.array = (uint16_t *)out.data;
1252                 }
1253                 break;
1254         case 23:
1255                 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
1256                 break;
1257         case 24:
1258                 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
1259                 break;
1260         case 25:
1261                 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
1262                 memcpy(&u.info25.password.data[516], confounder, 16);
1263                 break;
1264         case 26:
1265                 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
1266                 memcpy(&u.info26.password.data[516], confounder, 16);
1267                 break;
1268         }
1269
1270         if (use_setinfo2) {
1271                 status = dcerpc_samr_SetUserInfo2(p, tctx, &s2);
1272         } else {
1273                 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1274         }
1275
1276         if (!NT_STATUS_IS_OK(status)) {
1277                 if (fields_present == 0) {
1278                         expected_error = NT_STATUS_INVALID_PARAMETER;
1279                 }
1280                 if (fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
1281                         expected_error = NT_STATUS_ACCESS_DENIED;
1282                 }
1283         }
1284
1285         if (!NT_STATUS_IS_OK(expected_error)) {
1286                 if (use_setinfo2) {
1287                         torture_assert_ntstatus_equal(tctx,
1288                                 s2.out.result,
1289                                 expected_error, "SetUserInfo2 failed");
1290                 } else {
1291                         torture_assert_ntstatus_equal(tctx,
1292                                 s.out.result,
1293                                 expected_error, "SetUserInfo failed");
1294                 }
1295                 *matched_expected_error = true;
1296                 return true;
1297         }
1298
1299         if (!NT_STATUS_IS_OK(status)) {
1300                 torture_warning(tctx, "SetUserInfo%s level %u failed - %s\n",
1301                        use_setinfo2 ? "2":"", level, nt_errstr(status));
1302                 ret = false;
1303         } else {
1304                 *password = newpass;
1305         }
1306
1307         return ret;
1308 }
1309
1310 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1311                                struct policy_handle *handle)
1312 {
1313         NTSTATUS status;
1314         struct samr_SetAliasInfo r;
1315         struct samr_QueryAliasInfo q;
1316         union samr_AliasInfo *info;
1317         uint16_t levels[] = {2, 3};
1318         int i;
1319         bool ret = true;
1320
1321         /* Ignoring switch level 1, as that includes the number of members for the alias
1322          * and setting this to a wrong value might have negative consequences
1323          */
1324
1325         for (i=0;i<ARRAY_SIZE(levels);i++) {
1326                 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
1327
1328                 r.in.alias_handle = handle;
1329                 r.in.level = levels[i];
1330                 r.in.info  = talloc(tctx, union samr_AliasInfo);
1331                 switch (r.in.level) {
1332                     case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
1333                     case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
1334                                 "Test Description, should test I18N as well"); break;
1335                     case ALIASINFOALL: torture_comment(tctx, "ALIASINFOALL ignored\n"); break;
1336                 }
1337
1338                 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
1339                 if (!NT_STATUS_IS_OK(status)) {
1340                         torture_warning(tctx, "SetAliasInfo level %u failed - %s\n",
1341                                levels[i], nt_errstr(status));
1342                         ret = false;
1343                 }
1344
1345                 q.in.alias_handle = handle;
1346                 q.in.level = levels[i];
1347                 q.out.info = &info;
1348
1349                 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
1350                 if (!NT_STATUS_IS_OK(status)) {
1351                         torture_warning(tctx, "QueryAliasInfo level %u failed - %s\n",
1352                                levels[i], nt_errstr(status));
1353                         ret = false;
1354                 }
1355         }
1356
1357         return ret;
1358 }
1359
1360 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1361                                   struct policy_handle *user_handle)
1362 {
1363         struct samr_GetGroupsForUser r;
1364         struct samr_RidWithAttributeArray *rids = NULL;
1365         NTSTATUS status;
1366
1367         torture_comment(tctx, "testing GetGroupsForUser\n");
1368
1369         r.in.user_handle = user_handle;
1370         r.out.rids = &rids;
1371
1372         status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
1373         torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
1374
1375         return true;
1376
1377 }
1378
1379 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1380                               struct lsa_String *domain_name)
1381 {
1382         NTSTATUS status;
1383         struct samr_GetDomPwInfo r;
1384         struct samr_PwInfo info;
1385
1386         r.in.domain_name = domain_name;
1387         r.out.info = &info;
1388
1389         torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1390
1391         status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1392         torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1393
1394         r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1395         torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1396
1397         status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1398         torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1399
1400         r.in.domain_name->string = "\\\\__NONAME__";
1401         torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1402
1403         status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1404         torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1405
1406         r.in.domain_name->string = "\\\\Builtin";
1407         torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1408
1409         status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1410         torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1411
1412         return true;
1413 }
1414
1415 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1416                                struct policy_handle *handle)
1417 {
1418         NTSTATUS status;
1419         struct samr_GetUserPwInfo r;
1420         struct samr_PwInfo info;
1421
1422         torture_comment(tctx, "Testing GetUserPwInfo\n");
1423
1424         r.in.user_handle = handle;
1425         r.out.info = &info;
1426
1427         status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
1428         torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
1429
1430         return true;
1431 }
1432
1433 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
1434                                 struct policy_handle *domain_handle, const char *name,
1435                                 uint32_t *rid)
1436 {
1437         NTSTATUS status;
1438         struct samr_LookupNames n;
1439         struct lsa_String sname[2];
1440         struct samr_Ids rids, types;
1441
1442         init_lsa_String(&sname[0], name);
1443
1444         n.in.domain_handle = domain_handle;
1445         n.in.num_names = 1;
1446         n.in.names = sname;
1447         n.out.rids = &rids;
1448         n.out.types = &types;
1449         status = dcerpc_samr_LookupNames(p, tctx, &n);
1450         if (NT_STATUS_IS_OK(status)) {
1451                 *rid = n.out.rids->ids[0];
1452         } else {
1453                 return status;
1454         }
1455
1456         init_lsa_String(&sname[1], "xxNONAMExx");
1457         n.in.num_names = 2;
1458         status = dcerpc_samr_LookupNames(p, tctx, &n);
1459         if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
1460                 torture_warning(tctx, "LookupNames[2] failed - %s\n", nt_errstr(status));
1461                 if (NT_STATUS_IS_OK(status)) {
1462                         return NT_STATUS_UNSUCCESSFUL;
1463                 }
1464                 return status;
1465         }
1466
1467         n.in.num_names = 0;
1468         status = dcerpc_samr_LookupNames(p, tctx, &n);
1469         if (!NT_STATUS_IS_OK(status)) {
1470                 torture_warning(tctx, "LookupNames[0] failed - %s\n", nt_errstr(status));
1471                 return status;
1472         }
1473
1474         init_lsa_String(&sname[0], "xxNONAMExx");
1475         n.in.num_names = 1;
1476         status = dcerpc_samr_LookupNames(p, tctx, &n);
1477         if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1478                 torture_warning(tctx, "LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
1479                 if (NT_STATUS_IS_OK(status)) {
1480                         return NT_STATUS_UNSUCCESSFUL;
1481                 }
1482                 return status;
1483         }
1484
1485         init_lsa_String(&sname[0], "xxNONAMExx");
1486         init_lsa_String(&sname[1], "xxNONAME2xx");
1487         n.in.num_names = 2;
1488         status = dcerpc_samr_LookupNames(p, tctx, &n);
1489         if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1490                 torture_warning(tctx, "LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
1491                 if (NT_STATUS_IS_OK(status)) {
1492                         return NT_STATUS_UNSUCCESSFUL;
1493                 }
1494                 return status;
1495         }
1496
1497         return NT_STATUS_OK;
1498 }
1499
1500 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p,
1501                                      struct torture_context *tctx,
1502                                      struct policy_handle *domain_handle,
1503                                      const char *name, struct policy_handle *user_handle)
1504 {
1505         NTSTATUS status;
1506         struct samr_OpenUser r;
1507         uint32_t rid;
1508
1509         status = test_LookupName(p, tctx, domain_handle, name, &rid);
1510         if (!NT_STATUS_IS_OK(status)) {
1511                 return status;
1512         }
1513
1514         r.in.domain_handle = domain_handle;
1515         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1516         r.in.rid = rid;
1517         r.out.user_handle = user_handle;
1518         status = dcerpc_samr_OpenUser(p, tctx, &r);
1519         if (!NT_STATUS_IS_OK(status)) {
1520                 torture_warning(tctx, "OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1521         }
1522
1523         return status;
1524 }
1525
1526 #if 0
1527 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p,
1528                                    struct torture_context *tctx,
1529                                    struct policy_handle *handle)
1530 {
1531         NTSTATUS status;
1532         struct samr_ChangePasswordUser r;
1533         bool ret = true;
1534         struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1535         struct policy_handle user_handle;
1536         char *oldpass = "test";
1537         char *newpass = "test2";
1538         uint8_t old_nt_hash[16], new_nt_hash[16];
1539         uint8_t old_lm_hash[16], new_lm_hash[16];
1540
1541         status = test_OpenUser_byname(p, tctx, handle, "testuser", &user_handle);
1542         if (!NT_STATUS_IS_OK(status)) {
1543                 return false;
1544         }
1545
1546         torture_comment(tctx, "Testing ChangePasswordUser for user 'testuser'\n");
1547
1548         torture_comment(tctx, "old password: %s\n", oldpass);
1549         torture_comment(tctx, "new password: %s\n", newpass);
1550
1551         E_md4hash(oldpass, old_nt_hash);
1552         E_md4hash(newpass, new_nt_hash);
1553         E_deshash(oldpass, old_lm_hash);
1554         E_deshash(newpass, new_lm_hash);
1555
1556         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1557         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1558         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1559         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1560         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1561         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1562
1563         r.in.handle = &user_handle;
1564         r.in.lm_present = 1;
1565         r.in.old_lm_crypted = &hash1;
1566         r.in.new_lm_crypted = &hash2;
1567         r.in.nt_present = 1;
1568         r.in.old_nt_crypted = &hash3;
1569         r.in.new_nt_crypted = &hash4;
1570         r.in.cross1_present = 1;
1571         r.in.nt_cross = &hash5;
1572         r.in.cross2_present = 1;
1573         r.in.lm_cross = &hash6;
1574
1575         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1576         if (!NT_STATUS_IS_OK(status)) {
1577                 torture_warning(tctx, "ChangePasswordUser failed - %s\n", nt_errstr(status));
1578                 ret = false;
1579         }
1580
1581         if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1582                 ret = false;
1583         }
1584
1585         return ret;
1586 }
1587 #endif
1588
1589 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1590                                     const char *acct_name,
1591                                     struct policy_handle *handle, char **password)
1592 {
1593         NTSTATUS status;
1594         struct samr_ChangePasswordUser r;
1595         bool ret = true;
1596         struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1597         struct policy_handle user_handle;
1598         char *oldpass;
1599         uint8_t old_nt_hash[16], new_nt_hash[16];
1600         uint8_t old_lm_hash[16], new_lm_hash[16];
1601         bool changed = true;
1602
1603         char *newpass;
1604         struct samr_GetUserPwInfo pwp;
1605         struct samr_PwInfo info;
1606         int policy_min_pw_len = 0;
1607
1608         status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle);
1609         if (!NT_STATUS_IS_OK(status)) {
1610                 return false;
1611         }
1612         pwp.in.user_handle = &user_handle;
1613         pwp.out.info = &info;
1614
1615         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1616         if (NT_STATUS_IS_OK(status)) {
1617                 policy_min_pw_len = pwp.out.info->min_password_length;
1618         }
1619         newpass = samr_rand_pass(tctx, policy_min_pw_len);
1620
1621         torture_comment(tctx, "Testing ChangePasswordUser\n");
1622
1623         torture_assert(tctx, *password != NULL,
1624                                    "Failing ChangePasswordUser as old password was NULL.  Previous test failed?");
1625
1626         oldpass = *password;
1627
1628         E_md4hash(oldpass, old_nt_hash);
1629         E_md4hash(newpass, new_nt_hash);
1630         E_deshash(oldpass, old_lm_hash);
1631         E_deshash(newpass, new_lm_hash);
1632
1633         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1634         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1635         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1636         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1637         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1638         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1639
1640         r.in.user_handle = &user_handle;
1641         r.in.lm_present = 1;
1642         /* Break the LM hash */
1643         hash1.hash[0]++;
1644         r.in.old_lm_crypted = &hash1;
1645         r.in.new_lm_crypted = &hash2;
1646         r.in.nt_present = 1;
1647         r.in.old_nt_crypted = &hash3;
1648         r.in.new_nt_crypted = &hash4;
1649         r.in.cross1_present = 1;
1650         r.in.nt_cross = &hash5;
1651         r.in.cross2_present = 1;
1652         r.in.lm_cross = &hash6;
1653
1654         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1655         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1656                 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1657
1658         /* Unbreak the LM hash */
1659         hash1.hash[0]--;
1660
1661         r.in.user_handle = &user_handle;
1662         r.in.lm_present = 1;
1663         r.in.old_lm_crypted = &hash1;
1664         r.in.new_lm_crypted = &hash2;
1665         /* Break the NT hash */
1666         hash3.hash[0]--;
1667         r.in.nt_present = 1;
1668         r.in.old_nt_crypted = &hash3;
1669         r.in.new_nt_crypted = &hash4;
1670         r.in.cross1_present = 1;
1671         r.in.nt_cross = &hash5;
1672         r.in.cross2_present = 1;
1673         r.in.lm_cross = &hash6;
1674
1675         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1676         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1677                 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1678
1679         /* Unbreak the NT hash */
1680         hash3.hash[0]--;
1681
1682         r.in.user_handle = &user_handle;
1683         r.in.lm_present = 1;
1684         r.in.old_lm_crypted = &hash1;
1685         r.in.new_lm_crypted = &hash2;
1686         r.in.nt_present = 1;
1687         r.in.old_nt_crypted = &hash3;
1688         r.in.new_nt_crypted = &hash4;
1689         r.in.cross1_present = 1;
1690         r.in.nt_cross = &hash5;
1691         r.in.cross2_present = 1;
1692         /* Break the LM cross */
1693         hash6.hash[0]++;
1694         r.in.lm_cross = &hash6;
1695
1696         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1697         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1698                 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1699                 ret = false;
1700         }
1701
1702         /* Unbreak the LM cross */
1703         hash6.hash[0]--;
1704
1705         r.in.user_handle = &user_handle;
1706         r.in.lm_present = 1;
1707         r.in.old_lm_crypted = &hash1;
1708         r.in.new_lm_crypted = &hash2;
1709         r.in.nt_present = 1;
1710         r.in.old_nt_crypted = &hash3;
1711         r.in.new_nt_crypted = &hash4;
1712         r.in.cross1_present = 1;
1713         /* Break the NT cross */
1714         hash5.hash[0]++;
1715         r.in.nt_cross = &hash5;
1716         r.in.cross2_present = 1;
1717         r.in.lm_cross = &hash6;
1718
1719         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1720         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1721                 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1722                 ret = false;
1723         }
1724
1725         /* Unbreak the NT cross */
1726         hash5.hash[0]--;
1727
1728
1729         /* Reset the hashes to not broken values */
1730         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1731         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1732         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1733         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1734         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1735         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1736
1737         r.in.user_handle = &user_handle;
1738         r.in.lm_present = 1;
1739         r.in.old_lm_crypted = &hash1;
1740         r.in.new_lm_crypted = &hash2;
1741         r.in.nt_present = 1;
1742         r.in.old_nt_crypted = &hash3;
1743         r.in.new_nt_crypted = &hash4;
1744         r.in.cross1_present = 1;
1745         r.in.nt_cross = &hash5;
1746         r.in.cross2_present = 0;
1747         r.in.lm_cross = NULL;
1748
1749         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1750         if (NT_STATUS_IS_OK(status)) {
1751                 changed = true;
1752                 *password = newpass;
1753         } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1754                 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1755                 ret = false;
1756         }
1757
1758         oldpass = newpass;
1759         newpass = samr_rand_pass(tctx, policy_min_pw_len);
1760
1761         E_md4hash(oldpass, old_nt_hash);
1762         E_md4hash(newpass, new_nt_hash);
1763         E_deshash(oldpass, old_lm_hash);
1764         E_deshash(newpass, new_lm_hash);
1765
1766
1767         /* Reset the hashes to not broken values */
1768         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1769         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1770         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1771         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1772         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1773         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1774
1775         r.in.user_handle = &user_handle;
1776         r.in.lm_present = 1;
1777         r.in.old_lm_crypted = &hash1;
1778         r.in.new_lm_crypted = &hash2;
1779         r.in.nt_present = 1;
1780         r.in.old_nt_crypted = &hash3;
1781         r.in.new_nt_crypted = &hash4;
1782         r.in.cross1_present = 0;
1783         r.in.nt_cross = NULL;
1784         r.in.cross2_present = 1;
1785         r.in.lm_cross = &hash6;
1786
1787         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1788         if (NT_STATUS_IS_OK(status)) {
1789                 changed = true;
1790                 *password = newpass;
1791         } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1792                 torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1793                 ret = false;
1794         }
1795
1796         oldpass = newpass;
1797         newpass = samr_rand_pass(tctx, policy_min_pw_len);
1798
1799         E_md4hash(oldpass, old_nt_hash);
1800         E_md4hash(newpass, new_nt_hash);
1801         E_deshash(oldpass, old_lm_hash);
1802         E_deshash(newpass, new_lm_hash);
1803
1804
1805         /* Reset the hashes to not broken values */
1806         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1807         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1808         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1809         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1810         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1811         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1812
1813         r.in.user_handle = &user_handle;
1814         r.in.lm_present = 1;
1815         r.in.old_lm_crypted = &hash1;
1816         r.in.new_lm_crypted = &hash2;
1817         r.in.nt_present = 1;
1818         r.in.old_nt_crypted = &hash3;
1819         r.in.new_nt_crypted = &hash4;
1820         r.in.cross1_present = 1;
1821         r.in.nt_cross = &hash5;
1822         r.in.cross2_present = 1;
1823         r.in.lm_cross = &hash6;
1824
1825         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1826         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1827                 torture_comment(tctx, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1828         } else  if (!NT_STATUS_IS_OK(status)) {
1829                 torture_warning(tctx, "ChangePasswordUser failed - %s\n", nt_errstr(status));
1830                 ret = false;
1831         } else {
1832                 changed = true;
1833                 *password = newpass;
1834         }
1835
1836         r.in.user_handle = &user_handle;
1837         r.in.lm_present = 1;
1838         r.in.old_lm_crypted = &hash1;
1839         r.in.new_lm_crypted = &hash2;
1840         r.in.nt_present = 1;
1841         r.in.old_nt_crypted = &hash3;
1842         r.in.new_nt_crypted = &hash4;
1843         r.in.cross1_present = 1;
1844         r.in.nt_cross = &hash5;
1845         r.in.cross2_present = 1;
1846         r.in.lm_cross = &hash6;
1847
1848         if (changed) {
1849                 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1850                 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1851                         torture_comment(tctx, "ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1852                 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1853                         torture_warning(tctx, "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1854                         ret = false;
1855                 }
1856         }
1857
1858
1859         if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1860                 ret = false;
1861         }
1862
1863         return ret;
1864 }
1865
1866
1867 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1868                                         const char *acct_name,
1869                                         struct policy_handle *handle, char **password)
1870 {
1871         NTSTATUS status;
1872         struct samr_OemChangePasswordUser2 r;
1873         bool ret = true;
1874         struct samr_Password lm_verifier;
1875         struct samr_CryptPassword lm_pass;
1876         struct lsa_AsciiString server, account, account_bad;
1877         char *oldpass;
1878         char *newpass;
1879         uint8_t old_lm_hash[16], new_lm_hash[16];
1880
1881         struct samr_GetDomPwInfo dom_pw_info;
1882         struct samr_PwInfo info;
1883         int policy_min_pw_len = 0;
1884
1885         struct lsa_String domain_name;
1886
1887         domain_name.string = "";
1888         dom_pw_info.in.domain_name = &domain_name;
1889         dom_pw_info.out.info = &info;
1890
1891         torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1892
1893         torture_assert(tctx, *password != NULL,
1894                                    "Failing OemChangePasswordUser2 as old password was NULL.  Previous test failed?");
1895
1896         oldpass = *password;
1897
1898         status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1899         if (NT_STATUS_IS_OK(status)) {
1900                 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1901         }
1902
1903         newpass = samr_rand_pass(tctx, policy_min_pw_len);
1904
1905         server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1906         account.string = acct_name;
1907
1908         E_deshash(oldpass, old_lm_hash);
1909         E_deshash(newpass, new_lm_hash);
1910
1911         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1912         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1913         E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1914
1915         r.in.server = &server;
1916         r.in.account = &account;
1917         r.in.password = &lm_pass;
1918         r.in.hash = &lm_verifier;
1919
1920         /* Break the verification */
1921         lm_verifier.hash[0]++;
1922
1923         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1924
1925         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1926             && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1927                 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1928                         nt_errstr(status));
1929                 ret = false;
1930         }
1931
1932         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1933         /* Break the old password */
1934         old_lm_hash[0]++;
1935         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1936         /* unbreak it for the next operation */
1937         old_lm_hash[0]--;
1938         E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1939
1940         r.in.server = &server;
1941         r.in.account = &account;
1942         r.in.password = &lm_pass;
1943         r.in.hash = &lm_verifier;
1944
1945         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1946
1947         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1948             && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1949                 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1950                         nt_errstr(status));
1951                 ret = false;
1952         }
1953
1954         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1955         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1956
1957         r.in.server = &server;
1958         r.in.account = &account;
1959         r.in.password = &lm_pass;
1960         r.in.hash = NULL;
1961
1962         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1963
1964         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1965             && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1966                 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1967                         nt_errstr(status));
1968                 ret = false;
1969         }
1970
1971         /* This shouldn't be a valid name */
1972         account_bad.string = TEST_ACCOUNT_NAME "XX";
1973         r.in.account = &account_bad;
1974
1975         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1976
1977         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1978                 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1979                         nt_errstr(status));
1980                 ret = false;
1981         }
1982
1983         /* This shouldn't be a valid name */
1984         account_bad.string = TEST_ACCOUNT_NAME "XX";
1985         r.in.account = &account_bad;
1986         r.in.password = &lm_pass;
1987         r.in.hash = &lm_verifier;
1988
1989         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1990
1991         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1992                 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1993                         nt_errstr(status));
1994                 ret = false;
1995         }
1996
1997         /* This shouldn't be a valid name */
1998         account_bad.string = TEST_ACCOUNT_NAME "XX";
1999         r.in.account = &account_bad;
2000         r.in.password = NULL;
2001         r.in.hash = &lm_verifier;
2002
2003         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
2004
2005         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
2006                 torture_warning(tctx, "OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
2007                         nt_errstr(status));
2008                 ret = false;
2009         }
2010
2011         E_deshash(oldpass, old_lm_hash);
2012         E_deshash(newpass, new_lm_hash);
2013
2014         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
2015         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2016         E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
2017
2018         r.in.server = &server;
2019         r.in.account = &account;
2020         r.in.password = &lm_pass;
2021         r.in.hash = &lm_verifier;
2022
2023         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
2024         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2025                 torture_comment(tctx, "OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
2026         } else if (!NT_STATUS_IS_OK(status)) {
2027                 torture_warning(tctx, "OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
2028                 ret = false;
2029         } else {
2030                 *password = newpass;
2031         }
2032
2033         return ret;
2034 }
2035
2036
2037 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
2038                                      const char *acct_name,
2039                                      char **password,
2040                                      char *newpass, bool allow_password_restriction)
2041 {
2042         NTSTATUS status;
2043         struct samr_ChangePasswordUser2 r;
2044         bool ret = true;
2045         struct lsa_String server, account;
2046         struct samr_CryptPassword nt_pass, lm_pass;
2047         struct samr_Password nt_verifier, lm_verifier;
2048         char *oldpass;
2049         uint8_t old_nt_hash[16], new_nt_hash[16];
2050         uint8_t old_lm_hash[16], new_lm_hash[16];
2051
2052         struct samr_GetDomPwInfo dom_pw_info;
2053         struct samr_PwInfo info;
2054
2055         struct lsa_String domain_name;
2056
2057         domain_name.string = "";
2058         dom_pw_info.in.domain_name = &domain_name;
2059         dom_pw_info.out.info = &info;
2060
2061         torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
2062
2063         torture_assert(tctx, *password != NULL,
2064                                    "Failing ChangePasswordUser2 as old password was NULL.  Previous test failed?");
2065         oldpass = *password;
2066
2067         if (!newpass) {
2068                 int policy_min_pw_len = 0;
2069                 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
2070                 if (NT_STATUS_IS_OK(status)) {
2071                         policy_min_pw_len = dom_pw_info.out.info->min_password_length;
2072                 }
2073
2074                 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2075         }
2076
2077         server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2078         init_lsa_String(&account, acct_name);
2079
2080         E_md4hash(oldpass, old_nt_hash);
2081         E_md4hash(newpass, new_nt_hash);
2082
2083         E_deshash(oldpass, old_lm_hash);
2084         E_deshash(newpass, new_lm_hash);
2085
2086         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
2087         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2088         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2089
2090         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2091         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2092         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2093
2094         r.in.server = &server;
2095         r.in.account = &account;
2096         r.in.nt_password = &nt_pass;
2097         r.in.nt_verifier = &nt_verifier;
2098         r.in.lm_change = 1;
2099         r.in.lm_password = &lm_pass;
2100         r.in.lm_verifier = &lm_verifier;
2101
2102         status = dcerpc_samr_ChangePasswordUser2(p, tctx, &r);
2103         if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2104                 torture_comment(tctx, "ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
2105         } else if (!NT_STATUS_IS_OK(status)) {
2106                 torture_warning(tctx, "ChangePasswordUser2 failed - %s\n", nt_errstr(status));
2107                 ret = false;
2108         } else {
2109                 *password = newpass;
2110         }
2111
2112         return ret;
2113 }
2114
2115
2116 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
2117                               const char *account_string,
2118                               int policy_min_pw_len,
2119                               char **password,
2120                               const char *newpass,
2121                               NTTIME last_password_change,
2122                               bool handle_reject_reason)
2123 {
2124         NTSTATUS status;
2125         struct samr_ChangePasswordUser3 r;
2126         bool ret = true;
2127         struct lsa_String server, account, account_bad;
2128         struct samr_CryptPassword nt_pass, lm_pass;
2129         struct samr_Password nt_verifier, lm_verifier;
2130         char *oldpass;
2131         uint8_t old_nt_hash[16], new_nt_hash[16];
2132         uint8_t old_lm_hash[16], new_lm_hash[16];
2133         NTTIME t;
2134         struct samr_DomInfo1 *dominfo = NULL;
2135         struct userPwdChangeFailureInformation *reject = NULL;
2136
2137         torture_comment(tctx, "Testing ChangePasswordUser3\n");
2138
2139         if (newpass == NULL) {
2140                 do {
2141                         if (policy_min_pw_len == 0) {
2142                                 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2143                         } else {
2144                                 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
2145                         }
2146                 } while (check_password_quality(newpass) == false);
2147         } else {
2148                 torture_comment(tctx, "Using password '%s'\n", newpass);
2149         }
2150
2151         torture_assert(tctx, *password != NULL,
2152                                    "Failing ChangePasswordUser3 as old password was NULL.  Previous test failed?");
2153
2154         oldpass = *password;
2155         server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2156         init_lsa_String(&account, account_string);
2157
2158         E_md4hash(oldpass, old_nt_hash);
2159         E_md4hash(newpass, new_nt_hash);
2160
2161         E_deshash(oldpass, old_lm_hash);
2162         E_deshash(newpass, new_lm_hash);
2163
2164         encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2165         arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2166         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2167
2168         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2169         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2170         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2171
2172         /* Break the verification */
2173         nt_verifier.hash[0]++;
2174
2175         r.in.server = &server;
2176         r.in.account = &account;
2177         r.in.nt_password = &nt_pass;
2178         r.in.nt_verifier = &nt_verifier;
2179         r.in.lm_change = 1;
2180         r.in.lm_password = &lm_pass;
2181         r.in.lm_verifier = &lm_verifier;
2182         r.in.password3 = NULL;
2183         r.out.dominfo = &dominfo;
2184         r.out.reject = &reject;
2185
2186         status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2187         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2188             (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2189                 torture_warning(tctx, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2190                         nt_errstr(status));
2191                 ret = false;
2192         }
2193
2194         encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2195         arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2196         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2197
2198         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2199         /* Break the NT hash */
2200         old_nt_hash[0]++;
2201         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2202         /* Unbreak it again */
2203         old_nt_hash[0]--;
2204         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2205
2206         r.in.server = &server;
2207         r.in.account = &account;
2208         r.in.nt_password = &nt_pass;
2209         r.in.nt_verifier = &nt_verifier;
2210         r.in.lm_change = 1;
2211         r.in.lm_password = &lm_pass;
2212         r.in.lm_verifier = &lm_verifier;
2213         r.in.password3 = NULL;
2214         r.out.dominfo = &dominfo;
2215         r.out.reject = &reject;
2216
2217         status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2218         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2219             (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2220                 torture_warning(tctx, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2221                         nt_errstr(status));
2222                 ret = false;
2223         }
2224
2225         /* This shouldn't be a valid name */
2226         init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
2227
2228         r.in.account = &account_bad;
2229         status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2230         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
2231                 torture_warning(tctx, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
2232                         nt_errstr(status));
2233                 ret = false;
2234         }
2235
2236         E_md4hash(oldpass, old_nt_hash);
2237         E_md4hash(newpass, new_nt_hash);
2238
2239         E_deshash(oldpass, old_lm_hash);
2240         E_deshash(newpass, new_lm_hash);
2241
2242         encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2243         arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2244         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2245
2246         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2247         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2248         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2249
2250         r.in.server = &server;
2251         r.in.account = &account;
2252         r.in.nt_password = &nt_pass;
2253         r.in.nt_verifier = &nt_verifier;
2254         r.in.lm_change = 1;
2255         r.in.lm_password = &lm_pass;
2256         r.in.lm_verifier = &lm_verifier;
2257         r.in.password3 = NULL;
2258         r.out.dominfo = &dominfo;
2259         r.out.reject = &reject;
2260
2261         unix_to_nt_time(&t, time(NULL));
2262
2263         status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2264
2265         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
2266             && dominfo
2267             && reject
2268             && handle_reject_reason
2269             && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
2270                 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
2271
2272                         if (reject && (reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR)) {
2273                                 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2274                                         SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2275                                 return false;
2276                         }
2277                 }
2278
2279                 /* We tested the order of precendence which is as follows:
2280
2281                 * pwd min_age
2282                 * pwd length
2283                 * pwd complexity
2284                 * pwd history
2285
2286                 Guenther */
2287
2288                 if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
2289                            (last_password_change + dominfo->min_password_age > t)) {
2290
2291                         if (reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2292                                 torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2293                                         SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2294                                 return false;
2295                         }
2296
2297                 } else if ((dominfo->min_password_length > 0) &&
2298                            (strlen(newpass) < dominfo->min_password_length)) {
2299
2300                         if (reject->extendedFailureReason != SAM_PWD_CHANGE_PASSWORD_TOO_SHORT) {
2301                                 torture_warning(tctx, "expected SAM_PWD_CHANGE_PASSWORD_TOO_SHORT (%d), got %d\n",
2302                                         SAM_PWD_CHANGE_PASSWORD_TOO_SHORT, reject->extendedFailureReason);
2303                                 return false;
2304                         }
2305
2306                 } else if ((dominfo->password_history_length > 0) &&
2307                             strequal(oldpass, newpass)) {
2308
2309                         if (reject->extendedFailureReason != SAM_PWD_CHANGE_PWD_IN_HISTORY) {
2310                                 torture_warning(tctx, "expected SAM_PWD_CHANGE_PWD_IN_HISTORY (%d), got %d\n",
2311                                         SAM_PWD_CHANGE_PWD_IN_HISTORY, reject->extendedFailureReason);
2312                                 return false;
2313                         }
2314                 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
2315
2316                         if (reject->extendedFailureReason != SAM_PWD_CHANGE_NOT_COMPLEX) {
2317                                 torture_warning(tctx, "expected SAM_PWD_CHANGE_NOT_COMPLEX (%d), got %d\n",
2318                                         SAM_PWD_CHANGE_NOT_COMPLEX, reject->extendedFailureReason);
2319                                 return false;
2320                         }
2321
2322                 }
2323
2324                 if (reject->extendedFailureReason == SAM_PWD_CHANGE_PASSWORD_TOO_SHORT) {
2325                         /* retry with adjusted size */
2326                         return test_ChangePasswordUser3(p, tctx, account_string,
2327                                                         dominfo->min_password_length,
2328                                                         password, NULL, 0, false);
2329
2330                 }
2331
2332         } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2333                 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2334                         torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2335                                SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2336                         return false;
2337                 }
2338                 /* Perhaps the server has a 'min password age' set? */
2339
2340         } else {
2341                 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3");
2342                 *password = talloc_strdup(tctx, newpass);
2343         }
2344
2345         return ret;
2346 }
2347
2348 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
2349                                     const char *account_string,
2350                                     struct policy_handle *handle,
2351                                     char **password)
2352 {
2353         NTSTATUS status;
2354         struct samr_ChangePasswordUser3 r;
2355         struct samr_SetUserInfo s;
2356         union samr_UserInfo u;
2357         DATA_BLOB session_key;
2358         DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
2359         uint8_t confounder[16];
2360         struct MD5Context ctx;
2361
2362         bool ret = true;
2363         struct lsa_String server, account;
2364         struct samr_CryptPassword nt_pass;
2365         struct samr_Password nt_verifier;
2366         DATA_BLOB new_random_pass;
2367         char *newpass;
2368         char *oldpass;
2369         uint8_t old_nt_hash[16], new_nt_hash[16];
2370         NTTIME t;
2371         struct samr_DomInfo1 *dominfo = NULL;
2372         struct userPwdChangeFailureInformation *reject = NULL;
2373
2374         new_random_pass = samr_very_rand_pass(tctx, 128);
2375
2376         torture_assert(tctx, *password != NULL,
2377                                    "Failing ChangePasswordUser3 as old password was NULL.  Previous test failed?");
2378
2379         oldpass = *password;
2380         server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2381         init_lsa_String(&account, account_string);
2382
2383         s.in.user_handle = handle;
2384         s.in.info = &u;
2385         s.in.level = 25;
2386
2387         ZERO_STRUCT(u);
2388
2389         u.info25.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT;
2390
2391         set_pw_in_buffer(u.info25.password.data, &new_random_pass);
2392
2393         status = dcerpc_fetch_session_key(p, &session_key);
2394         if (!NT_STATUS_IS_OK(status)) {
2395                 torture_warning(tctx, "SetUserInfo level %u - no session key - %s\n",
2396                        s.in.level, nt_errstr(status));
2397                 return false;
2398         }
2399
2400         generate_random_buffer((uint8_t *)confounder, 16);
2401
2402         MD5Init(&ctx);
2403         MD5Update(&ctx, confounder, 16);
2404         MD5Update(&ctx, session_key.data, session_key.length);
2405         MD5Final(confounded_session_key.data, &ctx);
2406
2407         arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
2408         memcpy(&u.info25.password.data[516], confounder, 16);
2409
2410         torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2411
2412         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
2413         if (!NT_STATUS_IS_OK(status)) {
2414                 torture_warning(tctx, "SetUserInfo level %u failed - %s\n",
2415                        s.in.level, nt_errstr(status));
2416                 ret = false;
2417         }
2418
2419         torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2420
2421         mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2422
2423         new_random_pass = samr_very_rand_pass(tctx, 128);
2424
2425         mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
2426
2427         set_pw_in_buffer(nt_pass.data, &new_random_pass);
2428         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2429         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2430
2431         r.in.server = &server;
2432         r.in.account = &account;
2433         r.in.nt_password = &nt_pass;
2434         r.in.nt_verifier = &nt_verifier;
2435         r.in.lm_change = 0;
2436         r.in.lm_password = NULL;
2437         r.in.lm_verifier = NULL;
2438         r.in.password3 = NULL;
2439         r.out.dominfo = &dominfo;
2440         r.out.reject = &reject;
2441
2442         unix_to_nt_time(&t, time(NULL));
2443
2444         status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2445
2446         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2447                 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2448                         torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2449                                SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2450                         return false;
2451                 }
2452                 /* Perhaps the server has a 'min password age' set? */
2453
2454         } else if (!NT_STATUS_IS_OK(status)) {
2455                 torture_warning(tctx, "ChangePasswordUser3 failed - %s\n", nt_errstr(status));
2456                 ret = false;
2457         }
2458
2459         newpass = samr_rand_pass(tctx, 128);
2460
2461         mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2462
2463         E_md4hash(newpass, new_nt_hash);
2464
2465         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2466         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2467         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2468
2469         r.in.server = &server;
2470         r.in.account = &account;
2471         r.in.nt_password = &nt_pass;
2472         r.in.nt_verifier = &nt_verifier;
2473         r.in.lm_change = 0;
2474         r.in.lm_password = NULL;
2475         r.in.lm_verifier = NULL;
2476         r.in.password3 = NULL;
2477         r.out.dominfo = &dominfo;
2478         r.out.reject = &reject;
2479
2480         unix_to_nt_time(&t, time(NULL));
2481
2482         status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2483
2484         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2485                 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2486                         torture_warning(tctx, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2487                                SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2488                         return false;
2489                 }
2490                 /* Perhaps the server has a 'min password age' set? */
2491
2492         } else {
2493                 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3 (on second random password)");
2494                 *password = talloc_strdup(tctx, newpass);
2495         }
2496
2497         return ret;
2498 }
2499
2500
2501 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2502                                   struct policy_handle *alias_handle)
2503 {
2504         struct samr_GetMembersInAlias r;
2505         struct lsa_SidArray sids;
2506         NTSTATUS status;
2507
2508         torture_comment(tctx, "Testing GetMembersInAlias\n");
2509
2510         r.in.alias_handle = alias_handle;
2511         r.out.sids = &sids;
2512
2513         status = dcerpc_samr_GetMembersInAlias(p, tctx, &r);
2514         torture_assert_ntstatus_ok(tctx, status, "GetMembersInAlias");
2515
2516         return true;
2517 }
2518
2519 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2520                                   struct policy_handle *alias_handle,
2521                                   const struct dom_sid *domain_sid)
2522 {
2523         struct samr_AddAliasMember r;
2524         struct samr_DeleteAliasMember d;
2525         NTSTATUS status;
2526         struct dom_sid *sid;
2527
2528         sid = dom_sid_add_rid(tctx, domain_sid, 512);
2529
2530         torture_comment(tctx, "testing AddAliasMember\n");
2531         r.in.alias_handle = alias_handle;
2532         r.in.sid = sid;
2533
2534         status = dcerpc_samr_AddAliasMember(p, tctx, &r);
2535         torture_assert_ntstatus_ok(tctx, status, "AddAliasMember");
2536
2537         d.in.alias_handle = alias_handle;
2538         d.in.sid = sid;
2539
2540         status = dcerpc_samr_DeleteAliasMember(p, tctx, &d);
2541         torture_assert_ntstatus_ok(tctx, status, "DelAliasMember");
2542
2543         return true;
2544 }
2545
2546 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2547                                            struct policy_handle *alias_handle)
2548 {
2549         struct samr_AddMultipleMembersToAlias a;
2550         struct samr_RemoveMultipleMembersFromAlias r;
2551         NTSTATUS status;
2552         struct lsa_SidArray sids;
2553
2554         torture_comment(tctx, "testing AddMultipleMembersToAlias\n");
2555         a.in.alias_handle = alias_handle;
2556         a.in.sids = &sids;
2557
2558         sids.num_sids = 3;
2559         sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2560
2561         sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2562         sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2563         sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2564
2565         status = dcerpc_samr_AddMultipleMembersToAlias(p, tctx, &a);
2566         torture_assert_ntstatus_ok(tctx, status, "AddMultipleMembersToAlias");
2567
2568
2569         torture_comment(tctx, "testing RemoveMultipleMembersFromAlias\n");
2570         r.in.alias_handle = alias_handle;
2571         r.in.sids = &sids;
2572
2573         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2574         torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2575
2576         /* strange! removing twice doesn't give any error */
2577         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2578         torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2579
2580         /* but removing an alias that isn't there does */
2581         sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2582
2583         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2584         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2585
2586         return true;
2587 }
2588
2589 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2590                                             struct policy_handle *user_handle)
2591 {
2592         struct samr_TestPrivateFunctionsUser r;
2593         NTSTATUS status;
2594
2595         torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2596
2597         r.in.user_handle = user_handle;
2598
2599         status = dcerpc_samr_TestPrivateFunctionsUser(p, tctx, &r);
2600         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2601
2602         return true;
2603 }
2604
2605 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_pipe *p,
2606                                           struct torture_context *tctx,
2607                                           struct policy_handle *handle,
2608                                           bool use_info2,
2609                                           NTTIME *pwdlastset)
2610 {
2611         NTSTATUS status;
2612         uint16_t levels[] = { /* 3, */ 5, 21 };
2613         int i;
2614         NTTIME pwdlastset3 = 0;
2615         NTTIME pwdlastset5 = 0;
2616         NTTIME pwdlastset21 = 0;
2617
2618         torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
2619                         use_info2 ? "2":"");
2620
2621         for (i=0; i<ARRAY_SIZE(levels); i++) {
2622
2623                 struct samr_QueryUserInfo r;
2624                 struct samr_QueryUserInfo2 r2;
2625                 union samr_UserInfo *info;
2626
2627                 if (use_info2) {
2628                         r2.in.user_handle = handle;
2629                         r2.in.level = levels[i];
2630                         r2.out.info = &info;
2631                         status = dcerpc_samr_QueryUserInfo2(p, tctx, &r2);
2632
2633                 } else {
2634                         r.in.user_handle = handle;
2635                         r.in.level = levels[i];
2636                         r.out.info = &info;
2637                         status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
2638                 }
2639
2640                 if (!NT_STATUS_IS_OK(status) &&
2641                     !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2642                         torture_warning(tctx, "QueryUserInfo%s level %u failed - %s\n",
2643                                use_info2 ? "2":"", levels[i], nt_errstr(status));
2644                         return false;
2645                 }
2646
2647                 switch (levels[i]) {
2648                 case 3:
2649                         pwdlastset3 = info->info3.last_password_change;
2650                         break;
2651                 case 5:
2652                         pwdlastset5 = info->info5.last_password_change;
2653                         break;
2654                 case 21:
2655                         pwdlastset21 = info->info21.last_password_change;
2656                         break;
2657                 default:
2658                         return false;
2659                 }
2660         }
2661         /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2662                                     "pwdlastset mixup"); */
2663         torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
2664                                  "pwdlastset mixup");
2665
2666         *pwdlastset = pwdlastset21;
2667
2668         torture_comment(tctx, "(pwdlastset: %lld)\n", *pwdlastset);
2669
2670         return true;
2671 }
2672
2673 static bool test_SamLogon(struct torture_context *tctx,
2674                           struct dcerpc_pipe *p,
2675                           struct cli_credentials *test_credentials,
2676                           NTSTATUS expected_result)
2677 {
2678         NTSTATUS status;
2679         struct netr_LogonSamLogonEx r;
2680         union netr_LogonLevel logon;
2681         union netr_Validation validation;
2682         uint8_t authoritative;
2683         struct netr_NetworkInfo ninfo;
2684         DATA_BLOB names_blob, chal, lm_resp, nt_resp;
2685         int flags = CLI_CRED_NTLM_AUTH;
2686         uint32_t samlogon_flags = 0;
2687
2688         if (lp_client_lanman_auth(tctx->lp_ctx)) {
2689                 flags |= CLI_CRED_LANMAN_AUTH;
2690         }
2691
2692         if (lp_client_ntlmv2_auth(tctx->lp_ctx)) {
2693                 flags |= CLI_CRED_NTLMv2_AUTH;
2694         }
2695
2696         cli_credentials_get_ntlm_username_domain(test_credentials, tctx,
2697                                                  &ninfo.identity_info.account_name.string,
2698                                                  &ninfo.identity_info.domain_name.string);
2699
2700         generate_random_buffer(ninfo.challenge,
2701                                sizeof(ninfo.challenge));
2702         chal = data_blob_const(ninfo.challenge,
2703                                sizeof(ninfo.challenge));
2704
2705         names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(test_credentials),
2706                                                 cli_credentials_get_domain(test_credentials));
2707
2708         status = cli_credentials_get_ntlm_response(test_credentials, tctx,
2709                                                    &flags,
2710                                                    chal,
2711                                                    names_blob,
2712                                                    &lm_resp, &nt_resp,
2713                                                    NULL, NULL);
2714         torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
2715
2716         ninfo.lm.data = lm_resp.data;
2717         ninfo.lm.length = lm_resp.length;
2718
2719         ninfo.nt.data = nt_resp.data;
2720         ninfo.nt.length = nt_resp.length;
2721
2722         ninfo.identity_info.parameter_control =
2723                 MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT |
2724                 MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
2725         ninfo.identity_info.logon_id_low = 0;
2726         ninfo.identity_info.logon_id_high = 0;
2727         ninfo.identity_info.workstation.string = cli_credentials_get_workstation(test_credentials);
2728
2729         logon.network = &ninfo;
2730
2731         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2732         r.in.computer_name = cli_credentials_get_workstation(test_credentials);
2733         r.in.logon_level = NetlogonNetworkInformation;
2734         r.in.logon = &logon;
2735         r.in.flags = &samlogon_flags;
2736         r.out.flags = &samlogon_flags;
2737         r.out.validation = &validation;
2738         r.out.authoritative = &authoritative;
2739
2740         torture_comment(tctx, "Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
2741
2742         r.in.validation_level = 6;
2743
2744         status = dcerpc_netr_LogonSamLogonEx(p, tctx, &r);
2745         if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2746                 r.in.validation_level = 3;
2747                 status = dcerpc_netr_LogonSamLogonEx(p, tctx, &r);
2748         }
2749         if (!NT_STATUS_IS_OK(status)) {
2750                 torture_assert_ntstatus_equal(tctx, status, expected_result, "LogonSamLogonEx failed");
2751                 return true;
2752         } else {
2753                 torture_assert_ntstatus_ok(tctx, status, "LogonSamLogonEx failed");
2754         }
2755
2756         return true;
2757 }
2758
2759 static bool test_SamLogon_with_creds(struct torture_context *tctx,
2760                                      struct dcerpc_pipe *p,
2761                                      struct cli_credentials *machine_creds,
2762                                      const char *acct_name,
2763                                      char *password,
2764                                      NTSTATUS expected_samlogon_result)
2765 {
2766         bool ret = true;
2767         struct cli_credentials *test_credentials;
2768
2769         test_credentials = cli_credentials_init(tctx);
2770
2771         cli_credentials_set_workstation(test_credentials,
2772                                         cli_credentials_get_workstation(machine_creds), CRED_SPECIFIED);
2773         cli_credentials_set_domain(test_credentials,
2774                                    cli_credentials_get_domain(machine_creds), CRED_SPECIFIED);
2775         cli_credentials_set_username(test_credentials,
2776                                      acct_name, CRED_SPECIFIED);
2777         cli_credentials_set_password(test_credentials,
2778                                      password, CRED_SPECIFIED);
2779
2780         torture_comment(tctx, "testing samlogon as %s password: %s\n",
2781                 acct_name, password);
2782
2783         if (!test_SamLogon(tctx, p, test_credentials,
2784                            expected_samlogon_result)) {
2785                 torture_warning(tctx, "new password did not work\n");
2786                 ret = false;
2787         }
2788
2789         return ret;
2790 }
2791
2792 static bool test_SetPassword_level(struct dcerpc_pipe *p,
2793                                    struct dcerpc_pipe *np,
2794                                    struct torture_context *tctx,
2795                                    struct policy_handle *handle,
2796                                    uint16_t level,
2797                                    uint32_t fields_present,
2798                                    uint8_t password_expired,
2799                                    bool *matched_expected_error,
2800                                    bool use_setinfo2,
2801                                    const char *acct_name,
2802                                    char **password,
2803                                    struct cli_credentials *machine_creds,
2804                                    bool use_queryinfo2,
2805                                    NTTIME *pwdlastset,
2806                                    NTSTATUS expected_samlogon_result)
2807 {
2808         const char *fields = NULL;
2809         bool ret = true;
2810
2811         switch (level) {
2812         case 21:
2813         case 23:
2814         case 25:
2815                 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
2816                                          fields_present);
2817                 break;
2818         default:
2819                 break;
2820         }
2821
2822         torture_comment(tctx, "Testing SetUserInfo%s level %d call "
2823                 "(password_expired: %d) %s\n",
2824                 use_setinfo2 ? "2":"", level, password_expired,
2825                 fields ? fields : "");
2826
2827         if (!test_SetUserPass_level_ex(p, tctx, handle, level,
2828                                        fields_present,
2829                                        password,
2830                                        password_expired,
2831                                        use_setinfo2,
2832                                        matched_expected_error)) {
2833                 ret = false;
2834         }
2835
2836         if (!test_QueryUserInfo_pwdlastset(p, tctx, handle,
2837                                            use_queryinfo2,
2838                                            pwdlastset)) {
2839                 ret = false;
2840         }
2841
2842         if (*matched_expected_error == true) {
2843                 return ret;
2844         }
2845
2846         if (!test_SamLogon_with_creds(tctx, np,
2847                                       machine_creds,
2848                                       acct_name,
2849                                       *password,
2850                                       expected_samlogon_result)) {
2851                 ret = false;
2852         }
2853
2854         return ret;
2855 }
2856
2857 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
2858                                         struct torture_context *tctx,
2859                                         uint32_t acct_flags,
2860                                         const char *acct_name,
2861                                         struct policy_handle *handle,
2862                                         char **password,
2863                                         struct cli_credentials *machine_credentials)
2864 {
2865         int s = 0, q = 0, f = 0, l = 0, z = 0;
2866         struct dcerpc_binding *b;
2867         bool ret = true;
2868         int delay = 50000;
2869         bool set_levels[] = { false, true };
2870         bool query_levels[] = { false, true };
2871         uint32_t levels[] = { 18, 21, 26, 23, 24, 25 }; /* Second half only used when TEST_ALL_LEVELS defined */
2872         uint32_t nonzeros[] = { 1, 24 };
2873         uint32_t fields_present[] = {
2874                 0,
2875                 SAMR_FIELD_EXPIRED_FLAG,
2876                 SAMR_FIELD_LAST_PWD_CHANGE,
2877                 SAMR_FIELD_EXPIRED_FLAG | SAMR_FIELD_LAST_PWD_CHANGE,
2878                 SAMR_FIELD_COMMENT,
2879                 SAMR_FIELD_NT_PASSWORD_PRESENT,
2880                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2881                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
2882                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2883                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2884                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2885                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE | SAMR_FIELD_EXPIRED_FLAG
2886         };
2887         NTSTATUS status;
2888         struct dcerpc_pipe *np = NULL;
2889
2890         if (torture_setting_bool(tctx, "samba3", false)) {
2891                 delay = 999999;
2892                 torture_comment(tctx, "Samba3 has second granularity, setting delay to: %d\n",
2893                         delay);
2894         }
2895
2896         status = torture_rpc_binding(tctx, &b);
2897         if (!NT_STATUS_IS_OK(status)) {
2898                 ret = false;
2899                 return ret;
2900         }
2901
2902         /* We have to use schannel, otherwise the SamLogonEx fails
2903          * with INTERNAL_ERROR */
2904
2905         b->flags &= ~DCERPC_AUTH_OPTIONS;
2906         b->flags |= DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_128;
2907
2908         status = dcerpc_pipe_connect_b(tctx, &np, b,
2909                                        &ndr_table_netlogon,
2910                                        machine_credentials, tctx->ev, tctx->lp_ctx);
2911
2912         if (!NT_STATUS_IS_OK(status)) {
2913                 torture_warning(tctx, "RPC pipe connect as domain member failed: %s\n", nt_errstr(status));
2914                 ret = false;
2915                 return ret;
2916         }
2917
2918         /* set to 1 to enable testing for all possible opcode
2919            (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
2920            combinations */
2921 #if 0
2922 #define TEST_ALL_LEVELS 1
2923 #define TEST_SET_LEVELS 1
2924 #define TEST_QUERY_LEVELS 1
2925 #endif
2926 #ifdef TEST_ALL_LEVELS
2927         for (l=0; l<ARRAY_SIZE(levels); l++) {
2928 #else
2929         for (l=0; l<(ARRAY_SIZE(levels))/2; l++) {
2930 #endif
2931         for (z=0; z<ARRAY_SIZE(nonzeros); z++) {
2932         for (f=0; f<ARRAY_SIZE(fields_present); f++) {
2933 #ifdef TEST_SET_LEVELS
2934         for (s=0; s<ARRAY_SIZE(set_levels); s++) {
2935 #endif
2936 #ifdef TEST_QUERY_LEVELS
2937         for (q=0; q<ARRAY_SIZE(query_levels); q++) {
2938 #endif
2939                 NTTIME pwdlastset_old = 0;
2940                 NTTIME pwdlastset_new = 0;
2941                 bool matched_expected_error = false;
2942                 NTSTATUS expected_samlogon_result = NT_STATUS_ACCOUNT_DISABLED;
2943
2944                 torture_comment(tctx, "------------------------------\n"
2945                                 "Testing pwdLastSet attribute for flags: 0x%08x "
2946                                 "(s: %d (l: %d), q: %d)\n",
2947                                 acct_flags, s, levels[l], q);
2948
2949                 switch (levels[l]) {
2950                 case 21:
2951                 case 23:
2952                 case 25:
2953                         if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2954                               (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT))) {
2955                                 expected_samlogon_result = NT_STATUS_WRONG_PASSWORD;
2956                         }
2957                         break;
2958                 }
2959
2960
2961                 /* set #1 */
2962
2963                 /* set a password and force password change (pwdlastset 0) by
2964                  * setting the password expired flag to a non-0 value */
2965
2966                 if (!test_SetPassword_level(p, np, tctx, handle,
2967                                             levels[l],
2968                                             fields_present[f],
2969                                             nonzeros[z],
2970                                             &matched_expected_error,
2971                                             set_levels[s],
2972                                             acct_name,
2973                                             password,
2974                                             machine_credentials,
2975                                             query_levels[q],
2976                                             &pwdlastset_old,
2977                                             expected_samlogon_result)) {
2978                         ret = false;
2979                 }
2980
2981                 if (matched_expected_error == true) {
2982                         /* skipping on expected failure */
2983                         continue;
2984                 }
2985
2986                 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
2987                  * set without the SAMR_FIELD_EXPIRED_FLAG */
2988
2989                 switch (levels[l]) {
2990                 case 21:
2991                 case 23:
2992                 case 25:
2993                         if ((pwdlastset_new != 0) &&
2994                             !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
2995                                 torture_comment(tctx, "not considering a non-0 "
2996                                         "pwdLastSet as a an error as the "
2997                                         "SAMR_FIELD_EXPIRED_FLAG has not "
2998                                         "been set\n");
2999                                 break;
3000                         }
3001                 default:
3002                         if (pwdlastset_new != 0) {
3003                                 torture_warning(tctx, "pwdLastSet test failed: "
3004                                         "expected pwdLastSet 0 but got %lld\n",
3005                                         pwdlastset_old);
3006                                 ret = false;
3007                         }
3008                         break;
3009                 }
3010
3011                 switch (levels[l]) {
3012                 case 21:
3013                 case 23:
3014                 case 25:
3015                         if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3016                              (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3017                              (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3018                              (pwdlastset_old >= pwdlastset_new)) {
3019                                 torture_warning(tctx, "pwdlastset not increasing\n");
3020                                 ret = false;
3021                         }
3022                         break;
3023                 default:
3024                         if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3025                             (pwdlastset_old >= pwdlastset_new)) {
3026                                 torture_warning(tctx, "pwdlastset not increasing\n");
3027                                 ret = false;
3028                         }
3029                         break;
3030                 }
3031
3032                 usleep(delay);
3033
3034                 /* set #2 */
3035
3036                 /* set a password, pwdlastset needs to get updated (increased
3037                  * value), password_expired value used here is 0 */
3038
3039                 if (!test_SetPassword_level(p, np, tctx, handle,
3040                                             levels[l],
3041                                             fields_present[f],
3042                                             0,
3043                                             &matched_expected_error,
3044                                             set_levels[s],
3045                                             acct_name,
3046                                             password,
3047                                             machine_credentials,
3048                                             query_levels[q],
3049                                             &pwdlastset_new,
3050                                             expected_samlogon_result)) {
3051                         ret = false;
3052                 }
3053
3054                 /* when a password has been changed, pwdlastset must not be 0 afterwards
3055                  * and must be larger then the old value */
3056
3057                 switch (levels[l]) {
3058                 case 21:
3059                 case 23:
3060                 case 25:
3061
3062                         /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3063                          * password has been changed, old and new pwdlastset
3064                          * need to be the same value */
3065
3066                         if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3067                             !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3068                               (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3069                         {
3070                                 torture_assert_int_equal(tctx, pwdlastset_old,
3071                                         pwdlastset_new, "pwdlastset must be equal");
3072                                 break;
3073                         }
3074                 default:
3075                         if (pwdlastset_old >= pwdlastset_new) {
3076                                 torture_warning(tctx, "pwdLastSet test failed: "
3077                                         "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3078                                         pwdlastset_old, pwdlastset_new);
3079                                 ret = false;
3080                         }
3081                         if (pwdlastset_new == 0) {
3082                                 torture_warning(tctx, "pwdLastSet test failed: "
3083                                         "expected non-0 pwdlastset, got: %lld\n",
3084                                         pwdlastset_new);
3085                                 ret = false;
3086                         }
3087                 }
3088
3089                 switch (levels[l]) {
3090                 case 21:
3091                 case 23:
3092                 case 25:
3093                         if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3094                              (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3095                              (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3096                              (pwdlastset_old >= pwdlastset_new)) {
3097                                 torture_warning(tctx, "pwdlastset not increasing\n");
3098                                 ret = false;
3099                         }
3100                         break;
3101                 default:
3102                         if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3103                             (pwdlastset_old >= pwdlastset_new)) {
3104                                 torture_warning(tctx, "pwdlastset not increasing\n");
3105                                 ret = false;
3106                         }
3107                         break;
3108                 }
3109
3110                 pwdlastset_old = pwdlastset_new;
3111
3112                 usleep(delay);
3113
3114                 /* set #2b */
3115
3116                 /* set a password, pwdlastset needs to get updated (increased
3117                  * value), password_expired value used here is 0 */
3118
3119                 if (!test_SetPassword_level(p, np, tctx, handle,
3120                                             levels[l],
3121                                             fields_present[f],
3122                                             0,
3123                                             &matched_expected_error,
3124                                             set_levels[s],
3125                                             acct_name,
3126                                             password,
3127                                             machine_credentials,
3128                                             query_levels[q],
3129                                             &pwdlastset_new,
3130                                             expected_samlogon_result)) {
3131                         ret = false;
3132                 }
3133
3134                 /* when a password has been changed, pwdlastset must not be 0 afterwards
3135                  * and must be larger then the old value */
3136
3137                 switch (levels[l]) {
3138                 case 21:
3139                 case 23:
3140                 case 25:
3141
3142                         /* if no password has been changed, old and new pwdlastset
3143                          * need to be the same value */
3144
3145                         if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3146                               (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3147                         {
3148                                 torture_assert_int_equal(tctx, pwdlastset_old,
3149                                         pwdlastset_new, "pwdlastset must be equal");
3150                                 break;
3151                         }
3152                 default:
3153                         if (pwdlastset_old >= pwdlastset_new) {
3154                                 torture_warning(tctx, "pwdLastSet test failed: "
3155                                         "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3156                                         pwdlastset_old, pwdlastset_new);
3157                                 ret = false;
3158                         }
3159                         if (pwdlastset_new == 0) {
3160                                 torture_warning(tctx, "pwdLastSet test failed: "
3161                                         "expected non-0 pwdlastset, got: %lld\n",
3162                                         pwdlastset_new);
3163                                 ret = false;
3164                         }
3165                 }
3166
3167                 /* set #3 */
3168
3169                 /* set a password and force password change (pwdlastset 0) by
3170                  * setting the password expired flag to a non-0 value */
3171
3172                 if (!test_SetPassword_level(p, np, tctx, handle,
3173                                             levels[l],
3174                                             fields_present[f],
3175                                             nonzeros[z],
3176                                             &matched_expected_error,
3177                                             set_levels[s],
3178                                             acct_name,
3179                                             password,
3180                                             machine_credentials,
3181                                             query_levels[q],
3182                                             &pwdlastset_new,
3183                                             expected_samlogon_result)) {
3184                         ret = false;
3185                 }
3186
3187                 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3188                  * set without the SAMR_FIELD_EXPIRED_FLAG */
3189
3190                 switch (levels[l]) {
3191                 case 21:
3192                 case 23:
3193                 case 25:
3194                         if ((pwdlastset_new != 0) &&
3195                             !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3196                                 torture_comment(tctx, "not considering a non-0 "
3197                                         "pwdLastSet as a an error as the "
3198                                         "SAMR_FIELD_EXPIRED_FLAG has not "
3199                                         "been set\n");
3200                                 break;
3201                         }
3202
3203                         /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3204                          * password has been changed, old and new pwdlastset
3205                          * need to be the same value */
3206
3207                         if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3208                             !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3209                               (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3210                         {
3211                                 torture_assert_int_equal(tctx, pwdlastset_old,
3212                                         pwdlastset_new, "pwdlastset must be equal");
3213                                 break;
3214                         }
3215                 default:
3216
3217                         if (pwdlastset_old == pwdlastset_new) {
3218                                 torture_warning(tctx, "pwdLastSet test failed: "
3219                                         "expected last pwdlastset (%lld) != new pwdlastset (%lld)\n",
3220                                         pwdlastset_old, pwdlastset_new);
3221                                 ret = false;
3222                         }
3223
3224                         if (pwdlastset_new != 0) {
3225                                 torture_warning(tctx, "pwdLastSet test failed: "
3226                                         "expected pwdLastSet 0, got %lld\n",
3227                                         pwdlastset_old);
3228                                 ret = false;
3229                         }
3230                         break;
3231                 }
3232
3233                 switch (levels[l]) {
3234                 case 21:
3235                 case 23:
3236                 case 25:
3237                         if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3238                              (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3239                              (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3240                              (pwdlastset_old >= pwdlastset_new)) {
3241                                 torture_warning(tctx, "pwdlastset not increasing\n");
3242                                 ret = false;
3243                         }
3244                         break;
3245                 default:
3246                         if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3247                             (pwdlastset_old >= pwdlastset_new)) {
3248                                 torture_warning(tctx, "pwdlastset not increasing\n");
3249                                 ret = false;
3250                         }
3251                         break;
3252                 }
3253
3254                 /* if the level we are testing does not have a fields_present
3255                  * field, skip all fields present tests by setting f to to
3256                  * arraysize */
3257                 switch (levels[l]) {
3258                 case 18:
3259                 case 24:
3260                 case 26:
3261                         f = ARRAY_SIZE(fields_present);
3262                         break;
3263                 }
3264
3265 #ifdef TEST_QUERY_LEVELS
3266         }
3267 #endif
3268 #ifdef TEST_SET_LEVELS
3269         }
3270 #endif
3271         } /* fields present */
3272         } /* nonzeros */
3273         } /* levels */
3274
3275 #undef TEST_SET_LEVELS
3276 #undef TEST_QUERY_LEVELS
3277
3278         talloc_free(np);
3279
3280         return ret;
3281 }
3282
3283 static bool test_DeleteUser_with_privs(struct dcerpc_pipe *p,
3284                                        struct dcerpc_pipe *lp,
3285                                        struct torture_context *tctx,
3286                                        struct policy_handle *domain_handle,
3287                                        struct policy_handle *lsa_handle,
3288                                        struct policy_handle *user_handle,
3289                                        const struct dom_sid *domain_sid,
3290                                        uint32_t rid,
3291                                        struct cli_credentials *machine_credentials)
3292 {
3293         NTSTATUS status;
3294         bool ret = true;
3295
3296         struct policy_handle lsa_acct_handle;
3297         struct dom_sid *user_sid;
3298
3299         user_sid = dom_sid_add_rid(tctx, domain_sid, rid);
3300
3301         {
3302                 struct lsa_EnumAccountRights r;
3303                 struct lsa_RightSet rights;
3304
3305                 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
3306
3307                 r.in.handle = lsa_handle;
3308                 r.in.sid = user_sid;
3309                 r.out.rights = &rights;
3310
3311                 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3312                 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3313                         "Expected enum rights for account to fail");
3314         }
3315
3316         {
3317                 struct lsa_RightSet rights;
3318                 struct lsa_StringLarge names[2];
3319                 struct lsa_AddAccountRights r;
3320
3321                 torture_comment(tctx, "Testing LSA AddAccountRights\n");
3322
3323                 init_lsa_StringLarge(&names[0], "SeMachineAccountPrivilege");
3324                 init_lsa_StringLarge(&names[1], NULL);
3325
3326                 rights.count = 1;
3327                 rights.names = names;
3328
3329                 r.in.handle = lsa_handle;
3330                 r.in.sid = user_sid;
3331                 r.in.rights = &rights;
3332
3333                 status = dcerpc_lsa_AddAccountRights(lp, tctx, &r);
3334                 torture_assert_ntstatus_ok(tctx, status,
3335                         "Failed to add privileges");
3336         }
3337
3338         {
3339                 struct lsa_EnumAccounts r;
3340                 uint32_t resume_handle = 0;
3341                 struct lsa_SidArray lsa_sid_array;
3342                 int i;
3343                 bool found_sid = false;
3344
3345                 torture_comment(tctx, "Testing LSA EnumAccounts\n");
3346
3347                 r.in.handle = lsa_handle;
3348                 r.in.num_entries = 0x1000;
3349                 r.in.resume_handle = &resume_handle;
3350                 r.out.sids = &lsa_sid_array;
3351                 r.out.resume_handle = &resume_handle;
3352
3353                 status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
3354                 torture_assert_ntstatus_ok(tctx, status,
3355                         "Failed to enum accounts");
3356
3357                 for (i=0; i < lsa_sid_array.num_sids; i++) {
3358                         if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
3359                                 found_sid = true;
3360                         }
3361                 }
3362
3363                 torture_assert(tctx, found_sid,
3364                         "failed to list privileged account");
3365         }
3366
3367         {
3368                 struct lsa_EnumAccountRights r;
3369                 struct lsa_RightSet user_rights;
3370
3371                 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
3372
3373                 r.in.handle = lsa_handle;
3374                 r.in.sid = user_sid;
3375                 r.out.rights = &user_rights;
3376
3377                 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3378                 torture_assert_ntstatus_ok(tctx, status,
3379                         "Failed to enum rights for account");
3380
3381                 if (user_rights.count < 1) {
3382                         torture_warning(tctx, "failed to find newly added rights");
3383                         return false;
3384                 }
3385         }
3386
3387         {
3388                 struct lsa_OpenAccount r;
3389
3390                 torture_comment(tctx, "Testing LSA OpenAccount\n");
3391
3392                 r.in.handle = lsa_handle;
3393                 r.in.sid = user_sid;
3394                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3395                 r.out.acct_handle = &lsa_acct_handle;
3396
3397                 status = dcerpc_lsa_OpenAccount(lp, tctx, &r);
3398                 torture_assert_ntstatus_ok(tctx, status,
3399                         "Failed to open lsa account");
3400         }
3401
3402         {
3403                 struct lsa_GetSystemAccessAccount r;
3404                 uint32_t access_mask;
3405
3406                 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
3407
3408                 r.in.handle = &lsa_acct_handle;
3409                 r.out.access_mask = &access_mask;
3410
3411                 status = dcerpc_lsa_GetSystemAccessAccount(lp, tctx, &r);
3412                 torture_assert_ntstatus_ok(tctx, status,
3413                         "Failed to get lsa system access account");
3414         }
3415
3416         {
3417                 struct lsa_Close r;
3418
3419                 torture_comment(tctx, "Testing LSA Close\n");
3420
3421                 r.in.handle = &lsa_acct_handle;
3422                 r.out.handle = &lsa_acct_handle;
3423
3424                 status = dcerpc_lsa_Close(lp, tctx, &r);
3425                 torture_assert_ntstatus_ok(tctx, status,
3426                         "Failed to close lsa");
3427         }
3428
3429         {
3430                 struct samr_DeleteUser r;
3431
3432                 torture_comment(tctx, "Testing SAMR DeleteUser\n");
3433
3434                 r.in.user_handle = user_handle;
3435                 r.out.user_handle = user_handle;
3436
3437                 status = dcerpc_samr_DeleteUser(p, tctx, &r);
3438                 torture_assert_ntstatus_ok(tctx, status, "Delete User failed");
3439         }
3440
3441         {
3442                 struct lsa_EnumAccounts r;
3443                 uint32_t resume_handle = 0;
3444                 struct lsa_SidArray lsa_sid_array;
3445                 int i;
3446                 bool found_sid = false;
3447
3448                 torture_comment(tctx, "Testing LSA EnumAccounts\n");
3449
3450                 r.in.handle = lsa_handle;
3451                 r.in.num_entries = 0x1000;
3452                 r.in.resume_handle = &resume_handle;
3453                 r.out.sids = &lsa_sid_array;
3454                 r.out.resume_handle = &resume_handle;
3455
3456                 status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
3457                 torture_assert_ntstatus_ok(tctx, status,
3458                         "Failed to enum accounts");
3459
3460                 for (i=0; i < lsa_sid_array.num_sids; i++) {
3461                         if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
3462                                 found_sid = true;
3463                         }
3464                 }
3465
3466                 torture_assert(tctx, found_sid,
3467                         "failed to list privileged account");
3468         }
3469
3470         {
3471                 struct lsa_EnumAccountRights r;
3472                 struct lsa_RightSet user_rights;
3473
3474                 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
3475
3476                 r.in.handle = lsa_handle;
3477                 r.in.sid = user_sid;
3478                 r.out.rights = &user_rights;
3479
3480                 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3481                 torture_assert_ntstatus_ok(tctx, status,
3482                         "Failed to enum rights for account");
3483
3484                 if (user_rights.count < 1) {
3485                         torture_warning(tctx, "failed to find newly added rights");
3486                         return false;
3487                 }
3488         }
3489
3490         {
3491                 struct lsa_OpenAccount r;
3492
3493                 torture_comment(tctx, "Testing LSA OpenAccount\n");
3494
3495                 r.in.handle = lsa_handle;
3496                 r.in.sid = user_sid;
3497                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3498                 r.out.acct_handle = &lsa_acct_handle;
3499
3500                 status = dcerpc_lsa_OpenAccount(lp, tctx, &r);
3501                 torture_assert_ntstatus_ok(tctx, status,
3502                         "Failed to open lsa account");
3503         }
3504
3505         {
3506                 struct lsa_GetSystemAccessAccount r;
3507                 uint32_t access_mask;
3508
3509                 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
3510
3511                 r.in.handle = &lsa_acct_handle;
3512                 r.out.access_mask = &access_mask;
3513
3514                 status = dcerpc_lsa_GetSystemAccessAccount(lp, tctx, &r);
3515                 torture_assert_ntstatus_ok(tctx, status,
3516                         "Failed to get lsa system access account");
3517         }
3518
3519         {
3520                 struct lsa_DeleteObject r;
3521
3522                 torture_comment(tctx, "Testing LSA DeleteObject\n");
3523
3524                 r.in.handle = &lsa_acct_handle;
3525                 r.out.handle = &lsa_acct_handle;
3526
3527                 status = dcerpc_lsa_DeleteObject(lp, tctx, &r);
3528                 torture_assert_ntstatus_ok(tctx, status,
3529                         "Failed to delete object");
3530         }
3531
3532         {
3533                 struct lsa_EnumAccounts r;
3534                 uint32_t resume_handle = 0;
3535                 struct lsa_SidArray lsa_sid_array;
3536                 int i;
3537                 bool found_sid = false;
3538
3539                 torture_comment(tctx, "Testing LSA EnumAccounts\n");
3540
3541                 r.in.handle = lsa_handle;
3542                 r.in.num_entries = 0x1000;
3543                 r.in.resume_handle = &resume_handle;
3544                 r.out.sids = &lsa_sid_array;
3545                 r.out.resume_handle = &resume_handle;
3546
3547                 status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
3548                 torture_assert_ntstatus_ok(tctx, status,
3549                         "Failed to enum accounts");
3550
3551                 for (i=0; i < lsa_sid_array.num_sids; i++) {
3552                         if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
3553                                 found_sid = true;
3554                         }
3555                 }
3556
3557                 torture_assert(tctx, !found_sid,
3558                         "should not have listed privileged account");
3559         }
3560
3561         {
3562                 struct lsa_EnumAccountRights r;
3563                 struct lsa_RightSet user_rights;
3564
3565                 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
3566
3567                 r.in.handle = lsa_handle;
3568                 r.in.sid = user_sid;
3569                 r.out.rights = &user_rights;
3570
3571                 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3572                 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3573                         "Failed to enum rights for account");
3574         }
3575
3576         return ret;
3577 }
3578
3579 static bool test_user_ops(struct dcerpc_pipe *p,
3580                           struct torture_context *tctx,
3581                           struct policy_handle *user_handle,
3582                           struct policy_handle *domain_handle,
3583                           const struct dom_sid *domain_sid,
3584                           uint32_t base_acct_flags,
3585                           const char *base_acct_name, enum torture_samr_choice which_ops,
3586                           struct cli_credentials *machine_credentials)
3587 {
3588         char *password = NULL;
3589         struct samr_QueryUserInfo q;
3590         union samr_UserInfo *info;
3591         NTSTATUS status;
3592
3593         bool ret = true;
3594         int i;
3595         uint32_t rid;
3596         const uint32_t password_fields[] = {
3597                 SAMR_FIELD_NT_PASSWORD_PRESENT,
3598                 SAMR_FIELD_LM_PASSWORD_PRESENT,
3599                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
3600                 0
3601         };
3602
3603         status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
3604         if (!NT_STATUS_IS_OK(status)) {
3605                 ret = false;
3606         }
3607
3608         switch (which_ops) {
3609         case TORTURE_SAMR_USER_ATTRIBUTES:
3610                 if (!test_QuerySecurity(p, tctx, user_handle)) {
3611                         ret = false;
3612                 }
3613
3614                 if (!test_QueryUserInfo(p, tctx, user_handle)) {
3615                         ret = false;
3616                 }
3617
3618                 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
3619                         ret = false;
3620                 }
3621
3622                 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
3623                                       base_acct_name)) {
3624                         ret = false;
3625                 }
3626
3627                 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
3628                         ret = false;
3629                 }
3630
3631                 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
3632                         ret = false;
3633                 }
3634
3635                 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
3636                         ret = false;
3637                 }
3638                 break;
3639         case TORTURE_SAMR_PASSWORDS:
3640                 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
3641                         char simple_pass[9];
3642                         char *v = generate_random_str(tctx, 1);
3643
3644                         ZERO_STRUCT(simple_pass);
3645                         memset(simple_pass, *v, sizeof(simple_pass) - 1);
3646
3647                         torture_comment(tctx, "Testing machine account password policy rules\n");
3648
3649                         /* Workstation trust accounts don't seem to need to honour password quality policy */
3650                         if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
3651                                 ret = false;
3652                         }
3653
3654                         if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
3655                                 ret = false;
3656                         }
3657
3658                         /* reset again, to allow another 'user' password change */
3659                         if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
3660                                 ret = false;
3661                         }
3662
3663                         /* Try a 'short' password */
3664                         if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
3665                                 ret = false;
3666                         }
3667
3668                         /* Try a compleatly random password */
3669                         if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
3670                                 ret = false;
3671                         }
3672                 }
3673
3674                 for (i = 0; password_fields[i]; i++) {
3675                         if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
3676                                 ret = false;
3677                         }
3678
3679                         /* check it was set right */
3680                         if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3681                                 ret = false;
3682                         }
3683                 }
3684
3685                 for (i = 0; password_fields[i]; i++) {
3686                         if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
3687                                 ret = false;
3688                         }
3689
3690                         /* check it was set right */
3691                         if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3692                                 ret = false;
3693                         }
3694                 }
3695
3696                 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
3697                         ret = false;
3698                 }
3699
3700                 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
3701                         ret = false;
3702                 }
3703
3704                 if (torture_setting_bool(tctx, "samba4", false)) {
3705                         torture_comment(tctx, "skipping Set Password level 18 and 21 against Samba4\n");
3706                 } else {
3707
3708                         if (!test_SetUserPass_18(p, tctx, user_handle, &password)) {
3709                                 ret = false;
3710                         }
3711
3712                         if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3713                                 ret = false;
3714                         }
3715
3716                         for (i = 0; password_fields[i]; i++) {
3717
3718                                 if (password_fields[i] == SAMR_FIELD_LM_PASSWORD_PRESENT) {
3719                                         /* we need to skip as that would break
3720                                          * the ChangePasswordUser3 verify */
3721                                         continue;
3722                                 }
3723
3724                                 if (!test_SetUserPass_21(p, tctx, user_handle, password_fields[i], &password)) {
3725                                         ret = false;
3726                                 }
3727
3728                                 /* check it was set right */
3729                                 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3730                                         ret = false;
3731                                 }
3732                         }
3733                 }
3734
3735                 q.in.user_handle = user_handle;
3736                 q.in.level = 5;
3737                 q.out.info = &info;
3738
3739                 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
3740                 if (!NT_STATUS_IS_OK(status)) {
3741                         torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
3742                                q.in.level, nt_errstr(status));
3743                         ret = false;
3744                 } else {
3745                         uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
3746                         if ((info->info5.acct_flags) != expected_flags) {
3747                                 torture_warning(tctx, "QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
3748                                        info->info5.acct_flags,
3749                                        expected_flags);
3750                                 /* FIXME: GD */
3751                                 if (!torture_setting_bool(tctx, "samba3", false)) {
3752                                         ret = false;
3753                                 }
3754                         }
3755                         if (info->info5.rid != rid) {
3756                                 torture_warning(tctx, "QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
3757                                        info->info5.rid, rid);
3758
3759                         }
3760                 }
3761
3762                 break;
3763
3764         case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
3765
3766                 /* test last password change timestamp behaviour */
3767                 if (!test_SetPassword_pwdlastset(p, tctx, base_acct_flags,
3768                                                  base_acct_name,
3769                                                  user_handle, &password,
3770                                                  machine_credentials)) {
3771                         ret = false;
3772                 }
3773
3774                 if (ret == true) {
3775                         torture_comment(tctx, "pwdLastSet test succeeded\n");
3776                 } else {
3777                         torture_warning(tctx, "pwdLastSet test failed\n");
3778                 }
3779
3780                 break;
3781
3782         case TORTURE_SAMR_USER_PRIVILEGES: {
3783
3784                 struct dcerpc_pipe *lp;
3785                 struct policy_handle *lsa_handle;
3786
3787                 status = torture_rpc_connection(tctx, &lp, &ndr_table_lsarpc);
3788                 torture_assert_ntstatus_ok(tctx, status, "Failed to open LSA pipe");
3789
3790                 if (!test_lsa_OpenPolicy2(lp, tctx, &lsa_handle)) {
3791                         ret = false;
3792                 }
3793
3794                 if (!test_DeleteUser_with_privs(p, lp, tctx,
3795                                                 domain_handle, lsa_handle, user_handle,
3796                                                 domain_sid, rid,
3797                                                 machine_credentials)) {
3798                         ret = false;
3799                 }
3800
3801                 if (!test_lsa_Close(lp, tctx, lsa_handle)) {
3802                         ret = false;
3803                 }
3804
3805                 if (!ret) {
3806                         torture_warning(tctx, "privileged user delete test failed\n");
3807                 }
3808
3809                 break;
3810         }
3811         case TORTURE_SAMR_OTHER:
3812                 /* We just need the account to exist */
3813                 break;
3814         }
3815         return ret;
3816 }
3817
3818 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
3819                            struct policy_handle *alias_handle,
3820                            const struct dom_sid *domain_sid)
3821 {
3822         bool ret = true;
3823
3824         if (!torture_setting_bool(tctx, "samba3", false)) {
3825                 if (!test_QuerySecurity(p, tctx, alias_handle)) {
3826                         ret = false;
3827                 }
3828         }
3829
3830         if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
3831                 ret = false;
3832         }
3833
3834         if (!test_SetAliasInfo(p, tctx, alias_handle)) {
3835                 ret = false;
3836         }
3837
3838         if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
3839                 ret = false;
3840         }
3841
3842         if (torture_setting_bool(tctx, "samba3", false) ||
3843             torture_setting_bool(tctx, "samba4", false)) {
3844                 torture_comment(tctx, "skipping MultipleMembers Alias tests against Samba\n");
3845                 return ret;
3846         }
3847
3848         if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
3849                 ret = false;
3850         }
3851
3852         return ret;
3853 }
3854
3855
3856 static bool test_DeleteUser(struct dcerpc_pipe *p, struct torture_context *tctx,
3857                                      struct policy_handle *user_handle)
3858 {
3859         struct samr_DeleteUser d;
3860         NTSTATUS status;
3861         torture_comment(tctx, "Testing DeleteUser\n");
3862
3863         d.in.user_handle = user_handle;
3864         d.out.user_handle = user_handle;
3865
3866         status = dcerpc_samr_DeleteUser(p, tctx, &d);
3867         torture_assert_ntstatus_ok(tctx, status, "DeleteUser");
3868
3869         return true;
3870 }
3871
3872 bool test_DeleteUser_byname(struct dcerpc_pipe *p,
3873                             struct torture_context *tctx,
3874                             struct policy_handle *handle, const char *name)
3875 {
3876         NTSTATUS status;
3877         struct samr_DeleteUser d;
3878         struct policy_handle user_handle;
3879         uint32_t rid;
3880
3881         status = test_LookupName(p, tctx, handle, name, &rid);
3882         if (!NT_STATUS_IS_OK(status)) {
3883                 goto failed;
3884         }
3885
3886         status = test_OpenUser_byname(p, tctx, handle, name, &user_handle);
3887         if (!NT_STATUS_IS_OK(status)) {
3888                 goto failed;
3889         }
3890
3891         d.in.user_handle = &user_handle;
3892         d.out.user_handle = &user_handle;
3893         status = dcerpc_samr_DeleteUser(p, tctx, &d);
3894         if (!NT_STATUS_IS_OK(status)) {
3895                 goto failed;
3896         }
3897
3898         return true;
3899
3900 failed:
3901         torture_warning(tctx, "DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
3902         return false;
3903 }
3904
3905
3906 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p,
3907                                     struct torture_context *tctx,
3908                                     struct policy_handle *handle, const char *name)
3909 {
3910         NTSTATUS status;
3911         struct samr_OpenGroup r;
3912         struct samr_DeleteDomainGroup d;
3913         struct policy_handle group_handle;
3914         uint32_t rid;
3915
3916         status = test_LookupName(p, tctx, handle, name, &rid);
3917         if (!NT_STATUS_IS_OK(status)) {
3918                 goto failed;
3919         }
3920
3921         r.in.domain_handle = handle;
3922         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3923         r.in.rid = rid;
3924         r.out.group_handle = &group_handle;
3925         status = dcerpc_samr_OpenGroup(p, tctx, &r);
3926         if (!NT_STATUS_IS_OK(status)) {
3927                 goto failed;
3928         }
3929
3930         d.in.group_handle = &group_handle;
3931         d.out.group_handle = &group_handle;
3932         status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
3933         if (!NT_STATUS_IS_OK(status)) {
3934                 goto failed;
3935         }
3936
3937         return true;
3938
3939 failed:
3940         torture_warning(tctx, "DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
3941         return false;
3942 }
3943
3944
3945 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p,
3946                                     struct torture_context *tctx,
3947                                     struct policy_handle *domain_handle,
3948                                     const char *name)
3949 {
3950         NTSTATUS status;
3951         struct samr_OpenAlias r;
3952         struct samr_DeleteDomAlias d;
3953         struct policy_handle alias_handle;
3954         uint32_t rid;
3955
3956         torture_comment(tctx, "testing DeleteAlias_byname\n");
3957
3958         status = test_LookupName(p, tctx, domain_handle, name, &rid);
3959         if (!NT_STATUS_IS_OK(status)) {
3960                 goto failed;
3961         }
3962
3963         r.in.domain_handle = domain_handle;
3964         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3965         r.in.rid = rid;
3966         r.out.alias_handle = &alias_handle;
3967         status = dcerpc_samr_OpenAlias(p, tctx, &r);
3968         if (!NT_STATUS_IS_OK(status)) {
3969                 goto failed;
3970         }
3971
3972         d.in.alias_handle = &alias_handle;
3973         d.out.alias_handle = &alias_handle;
3974         status = dcerpc_samr_DeleteDomAlias(p, tctx, &d);
3975         if (!NT_STATUS_IS_OK(status)) {
3976                 goto failed;
3977         }
3978
3979         return true;
3980
3981 failed:
3982         torture_warning(tctx, "DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
3983         return false;
3984 }
3985
3986 static bool test_DeleteAlias(struct dcerpc_pipe *p,
3987                              struct torture_context *tctx,
3988                              struct policy_handle *alias_handle)
3989 {
3990         struct samr_DeleteDomAlias d;
3991         NTSTATUS status;
3992         bool ret = true;
3993
3994         torture_comment(tctx, "Testing DeleteAlias\n");
3995
3996         d.in.alias_handle = alias_handle;
3997         d.out.alias_handle = alias_handle;
3998
3999         status = dcerpc_samr_DeleteDomAlias(p, tctx, &d);
4000         if (!NT_STATUS_IS_OK(status)) {
4001                 torture_warning(tctx, "DeleteAlias failed - %s\n", nt_errstr(status));
4002                 ret = false;
4003         }
4004
4005         return ret;
4006 }
4007
4008 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
4009                              struct policy_handle *domain_handle,
4010                              const char *alias_name,
4011                              struct policy_handle *alias_handle,
4012                              const struct dom_sid *domain_sid,
4013                              bool test_alias)
4014 {
4015         NTSTATUS status;
4016         struct samr_CreateDomAlias r;
4017         struct lsa_String name;
4018         uint32_t rid;
4019         bool ret = true;
4020
4021         init_lsa_String(&name, alias_name);
4022         r.in.domain_handle = domain_handle;
4023         r.in.alias_name = &name;
4024         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4025         r.out.alias_handle = alias_handle;
4026         r.out.rid = &rid;
4027
4028         torture_comment(tctx, "Testing CreateAlias (%s)\n", r.in.alias_name->string);
4029
4030         status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
4031
4032         if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4033                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4034                         torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.alias_name->string);
4035                         return true;
4036                 } else {
4037                         torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
4038                                nt_errstr(status));
4039                         return false;
4040                 }
4041         }
4042
4043         if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
4044                 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
4045                         return false;
4046                 }
4047                 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
4048         }
4049
4050         if (!NT_STATUS_IS_OK(status)) {
4051                 torture_warning(tctx, "CreateAlias failed - %s\n", nt_errstr(status));
4052                 return false;
4053         }
4054
4055         if (!test_alias) {
4056                 return ret;
4057         }
4058
4059         if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
4060                 ret = false;
4061         }
4062
4063         return ret;
4064 }
4065
4066 static bool test_ChangePassword(struct dcerpc_pipe *p,
4067                                 struct torture_context *tctx,
4068                                 const char *acct_name,
4069                                 struct policy_handle *domain_handle, char **password)
4070 {
4071         bool ret = true;
4072
4073         if (!*password) {
4074                 return false;
4075         }
4076
4077         if (!test_ChangePasswordUser(p, tctx, acct_name, domain_handle, password)) {
4078                 ret = false;
4079         }
4080
4081         if (!test_ChangePasswordUser2(p, tctx, acct_name, password, 0, true)) {
4082                 ret = false;
4083         }
4084
4085         if (!test_OemChangePasswordUser2(p, tctx, acct_name, domain_handle, password)) {
4086                 ret = false;
4087         }
4088
4089         /* test what happens when setting the old password again */
4090         if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, *password, 0, true)) {
4091                 ret = false;
4092         }
4093
4094         {
4095                 char simple_pass[9];
4096                 char *v = generate_random_str(tctx, 1);
4097
4098                 ZERO_STRUCT(simple_pass);
4099                 memset(simple_pass, *v, sizeof(simple_pass) - 1);
4100
4101                 /* test what happens when picking a simple password */
4102                 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, simple_pass, 0, true)) {
4103                         ret = false;
4104                 }
4105         }
4106
4107         /* set samr_SetDomainInfo level 1 with min_length 5 */
4108         {
4109                 struct samr_QueryDomainInfo r;
4110                 union samr_DomainInfo *info = NULL;
4111                 struct samr_SetDomainInfo s;
4112                 uint16_t len_old, len;
4113                 uint32_t pwd_prop_old;
4114                 int64_t min_pwd_age_old;
4115                 NTSTATUS status;
4116
4117                 len = 5;
4118
4119                 r.in.domain_handle = domain_handle;
4120                 r.in.level = 1;
4121                 r.out.info = &info;
4122
4123                 torture_comment(tctx, "testing samr_QueryDomainInfo level 1\n");
4124                 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
4125                 if (!NT_STATUS_IS_OK(status)) {
4126                         return false;
4127                 }
4128
4129                 s.in.domain_handle = domain_handle;
4130                 s.in.level = 1;
4131                 s.in.info = info;
4132
4133                 /* remember the old min length, so we can reset it */
4134                 len_old = s.in.info->info1.min_password_length;
4135                 s.in.info->info1.min_password_length = len;
4136                 pwd_prop_old = s.in.info->info1.password_properties;
4137                 /* turn off password complexity checks for this test */
4138                 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
4139
4140                 min_pwd_age_old = s.in.info->info1.min_password_age;
4141                 s.in.info->info1.min_password_age = 0;
4142
4143                 torture_comment(tctx, "testing samr_SetDomainInfo level 1\n");
4144                 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
4145                 if (!NT_STATUS_IS_OK(status)) {
4146                         return false;
4147                 }
4148
4149                 torture_comment(tctx, "calling test_ChangePasswordUser3 with too short password\n");
4150
4151                 if (!test_ChangePasswordUser3(p, tctx, acct_name, len - 1, password, NULL, 0, true)) {
4152                         ret = false;
4153                 }
4154
4155                 s.in.info->info1.min_password_length = len_old;
4156                 s.in.info->info1.password_properties = pwd_prop_old;
4157                 s.in.info->info1.min_password_age = min_pwd_age_old;
4158
4159                 torture_comment(tctx, "testing samr_SetDomainInfo level 1\n");
4160                 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
4161                 if (!NT_STATUS_IS_OK(status)) {
4162                         return false;
4163                 }
4164
4165         }
4166
4167         {
4168                 NTSTATUS status;
4169                 struct samr_OpenUser r;
4170                 struct samr_QueryUserInfo q;
4171                 union samr_UserInfo *info;
4172                 struct samr_LookupNames n;
4173                 struct policy_handle user_handle;
4174                 struct samr_Ids rids, types;
4175
4176                 n.in.domain_handle = domain_handle;
4177                 n.in.num_names = 1;
4178                 n.in.names = talloc_array(tctx, struct lsa_String, 1);
4179                 n.in.names[0].string = acct_name;
4180                 n.out.rids = &rids;
4181                 n.out.types = &types;
4182
4183                 status = dcerpc_samr_LookupNames(p, tctx, &n);
4184                 if (!NT_STATUS_IS_OK(status)) {
4185                         torture_warning(tctx, "LookupNames failed - %s\n", nt_errstr(status));
4186                         return false;
4187                 }
4188
4189                 r.in.domain_handle = domain_handle;
4190                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4191                 r.in.rid = n.out.rids->ids[0];
4192                 r.out.user_handle = &user_handle;
4193
4194                 status = dcerpc_samr_OpenUser(p, tctx, &r);
4195                 if (!NT_STATUS_IS_OK(status)) {
4196                         torture_warning(tctx, "OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(status));
4197                         return false;
4198                 }
4199
4200                 q.in.user_handle = &user_handle;
4201                 q.in.level = 5;
4202                 q.out.info = &info;
4203
4204                 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
4205                 if (!NT_STATUS_IS_OK(status)) {
4206                         torture_warning(tctx, "QueryUserInfo failed - %s\n", nt_errstr(status));
4207                         return false;
4208                 }
4209
4210                 torture_comment(tctx, "calling test_ChangePasswordUser3 with too early password change\n");
4211
4212                 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL,
4213                                               info->info5.last_password_change, true)) {
4214                         ret = false;
4215                 }
4216         }
4217
4218         /* we change passwords twice - this has the effect of verifying
4219            they were changed correctly for the final call */
4220         if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
4221                 ret = false;
4222         }
4223
4224         if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
4225                 ret = false;
4226         }
4227
4228         return ret;
4229 }
4230
4231 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
4232                             struct policy_handle *domain_handle,
4233                             const char *user_name,
4234                             struct policy_handle *user_handle_out,
4235                             struct dom_sid *domain_sid,
4236                             enum torture_samr_choice which_ops,
4237                             struct cli_credentials *machine_credentials,
4238                             bool test_user)
4239 {
4240
4241         TALLOC_CTX *user_ctx;
4242
4243         NTSTATUS status;
4244         struct samr_CreateUser r;
4245         struct samr_QueryUserInfo q;
4246         union samr_UserInfo *info;
4247         struct samr_DeleteUser d;
4248         uint32_t rid;
4249
4250         /* This call creates a 'normal' account - check that it really does */
4251         const uint32_t acct_flags = ACB_NORMAL;
4252         struct lsa_String name;
4253         bool ret = true;
4254
4255         struct policy_handle user_handle;
4256         user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
4257         init_lsa_String(&name, user_name);
4258
4259         r.in.domain_handle = domain_handle;
4260         r.in.account_name = &name;
4261         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4262         r.out.user_handle = &user_handle;
4263         r.out.rid = &rid;
4264
4265         torture_comment(tctx, "Testing CreateUser(%s)\n", r.in.account_name->string);
4266
4267         status = dcerpc_samr_CreateUser(p, user_ctx, &r);
4268
4269         if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4270                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
4271                         torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
4272                         return true;
4273                 } else {
4274                         torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
4275                                nt_errstr(status));
4276                         return false;
4277                 }
4278         }
4279
4280         if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4281                 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
4282                         talloc_free(user_ctx);
4283                         return false;
4284                 }
4285                 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
4286         }
4287
4288         if (!NT_STATUS_IS_OK(status)) {
4289                 talloc_free(user_ctx);
4290                 torture_warning(tctx, "CreateUser failed - %s\n", nt_errstr(status));
4291                 return false;
4292         }
4293
4294         if (!test_user) {
4295                 if (user_handle_out) {
4296                         *user_handle_out = user_handle;
4297                 }
4298                 return ret;
4299         }
4300
4301         {
4302                 q.in.user_handle = &user_handle;
4303                 q.in.level = 16;
4304                 q.out.info = &info;
4305
4306                 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
4307                 if (!NT_STATUS_IS_OK(status)) {
4308                         torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
4309                                q.in.level, nt_errstr(status));
4310                         ret = false;
4311                 } else {
4312                         if ((info->info16.acct_flags & acct_flags) != acct_flags) {
4313                                 torture_warning(tctx, "QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4314                                        info->info16.acct_flags,
4315                                        acct_flags);
4316                                 ret = false;
4317                         }
4318                 }
4319
4320                 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
4321                                    domain_sid, acct_flags, name.string, which_ops,
4322                                    machine_credentials)) {
4323                         ret = false;
4324                 }
4325
4326                 if (user_handle_out) {
4327                         *user_handle_out = user_handle;
4328                 } else {
4329                         torture_comment(tctx, "Testing DeleteUser (createuser test)\n");
4330
4331                         d.in.user_handle = &user_handle;
4332                         d.out.user_handle = &user_handle;
4333
4334                         status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
4335                         if (!NT_STATUS_IS_OK(status)) {
4336                                 torture_warning(tctx, "DeleteUser failed - %s\n", nt_errstr(status));
4337                                 ret = false;
4338                         }
4339                 }
4340
4341         }
4342
4343         talloc_free(user_ctx);
4344
4345         return ret;
4346 }
4347
4348
4349 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
4350                              struct policy_handle *domain_handle,
4351                              struct dom_sid *domain_sid,
4352                              enum torture_samr_choice which_ops,
4353                              struct cli_credentials *machine_credentials)
4354 {
4355         NTSTATUS status;
4356         struct samr_CreateUser2 r;
4357         struct samr_QueryUserInfo q;
4358         union samr_UserInfo *info;
4359         struct samr_DeleteUser d;
4360         struct policy_handle user_handle;
4361         uint32_t rid;
4362         struct lsa_String name;
4363         bool ret = true;
4364         int i;
4365
4366         struct {
4367                 uint32_t acct_flags;
4368                 const char *account_name;
4369                 NTSTATUS nt_status;
4370         } account_types[] = {
4371                 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
4372                 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4373                 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4374                 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
4375                 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4376                 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4377                 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
4378                 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4379                 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4380                 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_ACCESS_DENIED },
4381                 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
4382                 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
4383                 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4384                 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4385                 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
4386         };
4387
4388         for (i = 0; account_types[i].account_name; i++) {
4389                 TALLOC_CTX *user_ctx;
4390                 uint32_t acct_flags = account_types[i].acct_flags;
4391                 uint32_t access_granted;
4392                 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
4393                 init_lsa_String(&name, account_types[i].account_name);
4394
4395                 r.in.domain_handle = domain_handle;
4396                 r.in.account_name = &name;
4397                 r.in.acct_flags = acct_flags;
4398                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4399                 r.out.user_handle = &user_handle;
4400                 r.out.access_granted = &access_granted;
4401                 r.out.rid = &rid;
4402
4403                 torture_comment(tctx, "Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
4404
4405                 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
4406
4407                 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4408                         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
4409                                 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
4410                                 continue;
4411                         } else {
4412                                 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
4413                                        nt_errstr(status));
4414                                 ret = false;
4415                                 continue;
4416                         }
4417                 }
4418
4419                 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4420                         if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
4421                                 talloc_free(user_ctx);
4422                                 ret = false;
4423                                 continue;
4424                         }
4425                         status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
4426
4427                 }
4428                 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
4429                         torture_warning(tctx, "CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
4430                                nt_errstr(status), nt_errstr(account_types[i].nt_status));
4431                         ret = false;
4432                 }
4433
4434                 if (NT_STATUS_IS_OK(status)) {
4435                         q.in.user_handle = &user_handle;
4436                         q.in.level = 5;
4437                         q.out.info = &info;
4438
4439                         status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
4440                         if (!NT_STATUS_IS_OK(status)) {
4441                                 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
4442                                        q.in.level, nt_errstr(status));
4443                                 ret = false;
4444                         } else {
4445                                 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
4446                                 if (acct_flags == ACB_NORMAL) {
4447                                         expected_flags |= ACB_PW_EXPIRED;
4448                                 }
4449                                 if ((info->info5.acct_flags) != expected_flags) {
4450                                         torture_warning(tctx, "QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4451                                                info->info5.acct_flags,
4452                                                expected_flags);
4453                                         ret = false;
4454                                 }
4455                                 switch (acct_flags) {
4456                                 case ACB_SVRTRUST:
4457                                         if (info->info5.primary_gid != DOMAIN_RID_DCS) {
4458                                                 torture_warning(tctx, "QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
4459                                                        DOMAIN_RID_DCS, info->info5.primary_gid);
4460                                                 ret = false;
4461                                         }
4462                                         break;
4463                                 case ACB_WSTRUST:
4464                                         if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
4465                                                 torture_warning(tctx, "QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
4466                                                        DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
4467                                                 ret = false;
4468                                         }
4469                                         break;
4470                                 case ACB_NORMAL:
4471                                         if (info->info5.primary_gid != DOMAIN_RID_USERS) {
4472                                                 torture_warning(tctx, "QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
4473                                                        DOMAIN_RID_USERS, info->info5.primary_gid);
4474                                                 ret = false;
4475                                         }
4476                                         break;
4477                                 }
4478                         }
4479
4480                         if (!test_user_ops(p, tctx, &user_handle, domain_handle,
4481                                            domain_sid, acct_flags, name.string, which_ops,
4482                                            machine_credentials)) {
4483                                 ret = false;
4484                         }
4485
4486                         if (!policy_handle_empty(&user_handle)) {
4487                                 torture_comment(tctx, "Testing DeleteUser (createuser2 test)\n");
4488
4489                                 d.in.user_handle = &user_handle;
4490                                 d.out.user_handle = &user_handle;
4491
4492                                 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
4493                                 if (!NT_STATUS_IS_OK(status)) {
4494                                         torture_warning(tctx, "DeleteUser failed - %s\n", nt_errstr(status));
4495                                         ret = false;
4496                                 }
4497                         }
4498                 }
4499                 talloc_free(user_ctx);
4500         }
4501
4502         return ret;
4503 }
4504
4505 static bool test_QueryAliasInfo(struct dcerpc_pipe *p,
4506                                 struct torture_context *tctx,
4507                                 struct policy_handle *handle)
4508 {
4509         NTSTATUS status;
4510         struct samr_QueryAliasInfo r;
4511         union samr_AliasInfo *info;
4512         uint16_t levels[] = {1, 2, 3};
4513         int i;
4514         bool ret = true;
4515
4516         for (i=0;i<ARRAY_SIZE(levels);i++) {
4517                 torture_comment(tctx, "Testing QueryAliasInfo level %u\n", levels[i]);
4518
4519                 r.in.alias_handle = handle;
4520                 r.in.level = levels[i];
4521                 r.out.info = &info;
4522
4523                 status = dcerpc_samr_QueryAliasInfo(p, tctx, &r);
4524                 if (!NT_STATUS_IS_OK(status)) {
4525                         torture_warning(tctx, "QueryAliasInfo level %u failed - %s\n",
4526                                levels[i], nt_errstr(status));
4527                         ret = false;
4528                 }
4529         }
4530
4531         return ret;
4532 }
4533
4534 static bool test_QueryGroupInfo(struct dcerpc_pipe *p,
4535                                 struct torture_context *tctx,
4536                                 struct policy_handle *handle)
4537 {
4538         NTSTATUS status;
4539         struct samr_QueryGroupInfo r;
4540         union samr_GroupInfo *info;
4541         uint16_t levels[] = {1, 2, 3, 4, 5};
4542         int i;
4543         bool ret = true;
4544
4545         for (i=0;i<ARRAY_SIZE(levels);i++) {
4546                 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
4547
4548                 r.in.group_handle = handle;
4549                 r.in.level = levels[i];
4550                 r.out.info = &info;
4551
4552                 status = dcerpc_samr_QueryGroupInfo(p, tctx, &r);
4553                 if (!NT_STATUS_IS_OK(status)) {
4554                         torture_warning(tctx, "QueryGroupInfo level %u failed - %s\n",
4555                                levels[i], nt_errstr(status));
4556                         ret = false;
4557                 }
4558         }
4559
4560         return ret;
4561 }
4562
4563 static bool test_QueryGroupMember(struct dcerpc_pipe *p,
4564                                   struct torture_context *tctx,
4565                                   struct policy_handle *handle)
4566 {
4567         NTSTATUS status;
4568         struct samr_QueryGroupMember r;
4569         struct samr_RidTypeArray *rids = NULL;
4570         bool ret = true;
4571
4572         torture_comment(tctx, "Testing QueryGroupMember\n");
4573
4574         r.in.group_handle = handle;
4575         r.out.rids = &rids;
4576
4577         status = dcerpc_samr_QueryGroupMember(p, tctx, &r);
4578         if (!NT_STATUS_IS_OK(status)) {
4579                 torture_warning(tctx, "QueryGroupInfo failed - %s\n", nt_errstr(status));
4580                 ret = false;
4581         }
4582
4583         return ret;
4584 }
4585
4586
4587 static bool test_SetGroupInfo(struct dcerpc_pipe *p,
4588                               struct torture_context *tctx,
4589                               struct policy_handle *handle)
4590 {
4591         NTSTATUS status;
4592         struct samr_QueryGroupInfo r;
4593         union samr_GroupInfo *info;
4594         struct samr_SetGroupInfo s;
4595         uint16_t levels[] = {1, 2, 3, 4};
4596         uint16_t set_ok[] = {0, 1, 1, 1};
4597         int i;
4598         bool ret = true;
4599
4600         for (i=0;i<ARRAY_SIZE(levels);i++) {
4601                 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
4602
4603                 r.in.group_handle = handle;
4604                 r.in.level = levels[i];
4605                 r.out.info = &info;
4606
4607                 status = dcerpc_samr_QueryGroupInfo(p, tctx, &r);
4608                 if (!NT_STATUS_IS_OK(status)) {
4609                         torture_warning(tctx, "QueryGroupInfo level %u failed - %s\n",
4610                                levels[i], nt_errstr(status));
4611                         ret = false;
4612                 }
4613
4614                 torture_comment(tctx, "Testing SetGroupInfo level %u\n", levels[i]);
4615
4616                 s.in.group_handle = handle;
4617                 s.in.level = levels[i];
4618                 s.in.info = *r.out.info;
4619
4620 #if 0
4621                 /* disabled this, as it changes the name only from the point of view of samr,
4622                    but leaves the name from the point of view of w2k3 internals (and ldap). This means
4623                    the name is still reserved, so creating the old name fails, but deleting by the old name
4624                    also fails */
4625                 if (s.in.level == 2) {
4626                         init_lsa_String(&s.in.info->string, "NewName");
4627                 }
4628 #endif
4629
4630                 if (s.in.level == 4) {
4631                         init_lsa_String(&s.in.info->description, "test description");
4632                 }
4633
4634                 status = dcerpc_samr_SetGroupInfo(p, tctx, &s);
4635                 if (set_ok[i]) {
4636                         if (!NT_STATUS_IS_OK(status)) {
4637                                 torture_warning(tctx, "SetGroupInfo level %u failed - %s\n",
4638                                        r.in.level, nt_errstr(status));
4639                                 ret = false;
4640                                 continue;
4641                         }
4642                 } else {
4643                         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
4644                                 torture_warning(tctx, "SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
4645                                        r.in.level, nt_errstr(status));
4646                                 ret = false;
4647                                 continue;
4648                         }
4649                 }
4650         }
4651
4652         return ret;
4653 }
4654
4655 static bool test_QueryUserInfo(struct dcerpc_pipe *p,
4656                                struct torture_context *tctx,
4657                                struct policy_handle *handle)
4658 {
4659         NTSTATUS status;
4660         struct samr_QueryUserInfo r;
4661         union samr_UserInfo *info;
4662         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4663                            11, 12, 13, 14, 16, 17, 20, 21};
4664         int i;
4665         bool ret = true;
4666
4667         for (i=0;i<ARRAY_SIZE(levels);i++) {
4668                 torture_comment(tctx, "Testing QueryUserInfo level %u\n", levels[i]);
4669
4670                 r.in.user_handle = handle;
4671                 r.in.level = levels[i];
4672                 r.out.info = &info;
4673
4674                 status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
4675                 if (!NT_STATUS_IS_OK(status)) {
4676                         torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
4677                                levels[i], nt_errstr(status));
4678                         ret = false;
4679                 }
4680         }
4681
4682         return ret;
4683 }
4684
4685 static bool test_QueryUserInfo2(struct dcerpc_pipe *p,
4686                                 struct torture_context *tctx,
4687                                 struct policy_handle *handle)
4688 {
4689         NTSTATUS status;
4690         struct samr_QueryUserInfo2 r;
4691         union samr_UserInfo *info;
4692         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4693                            11, 12, 13, 14, 16, 17, 20, 21};
4694         int i;
4695         bool ret = true;
4696
4697         for (i=0;i<ARRAY_SIZE(levels);i++) {
4698                 torture_comment(tctx, "Testing QueryUserInfo2 level %u\n", levels[i]);
4699
4700                 r.in.user_handle = handle;
4701                 r.in.level = levels[i];
4702                 r.out.info = &info;
4703
4704                 status = dcerpc_samr_QueryUserInfo2(p, tctx, &r);
4705                 if (!NT_STATUS_IS_OK(status)) {
4706                         torture_warning(tctx, "QueryUserInfo2 level %u failed - %s\n",
4707                                levels[i], nt_errstr(status));
4708                         ret = false;
4709                 }
4710         }
4711
4712         return ret;
4713 }
4714
4715 static bool test_OpenUser(struct dcerpc_pipe *p,
4716                           struct torture_context *tctx,
4717                           struct policy_handle *handle, uint32_t rid)
4718 {
4719         NTSTATUS status;
4720         struct samr_OpenUser r;
4721         struct policy_handle user_handle;
4722         bool ret = true;
4723
4724         torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
4725
4726         r.in.domain_handle = handle;
4727         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4728         r.in.rid = rid;
4729         r.out.user_handle = &user_handle;
4730
4731         status = dcerpc_samr_OpenUser(p, tctx, &r);
4732         if (!NT_STATUS_IS_OK(status)) {
4733                 torture_warning(tctx, "OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
4734                 return false;
4735         }
4736
4737         if (!test_QuerySecurity(p, tctx, &user_handle)) {
4738                 ret = false;
4739         }
4740
4741         if (!test_QueryUserInfo(p, tctx, &user_handle)) {
4742                 ret = false;
4743         }
4744
4745         if (!test_QueryUserInfo2(p, tctx, &user_handle)) {
4746                 ret = false;
4747         }
4748
4749         if (!test_GetUserPwInfo(p, tctx, &user_handle)) {
4750                 ret = false;
4751         }
4752
4753         if (!test_GetGroupsForUser(p,tctx, &user_handle)) {
4754                 ret = false;
4755         }
4756
4757         if (!test_samr_handle_Close(p, tctx, &user_handle)) {
4758                 ret = false;
4759         }
4760
4761         return ret;
4762 }
4763
4764 static bool test_OpenGroup(struct dcerpc_pipe *p,
4765                            struct torture_context *tctx,
4766                            struct policy_handle *handle, uint32_t rid)
4767 {
4768         NTSTATUS status;
4769         struct samr_OpenGroup r;
4770         struct policy_handle group_handle;
4771         bool ret = true;
4772
4773         torture_comment(tctx, "Testing OpenGroup(%u)\n", rid);
4774
4775         r.in.domain_handle = handle;
4776         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4777         r.in.rid = rid;
4778         r.out.group_handle = &group_handle;
4779
4780         status = dcerpc_samr_OpenGroup(p, tctx, &r);
4781         if (!NT_STATUS_IS_OK(status)) {
4782                 torture_warning(tctx, "OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
4783                 return false;
4784         }
4785
4786         if (!torture_setting_bool(tctx, "samba3", false)) {
4787                 if (!test_QuerySecurity(p, tctx, &group_handle)) {
4788                         ret = false;
4789                 }
4790         }
4791
4792         if (!test_QueryGroupInfo(p, tctx, &group_handle)) {
4793                 ret = false;
4794         }
4795
4796         if (!test_QueryGroupMember(p, tctx, &group_handle)) {
4797                 ret = false;
4798         }
4799
4800         if (!test_samr_handle_Close(p, tctx, &group_handle)) {
4801                 ret = false;
4802         }
4803
4804         return ret;
4805 }
4806
4807 static bool test_OpenAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
4808                            struct policy_handle *handle, uint32_t rid)
4809 {
4810         NTSTATUS status;
4811         struct samr_OpenAlias r;
4812         struct policy_handle alias_handle;
4813         bool ret = true;
4814
4815         torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
4816
4817         r.in.domain_handle = handle;
4818         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4819         r.in.rid = rid;
4820         r.out.alias_handle = &alias_handle;
4821
4822         status = dcerpc_samr_OpenAlias(p, tctx, &r);
4823         if (!NT_STATUS_IS_OK(status)) {
4824                 torture_warning(tctx, "OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
4825                 return false;
4826         }
4827
4828         if (!torture_setting_bool(tctx, "samba3", false)) {
4829                 if (!test_QuerySecurity(p, tctx, &alias_handle)) {
4830                         ret = false;
4831                 }
4832         }
4833
4834         if (!test_QueryAliasInfo(p, tctx, &alias_handle)) {
4835                 ret = false;
4836         }
4837
4838         if (!test_GetMembersInAlias(p, tctx, &alias_handle)) {
4839                 ret = false;
4840         }
4841
4842         if (!test_samr_handle_Close(p, tctx, &alias_handle)) {
4843                 ret = false;
4844         }
4845
4846         return ret;
4847 }
4848
4849 static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
4850                        struct policy_handle *handle, uint32_t rid,
4851                        uint32_t acct_flag_mask)
4852 {
4853         NTSTATUS status;
4854         struct samr_OpenUser r;
4855         struct samr_QueryUserInfo q;
4856         union samr_UserInfo *info;
4857         struct policy_handle user_handle;
4858         bool ret = true;
4859
4860         torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
4861
4862         r.in.domain_handle = handle;
4863         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4864         r.in.rid = rid;
4865         r.out.user_handle = &user_handle;
4866
4867         status = dcerpc_samr_OpenUser(p, tctx, &r);
4868         if (!NT_STATUS_IS_OK(status)) {
4869                 torture_warning(tctx, "OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
4870                 return false;
4871         }
4872
4873         q.in.user_handle = &user_handle;
4874         q.in.level = 16;
4875         q.out.info = &info;
4876
4877         status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
4878         if (!NT_STATUS_IS_OK(status)) {
4879                 torture_warning(tctx, "QueryUserInfo level 16 failed - %s\n",
4880                        nt_errstr(status));
4881                 ret = false;
4882         } else {
4883                 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
4884                         torture_warning(tctx, "Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
4885                                acct_flag_mask, info->info16.acct_flags, rid);
4886                         ret = false;
4887                 }
4888         }
4889
4890         if (!test_samr_handle_Close(p, tctx, &user_handle)) {
4891                 ret = false;
4892         }
4893
4894         return ret;
4895 }
4896
4897 static bool test_EnumDomainUsers_all(struct dcerpc_pipe *p,
4898                                      struct torture_context *tctx,
4899                                      struct policy_handle *handle)
4900 {
4901         NTSTATUS status = STATUS_MORE_ENTRIES;
4902         struct samr_EnumDomainUsers r;
4903         uint32_t mask, resume_handle=0;
4904         int i, mask_idx;
4905         bool ret = true;
4906         struct samr_LookupNames n;
4907         struct samr_LookupRids  lr ;
4908         struct lsa_Strings names;
4909         struct samr_Ids rids, types;
4910         struct samr_SamArray *sam = NULL;
4911         uint32_t num_entries = 0;
4912
4913         uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
4914                             ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
4915                             ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
4916                             ACB_PWNOEXP, 0};
4917
4918         torture_comment(tctx, "Testing EnumDomainUsers\n");
4919
4920         for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
4921                 r.in.domain_handle = handle;
4922                 r.in.resume_handle = &resume_handle;
4923                 r.in.acct_flags = mask = masks[mask_idx];
4924                 r.in.max_size = (uint32_t)-1;
4925                 r.out.resume_handle = &resume_handle;
4926                 r.out.num_entries = &num_entries;
4927                 r.out.sam = &sam;
4928
4929                 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
4930                 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
4931                     !NT_STATUS_IS_OK(status)) {
4932                         torture_warning(tctx, "EnumDomainUsers failed - %s\n", nt_errstr(status));
4933                         return false;
4934                 }
4935
4936                 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
4937
4938                 if (sam->count == 0) {
4939                         continue;
4940                 }
4941
4942                 for (i=0;i<sam->count;i++) {
4943                         if (mask) {
4944                                 if (!check_mask(p, tctx, handle, sam->entries[i].idx, mask)) {
4945                                         ret = false;
4946                                 }
4947                         } else if (!test_OpenUser(p, tctx, handle, sam->entries[i].idx)) {
4948                                 ret = false;
4949                         }
4950                 }
4951         }
4952
4953         torture_comment(tctx, "Testing LookupNames\n");
4954         n.in.domain_handle = handle;
4955         n.in.num_names = sam->count;
4956         n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
4957         n.out.rids = &rids;
4958         n.out.types = &types;
4959         for (i=0;i<sam->count;i++) {
4960                 n.in.names[i].string = sam->entries[i].name.string;
4961         }
4962         status = dcerpc_samr_LookupNames(p, tctx, &n);
4963         if (!NT_STATUS_IS_OK(status)) {
4964                 torture_warning(tctx, "LookupNames failed - %s\n", nt_errstr(status));
4965                 ret = false;
4966         }
4967
4968
4969         torture_comment(tctx, "Testing LookupRids\n");
4970         lr.in.domain_handle = handle;
4971         lr.in.num_rids = sam->count;
4972         lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
4973         lr.out.names = &names;
4974         lr.out.types = &types;
4975         for (i=0;i<sam->count;i++) {
4976                 lr.in.rids[i] = sam->entries[i].idx;
4977         }
4978         status = dcerpc_samr_LookupRids(p, tctx, &lr);
4979         torture_assert_ntstatus_ok(tctx, status, "LookupRids");
4980
4981         return ret;
4982 }
4983
4984 /*
4985   try blasting the server with a bunch of sync requests
4986 */
4987 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
4988                                        struct policy_handle *handle)
4989 {
4990         NTSTATUS status;
4991         struct samr_EnumDomainUsers r;
4992         uint32_t resume_handle=0;
4993         int i;
4994 #define ASYNC_COUNT 100
4995         struct rpc_request *req[ASYNC_COUNT];
4996
4997         if (!torture_setting_bool(tctx, "dangerous", false)) {
4998                 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
4999         }
5000
5001         torture_comment(tctx, "Testing EnumDomainUsers_async\n");
5002
5003         r.in.domain_handle = handle;
5004         r.in.resume_handle = &resume_handle;
5005         r.in.acct_flags = 0;
5006         r.in.max_size = (uint32_t)-1;
5007         r.out.resume_handle = &resume_handle;
5008
5009         for (i=0;i<ASYNC_COUNT;i++) {
5010                 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
5011         }
5012
5013         for (i=0;i<ASYNC_COUNT;i++) {
5014                 status = dcerpc_ndr_request_recv(req[i]);
5015                 if (!NT_STATUS_IS_OK(status)) {
5016                         torture_warning(tctx, "EnumDomainUsers[%d] failed - %s\n",
5017                                i, nt_errstr(status));
5018                         return false;
5019                 }
5020         }
5021
5022         torture_comment(tctx, "%d async requests OK\n", i);
5023
5024         return true;
5025 }
5026
5027 static bool test_EnumDomainGroups_all(struct dcerpc_pipe *p,
5028                                       struct torture_context *tctx,
5029                                       struct policy_handle *handle)
5030 {
5031         NTSTATUS status;
5032         struct samr_EnumDomainGroups r;
5033         uint32_t resume_handle=0;
5034         struct samr_SamArray *sam = NULL;
5035         uint32_t num_entries = 0;
5036         int i;
5037         bool ret = true;
5038
5039         torture_comment(tctx, "Testing EnumDomainGroups\n");
5040
5041         r.in.domain_handle = handle;
5042         r.in.resume_handle = &resume_handle;
5043         r.in.max_size = (uint32_t)-1;
5044         r.out.resume_handle = &resume_handle;
5045         r.out.num_entries = &num_entries;
5046         r.out.sam = &sam;
5047
5048         status = dcerpc_samr_EnumDomainGroups(p, tctx, &r);
5049         if (!NT_STATUS_IS_OK(status)) {
5050                 torture_warning(tctx, "EnumDomainGroups failed - %s\n", nt_errstr(status));
5051                 return false;
5052         }
5053
5054         if (!sam) {
5055                 return false;
5056         }
5057
5058         for (i=0;i<sam->count;i++) {
5059                 if (!test_OpenGroup(p, tctx, handle, sam->entries[i].idx)) {
5060                         ret = false;
5061                 }
5062         }
5063
5064         return ret;
5065 }
5066
5067 static bool test_EnumDomainAliases_all(struct dcerpc_pipe *p,
5068                                        struct torture_context *tctx,
5069                                        struct policy_handle *handle)
5070 {
5071         NTSTATUS status;
5072         struct samr_EnumDomainAliases r;
5073         uint32_t resume_handle=0;
5074         struct samr_SamArray *sam = NULL;
5075         uint32_t num_entries = 0;
5076         int i;
5077         bool ret = true;
5078
5079         torture_comment(tctx, "Testing EnumDomainAliases\n");
5080
5081         r.in.domain_handle = handle;
5082         r.in.resume_handle = &resume_handle;
5083         r.in.max_size = (uint32_t)-1;
5084         r.out.sam = &sam;
5085         r.out.num_entries = &num_entries;
5086         r.out.resume_handle = &resume_handle;
5087
5088         status = dcerpc_samr_EnumDomainAliases(p, tctx, &r);
5089         if (!NT_STATUS_IS_OK(status)) {
5090                 torture_warning(tctx, "EnumDomainAliases failed - %s\n", nt_errstr(status));
5091                 return false;
5092         }
5093
5094         if (!sam) {
5095                 return false;
5096         }
5097
5098         for (i=0;i<sam->count;i++) {
5099                 if (!test_OpenAlias(p, tctx, handle, sam->entries[i].idx)) {
5100                         ret = false;
5101                 }
5102         }
5103
5104         return ret;
5105 }
5106
5107 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p,
5108                                             struct torture_context *tctx,
5109                                             struct policy_handle *handle)
5110 {
5111         NTSTATUS status;
5112         struct samr_GetDisplayEnumerationIndex r;
5113         bool ret = true;
5114         uint16_t levels[] = {1, 2, 3, 4, 5};
5115         uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
5116         struct lsa_String name;
5117         uint32_t idx = 0;
5118         int i;
5119
5120         for (i=0;i<ARRAY_SIZE(levels);i++) {
5121                 torture_comment(tctx, "Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
5122
5123                 init_lsa_String(&name, TEST_ACCOUNT_NAME);
5124
5125                 r.in.domain_handle = handle;
5126                 r.in.level = levels[i];
5127                 r.in.name = &name;
5128                 r.out.idx = &idx;
5129
5130                 status = dcerpc_samr_GetDisplayEnumerationIndex(p, tctx, &r);
5131
5132                 if (ok_lvl[i] &&
5133                     !NT_STATUS_IS_OK(status) &&
5134                     !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5135                         torture_warning(tctx, "GetDisplayEnumerationIndex level %u failed - %s\n",
5136                                levels[i], nt_errstr(status));
5137                         ret = false;
5138                 }
5139
5140                 init_lsa_String(&name, "zzzzzzzz");
5141
5142                 status = dcerpc_samr_GetDisplayEnumerationIndex(p, tctx, &r);
5143
5144                 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5145                         torture_warning(tctx, "GetDisplayEnumerationIndex level %u failed - %s\n",
5146                                levels[i], nt_errstr(status));
5147                         ret = false;
5148                 }
5149         }
5150
5151         return ret;
5152 }
5153
5154 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p,
5155                                              struct torture_context *tctx,
5156                                              struct policy_handle *handle)
5157 {
5158         NTSTATUS status;
5159         struct samr_GetDisplayEnumerationIndex2 r;
5160         bool ret = true;
5161         uint16_t levels[] = {1, 2, 3, 4, 5};
5162         uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
5163         struct lsa_String name;
5164         uint32_t idx = 0;
5165         int i;
5166
5167         for (i=0;i<ARRAY_SIZE(levels);i++) {
5168                 torture_comment(tctx, "Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
5169
5170                 init_lsa_String(&name, TEST_ACCOUNT_NAME);
5171
5172                 r.in.domain_handle = handle;
5173                 r.in.level = levels[i];
5174                 r.in.name = &name;
5175                 r.out.idx = &idx;
5176
5177                 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, tctx, &r);
5178                 if (ok_lvl[i] &&
5179                     !NT_STATUS_IS_OK(status) &&
5180                     !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5181                         torture_warning(tctx, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
5182                                levels[i], nt_errstr(status));
5183                         ret = false;
5184                 }
5185
5186                 init_lsa_String(&name, "zzzzzzzz");
5187
5188                 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, tctx, &r);
5189                 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5190                         torture_warning(tctx, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
5191                                levels[i], nt_errstr(status));
5192                         ret = false;
5193                 }
5194         }
5195
5196         return ret;
5197 }
5198
5199 #define STRING_EQUAL_QUERY(s1, s2, user)                                        \
5200         if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
5201                 /* odd, but valid */                                            \
5202         } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
5203                         torture_warning(tctx, "%s mismatch for %s: %s != %s (%s)\n", \
5204                                #s1, user.string,  s1.string, s2.string, __location__);   \
5205                         ret = false; \
5206         }
5207 #define INT_EQUAL_QUERY(s1, s2, user)           \
5208                 if (s1 != s2) { \
5209                         torture_warning(tctx, "%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
5210                                #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
5211                         ret = false; \
5212                 }
5213
5214 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p,
5215                                        struct torture_context *tctx,
5216                                        struct samr_QueryDisplayInfo *querydisplayinfo,
5217                                        bool *seen_testuser)
5218 {
5219         struct samr_OpenUser r;
5220         struct samr_QueryUserInfo q;
5221         union samr_UserInfo *info;
5222         struct policy_handle user_handle;
5223         int i, ret = true;
5224         NTSTATUS status;
5225         r.in.domain_handle = querydisplayinfo->in.domain_handle;
5226         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5227         for (i = 0; ; i++) {
5228                 switch (querydisplayinfo->in.level) {
5229                 case 1:
5230                         if (i >= querydisplayinfo->out.info->info1.count) {
5231                                 return ret;
5232                         }
5233                         r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
5234                         break;
5235                 case 2:
5236                         if (i >= querydisplayinfo->out.info->info2.count) {
5237                                 return ret;
5238                         }
5239                         r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
5240                         break;
5241                 case 3:
5242                         /* Groups */
5243                 case 4:
5244                 case 5:
5245                         /* Not interested in validating just the account name */
5246                         return true;
5247                 }
5248
5249                 r.out.user_handle = &user_handle;
5250
5251                 switch (querydisplayinfo->in.level) {
5252                 case 1:
5253                 case 2:
5254                         status = dcerpc_samr_OpenUser(p, tctx, &r);
5255                         if (!NT_STATUS_IS_OK(status)) {
5256                                 torture_warning(tctx, "OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
5257                                 return false;
5258                         }
5259                 }
5260
5261                 q.in.user_handle = &user_handle;
5262                 q.in.level = 21;
5263                 q.out.info = &info;
5264                 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
5265                 if (!NT_STATUS_IS_OK(status)) {
5266                         torture_warning(tctx, "QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
5267                         return false;
5268                 }
5269
5270                 switch (querydisplayinfo->in.level) {
5271                 case 1:
5272                         if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
5273                                 *seen_testuser = true;
5274                         }
5275                         STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
5276                                            info->info21.full_name, info->info21.account_name);
5277                         STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
5278                                            info->info21.account_name, info->info21.account_name);
5279                         STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
5280                                            info->info21.description, info->info21.account_name);
5281                         INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
5282                                         info->info21.rid, info->info21.account_name);
5283                         INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
5284                                         info->info21.acct_flags, info->info21.account_name);
5285
5286                         break;
5287                 case 2:
5288                         STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
5289                                            info->info21.account_name, info->info21.account_name);
5290                         STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
5291                                            info->info21.description, info->info21.account_name);
5292                         INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
5293                                         info->info21.rid, info->info21.account_name);
5294                         INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
5295                                         info->info21.acct_flags, info->info21.account_name);
5296
5297                         if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
5298                                 torture_warning(tctx, "Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
5299                                        info->info21.account_name.string);
5300                         }
5301
5302                         if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
5303                                 torture_warning(tctx, "Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
5304                                        info->info21.account_name.string,
5305                                        querydisplayinfo->out.info->info2.entries[i].acct_flags,
5306                                        info->info21.acct_flags);
5307                                 return false;
5308                         }
5309
5310                         break;
5311                 }
5312
5313                 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
5314                         return false;
5315                 }
5316         }
5317         return ret;
5318 }
5319
5320 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p,
5321                                   struct torture_context *tctx,
5322                                   struct policy_handle *handle)
5323 {
5324         NTSTATUS status;
5325         struct samr_QueryDisplayInfo r;
5326         struct samr_QueryDomainInfo dom_info;
5327         union samr_DomainInfo *info = NULL;
5328         bool ret = true;
5329         uint16_t levels[] = {1, 2, 3, 4, 5};
5330         int i;
5331         bool seen_testuser = false;
5332         uint32_t total_size;
5333         uint32_t returned_size;
5334         union samr_DispInfo disp_info;
5335
5336
5337         for (i=0;i<ARRAY_SIZE(levels);i++) {
5338                 torture_comment(tctx, "Testing QueryDisplayInfo level %u\n", levels[i]);
5339
5340                 r.in.start_idx = 0;
5341                 status = STATUS_MORE_ENTRIES;
5342                 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5343                         r.in.domain_handle = handle;
5344                         r.in.level = levels[i];
5345                         r.in.max_entries = 2;
5346                         r.in.buf_size = (uint32_t)-1;
5347                         r.out.total_size = &total_size;
5348                         r.out.returned_size = &returned_size;
5349                         r.out.info = &disp_info;
5350
5351                         status = dcerpc_samr_QueryDisplayInfo(p, tctx, &r);
5352                         if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
5353                                 torture_warning(tctx, "QueryDisplayInfo level %u failed - %s\n",
5354                                        levels[i], nt_errstr(status));
5355                                 ret = false;
5356                         }
5357                         switch (r.in.level) {
5358                         case 1:
5359                                 if (!test_each_DisplayInfo_user(p, tctx, &r, &seen_testuser)) {
5360                                         ret = false;
5361                                 }
5362                                 r.in.start_idx += r.out.info->info1.count;
5363                                 break;
5364                         case 2:
5365                                 if (!test_each_DisplayInfo_user(p, tctx, &r, NULL)) {
5366                                         ret = false;
5367                                 }
5368                                 r.in.start_idx += r.out.info->info2.count;
5369                                 break;
5370                         case 3:
5371                                 r.in.start_idx += r.out.info->info3.count;
5372                                 break;
5373                         case 4:
5374                                 r.in.start_idx += r.out.info->info4.count;
5375                                 break;
5376                         case 5:
5377                                 r.in.start_idx += r.out.info->info5.count;
5378                                 break;
5379                         }
5380                 }
5381                 dom_info.in.domain_handle = handle;
5382                 dom_info.in.level = 2;
5383                 dom_info.out.info = &info;
5384
5385                 /* Check number of users returned is correct */
5386                 status = dcerpc_samr_QueryDomainInfo(p, tctx, &dom_info);
5387                 if (!NT_STATUS_IS_OK(status)) {
5388                         torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
5389                                r.in.level, nt_errstr(status));
5390                                 ret = false;
5391                                 break;
5392                 }
5393                 switch (r.in.level) {
5394                 case 1:
5395                 case 4:
5396                         if (info->general.num_users < r.in.start_idx) {
5397                                 torture_warning(tctx, "QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
5398                                        r.in.start_idx, info->general.num_groups,
5399                                        info->general.domain_name.string);
5400                                 ret = false;
5401                         }
5402                         if (!seen_testuser) {
5403                                 struct policy_handle user_handle;
5404                                 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, tctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
5405                                         torture_warning(tctx, "Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
5406                                                info->general.domain_name.string);
5407                                         ret = false;
5408                                         test_samr_handle_Close(p, tctx, &user_handle);
5409                                 }
5410                         }
5411                         break;
5412                 case 3:
5413                 case 5:
5414                         if (info->general.num_groups != r.in.start_idx) {
5415                                 torture_warning(tctx, "QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
5416                                        r.in.start_idx, info->general.num_groups,
5417                                        info->general.domain_name.string);
5418                                 ret = false;
5419                         }
5420
5421                         break;
5422                 }
5423
5424         }
5425
5426         return ret;
5427 }
5428
5429 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p,
5430                                    struct torture_context *tctx,
5431                                    struct policy_handle *handle)
5432 {
5433         NTSTATUS status;
5434         struct samr_QueryDisplayInfo2 r;
5435         bool ret = true;
5436         uint16_t levels[] = {1, 2, 3, 4, 5};
5437         int i;
5438         uint32_t total_size;
5439         uint32_t returned_size;
5440         union samr_DispInfo info;
5441
5442         for (i=0;i<ARRAY_SIZE(levels);i++) {
5443                 torture_comment(tctx, "Testing QueryDisplayInfo2 level %u\n", levels[i]);
5444
5445                 r.in.domain_handle = handle;
5446                 r.in.level = levels[i];
5447                 r.in.start_idx = 0;
5448                 r.in.max_entries = 1000;
5449                 r.in.buf_size = (uint32_t)-1;
5450                 r.out.total_size = &total_size;
5451                 r.out.returned_size = &returned_size;
5452                 r.out.info = &info;
5453
5454                 status = dcerpc_samr_QueryDisplayInfo2(p, tctx, &r);
5455                 if (!NT_STATUS_IS_OK(status)) {
5456                         torture_warning(tctx, "QueryDisplayInfo2 level %u failed - %s\n",
5457                                levels[i], nt_errstr(status));
5458                         ret = false;
5459                 }
5460         }
5461
5462         return ret;
5463 }
5464
5465 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context *tctx,
5466                                   struct policy_handle *handle)
5467 {
5468         NTSTATUS status;
5469         struct samr_QueryDisplayInfo3 r;
5470         bool ret = true;
5471         uint16_t levels[] = {1, 2, 3, 4, 5};
5472         int i;
5473         uint32_t total_size;
5474         uint32_t returned_size;
5475         union samr_DispInfo info;
5476
5477         for (i=0;i<ARRAY_SIZE(levels);i++) {
5478                 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
5479
5480                 r.in.domain_handle = handle;
5481                 r.in.level = levels[i];
5482                 r.in.start_idx = 0;
5483                 r.in.max_entries = 1000;
5484                 r.in.buf_size = (uint32_t)-1;
5485                 r.out.total_size = &total_size;
5486                 r.out.returned_size = &returned_size;
5487                 r.out.info = &info;
5488
5489                 status = dcerpc_samr_QueryDisplayInfo3(p, tctx, &r);
5490                 if (!NT_STATUS_IS_OK(status)) {
5491                         torture_warning(tctx, "QueryDisplayInfo3 level %u failed - %s\n",
5492                                levels[i], nt_errstr(status));
5493                         ret = false;
5494                 }
5495         }
5496
5497         return ret;
5498 }
5499
5500
5501 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p,
5502                                            struct torture_context *tctx,
5503                                            struct policy_handle *handle)
5504 {
5505         NTSTATUS status;
5506         struct samr_QueryDisplayInfo r;
5507         bool ret = true;
5508         uint32_t total_size;
5509         uint32_t returned_size;
5510         union samr_DispInfo info;
5511
5512         torture_comment(tctx, "Testing QueryDisplayInfo continuation\n");
5513
5514         r.in.domain_handle = handle;
5515         r.in.level = 1;
5516         r.in.start_idx = 0;
5517         r.in.max_entries = 1;
5518         r.in.buf_size = (uint32_t)-1;
5519         r.out.total_size = &total_size;
5520         r.out.returned_size = &returned_size;
5521         r.out.info = &info;
5522
5523         do {
5524                 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &r);
5525                 if (NT_STATUS_IS_OK(status) && *r.out.returned_size != 0) {
5526                         if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
5527                                 torture_warning(tctx, "expected idx %d but got %d\n",
5528                                        r.in.start_idx + 1,
5529                                        r.out.info->info1.entries[0].idx);
5530                                 break;
5531                         }
5532                 }
5533                 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
5534                     !NT_STATUS_IS_OK(status)) {
5535                         torture_warning(tctx, "QueryDisplayInfo level %u failed - %s\n",
5536                                r.in.level, nt_errstr(status));
5537                         ret = false;
5538                         break;
5539                 }
5540                 r.in.start_idx++;
5541         } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
5542                   NT_STATUS_IS_OK(status)) &&
5543                  *r.out.returned_size != 0);
5544
5545         return ret;
5546 }
5547
5548 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
5549                                  struct policy_handle *handle)
5550 {
5551         NTSTATUS status;
5552         struct samr_QueryDomainInfo r;
5553         union samr_DomainInfo *info = NULL;
5554         struct samr_SetDomainInfo s;
5555         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5556         uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1,  0,  1,  0};
5557         int i;
5558         bool ret = true;
5559         const char *domain_comment = talloc_asprintf(tctx,
5560                                   "Tortured by Samba4 RPC-SAMR: %s",
5561                                   timestring(tctx, time(NULL)));
5562
5563         s.in.domain_handle = handle;
5564         s.in.level = 4;
5565         s.in.info = talloc(tctx, union samr_DomainInfo);
5566
5567         s.in.info->oem.oem_information.string = domain_comment;
5568         status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5569         if (!NT_STATUS_IS_OK(status)) {
5570                 torture_warning(tctx, "SetDomainInfo level %u (set comment) failed - %s\n",
5571                        s.in.level, nt_errstr(status));
5572                 return false;
5573         }
5574
5575         for (i=0;i<ARRAY_SIZE(levels);i++) {
5576                 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
5577
5578                 r.in.domain_handle = handle;
5579                 r.in.level = levels[i];
5580                 r.out.info = &info;
5581
5582                 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
5583                 if (!NT_STATUS_IS_OK(status)) {
5584                         torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
5585                                r.in.level, nt_errstr(status));
5586                         ret = false;
5587                         continue;
5588                 }
5589
5590                 switch (levels[i]) {
5591                 case 2:
5592                         if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
5593                                 torture_warning(tctx, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
5594                                        levels[i], info->general.oem_information.string, domain_comment);
5595                                 if (!torture_setting_bool(tctx, "samba3", false)) {
5596                                         ret = false;
5597                                 }
5598                         }
5599                         if (!info->general.primary.string) {
5600                                 torture_warning(tctx, "QueryDomainInfo level %u returned no PDC name\n",
5601                                        levels[i]);
5602                                 ret = false;
5603                         } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
5604                                 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
5605                                         torture_warning(tctx, "QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
5606                                                levels[i], info->general.primary.string, dcerpc_server_name(p));
5607                                 }
5608                         }
5609                         break;
5610                 case 4:
5611                         if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
5612                                 torture_warning(tctx, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
5613                                        levels[i], info->oem.oem_information.string, domain_comment);
5614                                 if (!torture_setting_bool(tctx, "samba3", false)) {
5615                                         ret = false;
5616                                 }
5617                         }
5618                         break;
5619                 case 6:
5620                         if (!info->info6.primary.string) {
5621                                 torture_warning(tctx, "QueryDomainInfo level %u returned no PDC name\n",
5622                                        levels[i]);
5623                                 ret = false;
5624                         }
5625                         break;
5626                 case 11:
5627                         if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
5628                                 torture_warning(tctx, "QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
5629                                        levels[i], info->general2.general.oem_information.string, domain_comment);
5630                                 if (!torture_setting_bool(tctx, "samba3", false)) {
5631                                         ret = false;
5632                                 }
5633                         }
5634                         break;
5635                 }
5636
5637                 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
5638
5639                 s.in.domain_handle = handle;
5640                 s.in.level = levels[i];
5641                 s.in.info = info;
5642
5643                 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5644                 if (set_ok[i]) {
5645                         if (!NT_STATUS_IS_OK(status)) {
5646                                 torture_warning(tctx, "SetDomainInfo level %u failed - %s\n",
5647                                        r.in.level, nt_errstr(status));
5648                                 ret = false;
5649                                 continue;
5650                         }
5651                 } else {
5652                         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
5653                                 torture_warning(tctx, "SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
5654                                        r.in.level, nt_errstr(status));
5655                                 ret = false;
5656                                 continue;
5657                         }
5658                 }
5659
5660                 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
5661                 if (!NT_STATUS_IS_OK(status)) {
5662                         torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
5663                                r.in.level, nt_errstr(status));
5664                         ret = false;
5665                         continue;
5666                 }
5667         }
5668
5669         return ret;
5670 }
5671
5672
5673 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context *tctx,
5674                                   struct policy_handle *handle)
5675 {
5676         NTSTATUS status;
5677         struct samr_QueryDomainInfo2 r;
5678         union samr_DomainInfo *info = NULL;
5679         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5680         int i;
5681         bool ret = true;
5682
5683         for (i=0;i<ARRAY_SIZE(levels);i++) {
5684                 torture_comment(tctx, "Testing QueryDomainInfo2 level %u\n", levels[i]);
5685
5686                 r.in.domain_handle = handle;
5687                 r.in.level = levels[i];
5688                 r.out.info = &info;
5689
5690                 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
5691                 if (!NT_STATUS_IS_OK(status)) {
5692                         torture_warning(tctx, "QueryDomainInfo2 level %u failed - %s\n",
5693                                r.in.level, nt_errstr(status));
5694                         ret = false;
5695                         continue;
5696                 }
5697         }
5698
5699         return true;
5700 }
5701
5702 /* Test whether querydispinfo level 5 and enumdomgroups return the same
5703    set of group names. */
5704 static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
5705                            struct policy_handle *handle)
5706 {
5707         struct samr_EnumDomainGroups q1;
5708         struct samr_QueryDisplayInfo q2;
5709         NTSTATUS status;
5710         uint32_t resume_handle=0;
5711         struct samr_SamArray *sam = NULL;
5712         uint32_t num_entries = 0;
5713         int i;
5714         bool ret = true;
5715         uint32_t total_size;
5716         uint32_t returned_size;
5717         union samr_DispInfo info;
5718
5719         int num_names = 0;
5720         const char **names = NULL;
5721
5722         torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
5723
5724         q1.in.domain_handle = handle;
5725         q1.in.resume_handle = &resume_handle;
5726         q1.in.max_size = 5;
5727         q1.out.resume_handle = &resume_handle;
5728         q1.out.num_entries = &num_entries;
5729         q1.out.sam = &sam;
5730
5731         status = STATUS_MORE_ENTRIES;
5732         while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5733                 status = dcerpc_samr_EnumDomainGroups(p, tctx, &q1);
5734
5735                 if (!NT_STATUS_IS_OK(status) &&
5736                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
5737                         break;
5738
5739                 for (i=0; i<*q1.out.num_entries; i++) {
5740                         add_string_to_array(tctx,
5741                                             sam->entries[i].name.string,
5742                                             &names, &num_names);
5743                 }
5744         }
5745
5746         torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
5747
5748         torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
5749
5750         q2.in.domain_handle = handle;
5751         q2.in.level = 5;
5752         q2.in.start_idx = 0;
5753         q2.in.max_entries = 5;
5754         q2.in.buf_size = (uint32_t)-1;
5755         q2.out.total_size = &total_size;
5756         q2.out.returned_size = &returned_size;
5757         q2.out.info = &info;
5758
5759         status = STATUS_MORE_ENTRIES;
5760         while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5761                 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &q2);
5762
5763                 if (!NT_STATUS_IS_OK(status) &&
5764                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
5765                         break;
5766
5767                 for (i=0; i<q2.out.info->info5.count; i++) {
5768                         int j;
5769                         const char *name = q2.out.info->info5.entries[i].account_name.string;
5770                         bool found = false;
5771                         for (j=0; j<num_names; j++) {
5772                                 if (names[j] == NULL)
5773                                         continue;
5774                                 if (strequal(names[j], name)) {
5775                                         names[j] = NULL;
5776                                         found = true;
5777                                         break;
5778                                 }
5779                         }
5780
5781                         if (!found) {
5782                                 torture_warning(tctx, "QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
5783                                        name);
5784                                 ret = false;
5785                         }
5786                 }
5787                 q2.in.start_idx += q2.out.info->info5.count;
5788         }
5789
5790         if (!NT_STATUS_IS_OK(status)) {
5791                 torture_warning(tctx, "QueryDisplayInfo level 5 failed - %s\n",
5792                        nt_errstr(status));
5793                 ret = false;
5794         }
5795
5796         for (i=0; i<num_names; i++) {
5797                 if (names[i] != NULL) {
5798                         torture_warning(tctx, "EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
5799                                names[i]);
5800                         ret = false;
5801                 }
5802         }
5803
5804         return ret;
5805 }
5806
5807 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, struct torture_context *tctx,
5808                                    struct policy_handle *group_handle)
5809 {
5810         struct samr_DeleteDomainGroup d;
5811         NTSTATUS status;
5812
5813         torture_comment(tctx, "Testing DeleteDomainGroup\n");
5814
5815         d.in.group_handle = group_handle;
5816         d.out.group_handle = group_handle;
5817
5818         status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
5819         torture_assert_ntstatus_ok(tctx, status, "DeleteDomainGroup");
5820
5821         return true;
5822 }
5823
5824 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5825                                             struct policy_handle *domain_handle)
5826 {
5827         struct samr_TestPrivateFunctionsDomain r;
5828         NTSTATUS status;
5829         bool ret = true;
5830
5831         torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
5832
5833         r.in.domain_handle = domain_handle;
5834
5835         status = dcerpc_samr_TestPrivateFunctionsDomain(p, tctx, &r);
5836         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsDomain");
5837
5838         return ret;
5839 }
5840
5841 static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
5842                           struct dom_sid *domain_sid,
5843                           struct policy_handle *domain_handle)
5844 {
5845         struct samr_RidToSid r;
5846         NTSTATUS status;
5847         bool ret = true;
5848         struct dom_sid *calc_sid, *out_sid;
5849         int rids[] = { 0, 42, 512, 10200 };
5850         int i;
5851
5852         for (i=0;i<ARRAY_SIZE(rids);i++) {
5853                 torture_comment(tctx, "Testing RidToSid\n");
5854
5855                 calc_sid = dom_sid_dup(tctx, domain_sid);
5856                 r.in.domain_handle = domain_handle;
5857                 r.in.rid = rids[i];
5858                 r.out.sid = &out_sid;
5859
5860                 status = dcerpc_samr_RidToSid(p, tctx, &r);
5861                 if (!NT_STATUS_IS_OK(status)) {
5862                         torture_warning(tctx, "RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
5863                         ret = false;
5864                 } else {
5865                         calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
5866
5867                         if (!dom_sid_equal(calc_sid, out_sid)) {
5868                                 torture_warning(tctx, "RidToSid for %d failed - got %s, expected %s\n", rids[i],
5869                                        dom_sid_string(tctx, out_sid),
5870                                        dom_sid_string(tctx, calc_sid));
5871                                 ret = false;
5872                         }
5873                 }
5874         }
5875
5876         return ret;
5877 }
5878
5879 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, struct torture_context *tctx,
5880                                        struct policy_handle *domain_handle)
5881 {
5882         struct samr_GetBootKeyInformation r;
5883         NTSTATUS status;
5884         bool ret = true;
5885         uint32_t unknown = 0;
5886
5887         torture_comment(tctx, "Testing GetBootKeyInformation\n");
5888
5889         r.in.domain_handle = domain_handle;
5890         r.out.unknown = &unknown;
5891
5892         status = dcerpc_samr_GetBootKeyInformation(p, tctx, &r);
5893         if (!NT_STATUS_IS_OK(status)) {
5894                 /* w2k3 seems to fail this sometimes and pass it sometimes */
5895                 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
5896         }
5897
5898         return ret;
5899 }
5900
5901 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx,
5902                                 struct policy_handle *domain_handle,
5903                                 struct policy_handle *group_handle)
5904 {
5905         NTSTATUS status;
5906         struct samr_AddGroupMember r;
5907         struct samr_DeleteGroupMember d;
5908         struct samr_QueryGroupMember q;
5909         struct samr_RidTypeArray *rids = NULL;
5910         struct samr_SetMemberAttributesOfGroup s;
5911         uint32_t rid;
5912         bool found_member = false;
5913         int i;
5914
5915         status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
5916         torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
5917
5918         r.in.group_handle = group_handle;
5919         r.in.rid = rid;
5920         r.in.flags = 0; /* ??? */
5921
5922         torture_comment(tctx, "Testing AddGroupMember, QueryGroupMember and DeleteGroupMember\n");
5923
5924         d.in.group_handle = group_handle;
5925         d.in.rid = rid;
5926
5927         status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
5928         torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, status, "DeleteGroupMember");
5929
5930         status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5931         torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
5932
5933         status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5934         torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, status, "AddGroupMember");
5935
5936         if (torture_setting_bool(tctx, "samba4", false) ||
5937             torture_setting_bool(tctx, "samba3", false)) {
5938                 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba\n");
5939         } else {
5940                 /* this one is quite strange. I am using random inputs in the
5941                    hope of triggering an error that might give us a clue */
5942
5943                 s.in.group_handle = group_handle;
5944                 s.in.unknown1 = random();
5945                 s.in.unknown2 = random();
5946
5947                 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
5948                 torture_assert_ntstatus_ok(tctx, status, "SetMemberAttributesOfGroup");
5949         }
5950
5951         q.in.group_handle = group_handle;
5952         q.out.rids = &rids;
5953
5954         status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
5955         torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
5956         torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
5957
5958         for (i=0; i < rids->count; i++) {
5959                 if (rids->rids[i] == rid) {
5960                         found_member = true;
5961                 }
5962         }
5963
5964         torture_assert(tctx, found_member, "QueryGroupMember did not list newly added member");
5965
5966         status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
5967         torture_assert_ntstatus_ok(tctx, status, "DeleteGroupMember");
5968
5969         rids = NULL;
5970         found_member = false;
5971
5972         status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
5973         torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
5974         torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
5975
5976         for (i=0; i < rids->count; i++) {
5977                 if (rids->rids[i] == rid) {
5978                         found_member = true;
5979                 }
5980         }
5981
5982         torture_assert(tctx, !found_member, "QueryGroupMember does still list removed member");
5983
5984         status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5985         torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
5986
5987         return true;
5988 }
5989
5990
5991 static bool test_CreateDomainGroup(struct dcerpc_pipe *p,
5992                                    struct torture_context *tctx,
5993                                    struct policy_handle *domain_handle,
5994                                    const char *group_name,
5995                                    struct policy_handle *group_handle,
5996                                    struct dom_sid *domain_sid,
5997                                    bool test_group)
5998 {
5999         NTSTATUS status;
6000         struct samr_CreateDomainGroup r;
6001         uint32_t rid;
6002         struct lsa_String name;
6003         bool ret = true;
6004
6005         init_lsa_String(&name, group_name);
6006
6007         r.in.domain_handle = domain_handle;
6008         r.in.name = &name;
6009         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6010         r.out.group_handle = group_handle;
6011         r.out.rid = &rid;
6012
6013         torture_comment(tctx, "Testing CreateDomainGroup(%s)\n", r.in.name->string);
6014
6015         status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
6016
6017         if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
6018                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6019                         torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
6020                         return true;
6021                 } else {
6022                         torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.name->string,
6023                                nt_errstr(status));
6024                         return false;
6025                 }
6026         }
6027
6028         if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
6029                 if (!test_DeleteGroup_byname(p, tctx, domain_handle, r.in.name->string)) {
6030                         torture_warning(tctx, "CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
6031                                nt_errstr(status));
6032                         return false;
6033                 }
6034                 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
6035         }
6036         if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
6037                 if (!test_DeleteUser_byname(p, tctx, domain_handle, r.in.name->string)) {
6038
6039                         torture_warning(tctx, "CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
6040                                nt_errstr(status));
6041                         return false;
6042                 }
6043                 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
6044         }
6045         torture_assert_ntstatus_ok(tctx, status, "CreateDomainGroup");
6046
6047         if (!test_group) {
6048                 return ret;
6049         }
6050
6051         if (!test_AddGroupMember(p, tctx, domain_handle, group_handle)) {
6052                 torture_warning(tctx, "CreateDomainGroup failed - %s\n", nt_errstr(status));
6053                 ret = false;
6054         }
6055
6056         if (!test_SetGroupInfo(p, tctx, group_handle)) {
6057                 ret = false;
6058         }
6059
6060         return ret;
6061 }
6062
6063
6064 /*
6065   its not totally clear what this does. It seems to accept any sid you like.
6066 */
6067 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
6068                                                struct torture_context *tctx,
6069                                                struct policy_handle *domain_handle)
6070 {
6071         NTSTATUS status;
6072         struct samr_RemoveMemberFromForeignDomain r;
6073
6074         r.in.domain_handle = domain_handle;
6075         r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
6076
6077         status = dcerpc_samr_RemoveMemberFromForeignDomain(p, tctx, &r);
6078         torture_assert_ntstatus_ok(tctx, status, "RemoveMemberFromForeignDomain");
6079
6080         return true;
6081 }
6082
6083 static bool test_EnumDomainUsers(struct dcerpc_pipe *p,
6084                                  struct torture_context *tctx,
6085                                  struct policy_handle *domain_handle,
6086                                  uint32_t *total_num_entries_p)
6087 {
6088         NTSTATUS status;
6089         struct samr_EnumDomainUsers r;
6090         uint32_t resume_handle = 0;
6091         uint32_t num_entries = 0;
6092         uint32_t total_num_entries = 0;
6093         struct samr_SamArray *sam;
6094
6095         r.in.domain_handle = domain_handle;
6096         r.in.acct_flags = 0;
6097         r.in.max_size = (uint32_t)-1;
6098         r.in.resume_handle = &resume_handle;
6099
6100         r.out.sam = &sam;
6101         r.out.num_entries = &num_entries;
6102         r.out.resume_handle = &resume_handle;
6103
6104         torture_comment(tctx, "Testing EnumDomainUsers\n");
6105
6106         do {
6107                 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
6108                 if (NT_STATUS_IS_ERR(status)) {
6109                         torture_assert_ntstatus_ok(tctx, status,
6110                                 "failed to enumerate users");
6111                 }
6112
6113                 total_num_entries += num_entries;
6114         } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
6115
6116         if (total_num_entries_p) {
6117                 *total_num_entries_p = total_num_entries;
6118         }
6119
6120         return true;
6121 }
6122
6123 static bool test_EnumDomainGroups(struct dcerpc_pipe *p,
6124                                   struct torture_context *tctx,
6125                                   struct policy_handle *domain_handle,
6126                                   uint32_t *total_num_entries_p)
6127 {
6128         NTSTATUS status;
6129         struct samr_EnumDomainGroups r;
6130         uint32_t resume_handle = 0;
6131         uint32_t num_entries = 0;
6132         uint32_t total_num_entries = 0;
6133         struct samr_SamArray *sam;
6134
6135         r.in.domain_handle = domain_handle;
6136         r.in.max_size = (uint32_t)-1;
6137         r.in.resume_handle = &resume_handle;
6138
6139         r.out.sam = &sam;
6140         r.out.num_entries = &num_entries;
6141         r.out.resume_handle = &resume_handle;
6142
6143         torture_comment(tctx, "Testing EnumDomainGroups\n");
6144
6145         do {
6146                 status = dcerpc_samr_EnumDomainGroups(p, tctx, &r);
6147                 if (NT_STATUS_IS_ERR(status)) {
6148                         torture_assert_ntstatus_ok(tctx, status,
6149                                 "failed to enumerate groups");
6150                 }
6151
6152                 total_num_entries += num_entries;
6153         } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
6154
6155         if (total_num_entries_p) {
6156                 *total_num_entries_p = total_num_entries;
6157         }
6158
6159         return true;
6160 }
6161
6162 static bool test_EnumDomainAliases(struct dcerpc_pipe *p,
6163                                    struct torture_context *tctx,
6164                                    struct policy_handle *domain_handle,
6165                                    uint32_t *total_num_entries_p)
6166 {
6167         NTSTATUS status;
6168         struct samr_EnumDomainAliases r;
6169         uint32_t resume_handle = 0;
6170         uint32_t num_entries = 0;
6171         uint32_t total_num_entries = 0;
6172         struct samr_SamArray *sam;
6173
6174         r.in.domain_handle = domain_handle;
6175         r.in.max_size = (uint32_t)-1;
6176         r.in.resume_handle = &resume_handle;
6177
6178         r.out.sam = &sam;
6179         r.out.num_entries = &num_entries;
6180         r.out.resume_handle = &resume_handle;
6181
6182         torture_comment(tctx, "Testing EnumDomainAliases\n");
6183
6184         do {
6185                 status = dcerpc_samr_EnumDomainAliases(p, tctx, &r);
6186                 if (NT_STATUS_IS_ERR(status)) {
6187                         torture_assert_ntstatus_ok(tctx, status,
6188                                 "failed to enumerate aliases");
6189                 }
6190
6191                 total_num_entries += num_entries;
6192         } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
6193
6194         if (total_num_entries_p) {
6195                 *total_num_entries_p = total_num_entries;
6196         }
6197
6198         return true;
6199 }
6200
6201 static bool test_QueryDisplayInfo_level(struct dcerpc_pipe *p,
6202                                         struct torture_context *tctx,
6203                                         struct policy_handle *handle,
6204                                         uint16_t level,
6205                                         uint32_t *total_num_entries_p)
6206 {
6207         NTSTATUS status;
6208         struct samr_QueryDisplayInfo r;
6209         uint32_t total_num_entries = 0;
6210
6211         r.in.domain_handle = handle;
6212         r.in.level = level;
6213         r.in.start_idx = 0;
6214         r.in.max_entries = (uint32_t)-1;
6215         r.in.buf_size = (uint32_t)-1;
6216
6217         torture_comment(tctx, "Testing QueryDisplayInfo\n");
6218
6219         do {
6220                 uint32_t total_size;
6221                 uint32_t returned_size;
6222                 union samr_DispInfo info;
6223
6224                 r.out.total_size = &total_size;
6225                 r.out.returned_size = &returned_size;
6226                 r.out.info = &info;
6227
6228                 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &r);
6229                 if (NT_STATUS_IS_ERR(status)) {
6230                         torture_assert_ntstatus_ok(tctx, status,
6231                                 "failed to query displayinfo");
6232                 }
6233
6234                 if (*r.out.returned_size == 0) {
6235                         break;
6236                 }
6237
6238                 switch (r.in.level) {
6239                 case 1:
6240                         total_num_entries += info.info1.count;
6241                         r.in.start_idx += info.info1.entries[info.info1.count - 1].idx + 1;
6242                         break;
6243                 case 2:
6244                         total_num_entries += info.info2.count;
6245                         r.in.start_idx += info.info2.entries[info.info2.count - 1].idx + 1;
6246                         break;
6247                 case 3:
6248                         total_num_entries += info.info3.count;
6249                         r.in.start_idx += info.info3.entries[info.info3.count - 1].idx + 1;
6250                         break;
6251                 case 4:
6252                         total_num_entries += info.info4.count;
6253                         r.in.start_idx += info.info4.entries[info.info4.count - 1].idx + 1;
6254                         break;
6255                 case 5:
6256                         total_num_entries += info.info5.count;
6257                         r.in.start_idx += info.info5.entries[info.info5.count - 1].idx + 1;
6258                         break;
6259                 default:
6260                         return false;
6261                 }
6262
6263         } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
6264
6265         if (total_num_entries_p) {
6266                 *total_num_entries_p = total_num_entries;
6267         }
6268
6269         return true;
6270 }
6271
6272 static bool test_ManyObjects(struct dcerpc_pipe *p,
6273                              struct torture_context *tctx,
6274                              struct policy_handle *domain_handle,
6275                              struct dom_sid *domain_sid,
6276                              enum torture_samr_choice which_ops)
6277 {
6278         uint32_t num_total = 1500;
6279         uint32_t num_enum = 0;
6280         uint32_t num_disp = 0;
6281         uint32_t num_created = 0;
6282         uint32_t num_anounced = 0;
6283         bool ret = true;
6284         NTSTATUS status;
6285         uint32_t i;
6286
6287         struct policy_handle *handles = talloc_zero_array(tctx, struct policy_handle, num_total);
6288
6289         /* query */
6290
6291         {
6292                 struct samr_QueryDomainInfo2 r;
6293                 union samr_DomainInfo *info;
6294                 r.in.domain_handle = domain_handle;
6295                 r.in.level = 2;
6296                 r.out.info = &info;
6297
6298                 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
6299                 torture_assert_ntstatus_ok(tctx, status,
6300                         "failed to query domain info");
6301
6302                 switch (which_ops) {
6303                 case TORTURE_SAMR_MANY_ACCOUNTS:
6304                         num_anounced = info->general.num_users;
6305                         break;
6306                 case TORTURE_SAMR_MANY_GROUPS:
6307                         num_anounced = info->general.num_groups;
6308                         break;
6309                 case TORTURE_SAMR_MANY_ALIASES:
6310                         num_anounced = info->general.num_aliases;
6311                         break;
6312                 default:
6313                         return false;
6314                 }
6315         }
6316
6317         /* create */
6318
6319         for (i=0; i < num_total; i++) {
6320
6321                 const char *name = NULL;
6322
6323                 switch (which_ops) {
6324                 case TORTURE_SAMR_MANY_ACCOUNTS:
6325                         name = talloc_asprintf(tctx, "%s%04d", TEST_ACCOUNT_NAME, i);
6326                         ret &= test_CreateUser(p, tctx, domain_handle, name, &handles[i], domain_sid, 0, NULL, false);
6327                         break;
6328                 case TORTURE_SAMR_MANY_GROUPS:
6329                         name = talloc_asprintf(tctx, "%s%04d", TEST_GROUPNAME, i);
6330                         ret &= test_CreateDomainGroup(p, tctx, domain_handle, name, &handles[i], domain_sid, false);
6331                         break;
6332                 case TORTURE_SAMR_MANY_ALIASES:
6333                         name = talloc_asprintf(tctx, "%s%04d", TEST_ALIASNAME, i);
6334                         ret &= test_CreateAlias(p, tctx, domain_handle, name, &handles[i], domain_sid, false);
6335                         break;
6336                 default:
6337                         return false;
6338                 }
6339                 if (!policy_handle_empty(&handles[i])) {
6340                         num_created++;
6341                 }
6342         }
6343
6344         /* enum */
6345
6346         switch (which_ops) {
6347         case TORTURE_SAMR_MANY_ACCOUNTS:
6348                 ret &= test_EnumDomainUsers(p, tctx, domain_handle, &num_enum);
6349                 break;
6350         case TORTURE_SAMR_MANY_GROUPS:
6351                 ret &= test_EnumDomainGroups(p, tctx, domain_handle, &num_enum);
6352                 break;
6353         case TORTURE_SAMR_MANY_ALIASES:
6354                 ret &= test_EnumDomainAliases(p, tctx, domain_handle, &num_enum);
6355                 break;
6356         default:
6357                 return false;
6358         }
6359
6360         /* dispinfo */
6361
6362         switch (which_ops) {
6363         case TORTURE_SAMR_MANY_ACCOUNTS:
6364                 ret &= test_QueryDisplayInfo_level(p, tctx, domain_handle, 1, &num_disp);
6365                 break;
6366         case TORTURE_SAMR_MANY_GROUPS:
6367                 ret &= test_QueryDisplayInfo_level(p, tctx, domain_handle, 3, &num_disp);
6368                 break;
6369         case TORTURE_SAMR_MANY_ALIASES:
6370                 /* no aliases in dispinfo */
6371                 break;
6372         default:
6373                 return false;
6374         }
6375
6376         /* close or delete */
6377
6378         for (i=0; i < num_total; i++) {
6379
6380                 if (policy_handle_empty(&handles[i])) {
6381                         continue;
6382                 }
6383
6384                 if (torture_setting_bool(tctx, "samba3", false)) {
6385                         ret &= test_samr_handle_Close(p, tctx, &handles[i]);
6386                 } else {
6387                         switch (which_ops) {
6388                         case TORTURE_SAMR_MANY_ACCOUNTS:
6389                                 ret &= test_DeleteUser(p, tctx, &handles[i]);
6390                                 break;
6391                         case TORTURE_SAMR_MANY_GROUPS:
6392                                 ret &= test_DeleteDomainGroup(p, tctx, &handles[i]);
6393                                 break;
6394                         case TORTURE_SAMR_MANY_ALIASES:
6395                                 ret &= test_DeleteAlias(p, tctx, &handles[i]);
6396                                 break;
6397                         default:
6398                                 return false;
6399                         }
6400                 }
6401         }
6402
6403         talloc_free(handles);
6404
6405         if (which_ops == TORTURE_SAMR_MANY_ACCOUNTS && num_enum != num_anounced + num_created) {
6406                 torture_comment(tctx,
6407                                 "unexpected number of results (%u) returned in enum call, expected %u\n",
6408                                 num_enum, num_anounced + num_created);
6409
6410                 torture_comment(tctx,
6411                                 "unexpected number of results (%u) returned in dispinfo, call, expected %u\n",
6412                                 num_disp, num_anounced + num_created);
6413         }
6414         return ret;
6415 }
6416
6417 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
6418                          struct policy_handle *handle);
6419
6420 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
6421                             struct policy_handle *handle, struct dom_sid *sid,
6422                             enum torture_samr_choice which_ops,
6423                             struct cli_credentials *machine_credentials)
6424 {
6425         NTSTATUS status;
6426         struct samr_OpenDomain r;
6427         struct policy_handle domain_handle;
6428         struct policy_handle alias_handle;
6429         struct policy_handle user_handle;
6430         struct policy_handle group_handle;
6431         bool ret = true;
6432
6433         ZERO_STRUCT(alias_handle);
6434         ZERO_STRUCT(user_handle);
6435         ZERO_STRUCT(group_handle);
6436         ZERO_STRUCT(domain_handle);
6437
6438         torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
6439
6440         r.in.connect_handle = handle;
6441         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6442         r.in.sid = sid;
6443         r.out.domain_handle = &domain_handle;
6444
6445         status = dcerpc_samr_OpenDomain(p, tctx, &r);
6446         torture_assert_ntstatus_ok(tctx, status, "OpenDomain");
6447
6448         /* run the domain tests with the main handle closed - this tests
6449            the servers reference counting */
6450         torture_assert(tctx, test_samr_handle_Close(p, tctx, handle), "Failed to close SAMR handle");
6451
6452         switch (which_ops) {
6453         case TORTURE_SAMR_PASSWORDS:
6454         case TORTURE_SAMR_USER_PRIVILEGES:
6455                 if (!torture_setting_bool(tctx, "samba3", false)) {
6456                         ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, NULL);
6457                 }
6458                 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, which_ops, NULL, true);
6459                 if (!ret) {
6460                         torture_warning(tctx, "Testing PASSWORDS or PRIVILEGES on domain %s failed!\n", dom_sid_string(tctx, sid));
6461                 }
6462                 break;
6463         case TORTURE_SAMR_USER_ATTRIBUTES:
6464                 if (!torture_setting_bool(tctx, "samba3", false)) {
6465                         ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, NULL);
6466                 }
6467                 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, which_ops, NULL, true);
6468                 /* This test needs 'complex' users to validate */
6469                 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
6470                 if (!ret) {
6471                         torture_warning(tctx, "Testing ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
6472                 }
6473                 break;
6474         case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
6475                 if (!torture_setting_bool(tctx, "samba3", false)) {
6476                         ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, machine_credentials);
6477                 }
6478                 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, which_ops, machine_credentials, true);
6479                 if (!ret) {
6480                         torture_warning(tctx, "Testing PASSWORDS PWDLASTSET on domain %s failed!\n", dom_sid_string(tctx, sid));
6481                 }
6482                 break;
6483         case TORTURE_SAMR_MANY_ACCOUNTS:
6484         case TORTURE_SAMR_MANY_GROUPS:
6485         case TORTURE_SAMR_MANY_ALIASES:
6486                 ret &= test_ManyObjects(p, tctx, &domain_handle, sid, which_ops);
6487                 if (!ret) {
6488                         torture_warning(tctx, "Testing MANY-{ACCOUNTS,GROUPS,ALIASES} on domain %s failed!\n", dom_sid_string(tctx, sid));
6489                 }
6490                 break;
6491         case TORTURE_SAMR_OTHER:
6492                 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, which_ops, NULL, true);
6493                 if (!ret) {
6494                         torture_warning(tctx, "Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
6495                 }
6496                 if (!torture_setting_bool(tctx, "samba3", false)) {
6497                         ret &= test_QuerySecurity(p, tctx, &domain_handle);
6498                 }
6499                 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
6500                 ret &= test_CreateAlias(p, tctx, &domain_handle, TEST_ALIASNAME, &alias_handle, sid, true);
6501                 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, TEST_GROUPNAME, &group_handle, sid, true);
6502                 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
6503                 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
6504                 ret &= test_EnumDomainUsers_all(p, tctx, &domain_handle);
6505                 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
6506                 ret &= test_EnumDomainGroups_all(p, tctx, &domain_handle);
6507                 ret &= test_EnumDomainAliases_all(p, tctx, &domain_handle);
6508                 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
6509                 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
6510                 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
6511
6512                 if (torture_setting_bool(tctx, "samba4", false)) {
6513                         torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
6514                 } else {
6515                         ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
6516                         ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
6517                 }
6518                 ret &= test_GroupList(p, tctx, &domain_handle);
6519                 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
6520                 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
6521                 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
6522                 if (!ret) {
6523                         torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
6524                 }
6525                 break;
6526         }
6527
6528         if (!policy_handle_empty(&user_handle) &&
6529             !test_DeleteUser(p, tctx, &user_handle)) {
6530                 ret = false;
6531         }
6532
6533         if (!policy_handle_empty(&alias_handle) &&
6534             !test_DeleteAlias(p, tctx, &alias_handle)) {
6535                 ret = false;
6536         }
6537
6538         if (!policy_handle_empty(&group_handle) &&
6539             !test_DeleteDomainGroup(p, tctx, &group_handle)) {
6540                 ret = false;
6541         }
6542
6543         torture_assert(tctx, test_samr_handle_Close(p, tctx, &domain_handle), "Failed to close SAMR domain handle");
6544
6545         torture_assert(tctx, test_Connect(p, tctx, handle), "Faile to re-connect SAMR handle");
6546         /* reconnect the main handle */
6547
6548         if (!ret) {
6549                 torture_warning(tctx, "Testing domain %s failed!\n", dom_sid_string(tctx, sid));
6550         }
6551
6552         return ret;
6553 }
6554
6555 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
6556                               struct policy_handle *handle, const char *domain,
6557                               enum torture_samr_choice which_ops,
6558                               struct cli_credentials *machine_credentials)
6559 {
6560         NTSTATUS status;
6561         struct samr_LookupDomain r;
6562         struct dom_sid2 *sid = NULL;
6563         struct lsa_String n1;
6564         struct lsa_String n2;
6565         bool ret = true;
6566
6567         torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
6568
6569         /* check for correct error codes */
6570         r.in.connect_handle = handle;
6571         r.in.domain_name = &n2;
6572         r.out.sid = &sid;
6573         n2.string = NULL;
6574
6575         status = dcerpc_samr_LookupDomain(p, tctx, &r);
6576         torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, status, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
6577
6578         init_lsa_String(&n2, "xxNODOMAINxx");
6579
6580         status = dcerpc_samr_LookupDomain(p, tctx, &r);
6581         torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, status, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
6582
6583         r.in.connect_handle = handle;
6584
6585         init_lsa_String(&n1, domain);
6586         r.in.domain_name = &n1;
6587
6588         status = dcerpc_samr_LookupDomain(p, tctx, &r);
6589         torture_assert_ntstatus_ok(tctx, status, "LookupDomain");
6590
6591         if (!test_GetDomPwInfo(p, tctx, &n1)) {
6592                 ret = false;
6593         }
6594
6595         if (!test_OpenDomain(p, tctx, handle, *r.out.sid, which_ops,
6596                              machine_credentials)) {
6597                 ret = false;
6598         }
6599
6600         return ret;
6601 }
6602
6603
6604 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
6605                              struct policy_handle *handle, enum torture_samr_choice which_ops,
6606                              struct cli_credentials *machine_credentials)
6607 {
6608         NTSTATUS status;
6609         struct samr_EnumDomains r;
6610         uint32_t resume_handle = 0;
6611         uint32_t num_entries = 0;
6612         struct samr_SamArray *sam = NULL;
6613         int i;
6614         bool ret = true;
6615
6616         r.in.connect_handle = handle;
6617         r.in.resume_handle = &resume_handle;
6618         r.in.buf_size = (uint32_t)-1;
6619         r.out.resume_handle = &resume_handle;
6620         r.out.num_entries = &num_entries;
6621         r.out.sam = &sam;
6622
6623         status = dcerpc_samr_EnumDomains(p, tctx, &r);
6624         torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
6625
6626         if (!*r.out.sam) {
6627                 return false;
6628         }
6629
6630         for (i=0;i<sam->count;i++) {
6631                 if (!test_LookupDomain(p, tctx, handle,
6632                                        sam->entries[i].name.string, which_ops,
6633                                        machine_credentials)) {
6634                         ret = false;
6635                 }
6636         }
6637
6638         status = dcerpc_samr_EnumDomains(p, tctx, &r);
6639         torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
6640
6641         return ret;
6642 }
6643
6644
6645 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
6646                          struct policy_handle *handle)
6647 {
6648         NTSTATUS status;
6649         struct samr_Connect r;
6650         struct samr_Connect2 r2;
6651         struct samr_Connect3 r3;
6652         struct samr_Connect4 r4;
6653         struct samr_Connect5 r5;
6654         union samr_ConnectInfo info;
6655         struct policy_handle h;
6656         uint32_t level_out = 0;
6657         bool ret = true, got_handle = false;
6658
6659         torture_comment(tctx, "testing samr_Connect\n");
6660
6661         r.in.system_name = 0;
6662         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6663         r.out.connect_handle = &h;
6664
6665         status = dcerpc_samr_Connect(p, tctx, &r);
6666         if (!NT_STATUS_IS_OK(status)) {
6667                 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(status));
6668                 ret = false;
6669         } else {
6670                 got_handle = true;
6671                 *handle = h;
6672         }
6673
6674         torture_comment(tctx, "testing samr_Connect2\n");
6675
6676         r2.in.system_name = NULL;
6677         r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6678         r2.out.connect_handle = &h;
6679
6680         status = dcerpc_samr_Connect2(p, tctx, &r2);
6681         if (!NT_STATUS_IS_OK(status)) {
6682                 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(status));
6683                 ret = false;
6684         } else {
6685                 if (got_handle) {
6686                         test_samr_handle_Close(p, tctx, handle);
6687                 }
6688                 got_handle = true;
6689                 *handle = h;
6690         }
6691
6692         torture_comment(tctx, "testing samr_Connect3\n");
6693
6694         r3.in.system_name = NULL;
6695         r3.in.unknown = 0;
6696         r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6697         r3.out.connect_handle = &h;
6698
6699         status = dcerpc_samr_Connect3(p, tctx, &r3);
6700         if (!NT_STATUS_IS_OK(status)) {
6701                 torture_warning(tctx, "Connect3 failed - %s\n", nt_errstr(status));
6702                 ret = false;
6703         } else {
6704                 if (got_handle) {
6705                         test_samr_handle_Close(p, tctx, handle);
6706                 }
6707                 got_handle = true;
6708                 *handle = h;
6709         }
6710
6711         torture_comment(tctx, "testing samr_Connect4\n");
6712
6713         r4.in.system_name = "";
6714         r4.in.client_version = 0;
6715         r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6716         r4.out.connect_handle = &h;
6717
6718         status = dcerpc_samr_Connect4(p, tctx, &r4);
6719         if (!NT_STATUS_IS_OK(status)) {
6720                 torture_warning(tctx, "Connect4 failed - %s\n", nt_errstr(status));
6721                 ret = false;
6722         } else {
6723                 if (got_handle) {
6724                         test_samr_handle_Close(p, tctx, handle);
6725                 }
6726                 got_handle = true;
6727                 *handle = h;
6728         }
6729
6730         torture_comment(tctx, "testing samr_Connect5\n");
6731
6732         info.info1.client_version = 0;
6733         info.info1.unknown2 = 0;
6734
6735         r5.in.system_name = "";
6736         r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6737         r5.in.level_in = 1;
6738         r5.out.level_out = &level_out;
6739         r5.in.info_in = &info;
6740         r5.out.info_out = &info;
6741         r5.out.connect_handle = &h;
6742
6743         status = dcerpc_samr_Connect5(p, tctx, &r5);
6744         if (!NT_STATUS_IS_OK(status)) {
6745                 torture_warning(tctx, "Connect5 failed - %s\n", nt_errstr(status));
6746                 ret = false;
6747         } else {
6748                 if (got_handle) {
6749                         test_samr_handle_Close(p, tctx, handle);
6750                 }
6751                 got_handle = true;
6752                 *handle = h;
6753         }
6754
6755         return ret;
6756 }
6757
6758
6759 static bool test_samr_ValidatePassword(struct dcerpc_pipe *p, struct torture_context *tctx)
6760 {
6761         struct samr_ValidatePassword r;
6762         union samr_ValidatePasswordReq req;
6763         union samr_ValidatePasswordRep *repp = NULL;
6764         NTSTATUS status;
6765         const char *passwords[] = { "penguin", "p@ssw0rd", "p@ssw0rd123$", NULL };
6766         int i;
6767
6768         torture_comment(tctx, "testing samr_ValidatePassword\n");
6769
6770         ZERO_STRUCT(r);
6771         r.in.level = NetValidatePasswordReset;
6772         r.in.req = &req;
6773         r.out.rep = &repp;
6774         
6775         ZERO_STRUCT(req);
6776         req.req3.account.string = "non-existant-account-aklsdji";
6777
6778         for (i=0; passwords[i]; i++) {
6779                 req.req3.password.string = passwords[i];
6780                 status = dcerpc_samr_ValidatePassword(p, tctx, &r);
6781                 torture_assert_ntstatus_ok(tctx, status, "samr_ValidatePassword");
6782                 torture_comment(tctx, "Server %s password '%s'\n", 
6783                                 repp->ctr3.status==SAMR_VALIDATION_STATUS_SUCCESS?"allowed":"refused",
6784                                 req.req3.password.string);
6785         }
6786
6787         return true;    
6788 }
6789
6790 bool torture_rpc_samr(struct torture_context *torture)
6791 {
6792         NTSTATUS status;
6793         struct dcerpc_pipe *p;
6794         bool ret = true;
6795         struct policy_handle handle;
6796
6797         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6798         if (!NT_STATUS_IS_OK(status)) {
6799                 return false;
6800         }
6801
6802         ret &= test_Connect(p, torture, &handle);
6803
6804         if (!torture_setting_bool(torture, "samba3", false)) {
6805                 ret &= test_QuerySecurity(p, torture, &handle);
6806         }
6807
6808         ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER, NULL);
6809
6810         ret &= test_SetDsrmPassword(p, torture, &handle);
6811
6812         ret &= test_Shutdown(p, torture, &handle);
6813
6814         ret &= test_samr_handle_Close(p, torture, &handle);
6815
6816         return ret;
6817 }
6818
6819
6820 bool torture_rpc_samr_users(struct torture_context *torture)
6821 {
6822         NTSTATUS status;
6823         struct dcerpc_pipe *p;
6824         bool ret = true;
6825         struct policy_handle handle;
6826
6827         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6828         if (!NT_STATUS_IS_OK(status)) {
6829                 return false;
6830         }
6831
6832         ret &= test_Connect(p, torture, &handle);
6833
6834         if (!torture_setting_bool(torture, "samba3", false)) {
6835                 ret &= test_QuerySecurity(p, torture, &handle);
6836         }
6837
6838         ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES, NULL);
6839
6840         ret &= test_SetDsrmPassword(p, torture, &handle);
6841
6842         ret &= test_Shutdown(p, torture, &handle);
6843
6844         ret &= test_samr_handle_Close(p, torture, &handle);
6845
6846         return ret;
6847 }
6848
6849
6850 bool torture_rpc_samr_passwords(struct torture_context *torture)
6851 {
6852         NTSTATUS status;
6853         struct dcerpc_pipe *p;
6854         bool ret = true;
6855         struct policy_handle handle;
6856
6857         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6858         if (!NT_STATUS_IS_OK(status)) {
6859                 return false;
6860         }
6861
6862         ret &= test_Connect(p, torture, &handle);
6863
6864         ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS, NULL);
6865
6866         ret &= test_samr_handle_Close(p, torture, &handle);
6867
6868         ret &= test_samr_ValidatePassword(p, torture);
6869
6870         return ret;
6871 }
6872
6873 static bool torture_rpc_samr_pwdlastset(struct torture_context *torture,
6874                                         struct dcerpc_pipe *p2,
6875                                         struct cli_credentials *machine_credentials)
6876 {
6877         NTSTATUS status;
6878         struct dcerpc_pipe *p;
6879         bool ret = true;
6880         struct policy_handle handle;
6881
6882         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6883         if (!NT_STATUS_IS_OK(status)) {
6884                 return false;
6885         }
6886
6887         ret &= test_Connect(p, torture, &handle);
6888
6889         ret &= test_EnumDomains(p, torture, &handle,
6890                                 TORTURE_SAMR_PASSWORDS_PWDLASTSET,
6891                                 machine_credentials);
6892
6893         ret &= test_samr_handle_Close(p, torture, &handle);
6894
6895         return ret;
6896 }
6897
6898 struct torture_suite *torture_rpc_samr_passwords_pwdlastset(TALLOC_CTX *mem_ctx)
6899 {
6900         struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-PASSWORDS-PWDLASTSET");
6901         struct torture_rpc_tcase *tcase;
6902
6903         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
6904                                                           &ndr_table_samr,
6905                                                           TEST_ACCOUNT_NAME_PWD);
6906
6907         torture_rpc_tcase_add_test_creds(tcase, "pwdLastSet",
6908                                          torture_rpc_samr_pwdlastset);
6909
6910         return suite;
6911 }
6912
6913 static bool torture_rpc_samr_users_privileges_delete_user(struct torture_context *torture,
6914                                                           struct dcerpc_pipe *p2,
6915                                                           struct cli_credentials *machine_credentials)
6916 {
6917         NTSTATUS status;
6918         struct dcerpc_pipe *p;
6919         bool ret = true;
6920         struct policy_handle handle;
6921
6922         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6923         if (!NT_STATUS_IS_OK(status)) {
6924                 return false;
6925         }
6926
6927         ret &= test_Connect(p, torture, &handle);
6928
6929         ret &= test_EnumDomains(p, torture, &handle,
6930                                 TORTURE_SAMR_USER_PRIVILEGES,
6931                                 machine_credentials);
6932
6933         ret &= test_samr_handle_Close(p, torture, &handle);
6934
6935         return ret;
6936 }
6937
6938 struct torture_suite *torture_rpc_samr_user_privileges(TALLOC_CTX *mem_ctx)
6939 {
6940         struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-USERS-PRIVILEGES");
6941         struct torture_rpc_tcase *tcase;
6942
6943         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
6944                                                           &ndr_table_samr,
6945                                                           TEST_ACCOUNT_NAME_PWD);
6946
6947         torture_rpc_tcase_add_test_creds(tcase, "delete_privileged_user",
6948                                          torture_rpc_samr_users_privileges_delete_user);
6949
6950         return suite;
6951 }
6952
6953 static bool torture_rpc_samr_many_accounts(struct torture_context *torture,
6954                                            struct dcerpc_pipe *p2,
6955                                            struct cli_credentials *machine_credentials)
6956 {
6957         NTSTATUS status;
6958         struct dcerpc_pipe *p;
6959         bool ret = true;
6960         struct policy_handle handle;
6961
6962         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6963         if (!NT_STATUS_IS_OK(status)) {
6964                 return false;
6965         }
6966
6967         ret &= test_Connect(p, torture, &handle);
6968
6969         ret &= test_EnumDomains(p, torture, &handle,
6970                                 TORTURE_SAMR_MANY_ACCOUNTS,
6971                                 machine_credentials);
6972
6973         ret &= test_samr_handle_Close(p, torture, &handle);
6974
6975         return ret;
6976 }
6977
6978 static bool torture_rpc_samr_many_groups(struct torture_context *torture,
6979                                          struct dcerpc_pipe *p2,
6980                                          struct cli_credentials *machine_credentials)
6981 {
6982         NTSTATUS status;
6983         struct dcerpc_pipe *p;
6984         bool ret = true;
6985         struct policy_handle handle;
6986
6987         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6988         if (!NT_STATUS_IS_OK(status)) {
6989                 return false;
6990         }
6991
6992         ret &= test_Connect(p, torture, &handle);
6993
6994         ret &= test_EnumDomains(p, torture, &handle,
6995                                 TORTURE_SAMR_MANY_GROUPS,
6996                                 machine_credentials);
6997
6998         ret &= test_samr_handle_Close(p, torture, &handle);
6999
7000         return ret;
7001 }
7002
7003 static bool torture_rpc_samr_many_aliases(struct torture_context *torture,
7004                                           struct dcerpc_pipe *p2,
7005                                           struct cli_credentials *machine_credentials)
7006 {
7007         NTSTATUS status;
7008         struct dcerpc_pipe *p;
7009         bool ret = true;
7010         struct policy_handle handle;
7011
7012         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
7013         if (!NT_STATUS_IS_OK(status)) {
7014                 return false;
7015         }
7016
7017         ret &= test_Connect(p, torture, &handle);
7018
7019         ret &= test_EnumDomains(p, torture, &handle,
7020                                 TORTURE_SAMR_MANY_ALIASES,
7021                                 machine_credentials);
7022
7023         ret &= test_samr_handle_Close(p, torture, &handle);
7024
7025         return ret;
7026 }
7027
7028 struct torture_suite *torture_rpc_samr_large_dc(TALLOC_CTX *mem_ctx)
7029 {
7030         struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-LARGE-DC");
7031         struct torture_rpc_tcase *tcase;
7032
7033         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
7034                                                           &ndr_table_samr,
7035                                                           TEST_ACCOUNT_NAME);
7036
7037         torture_rpc_tcase_add_test_creds(tcase, "many_aliases",
7038                                          torture_rpc_samr_many_aliases);
7039         torture_rpc_tcase_add_test_creds(tcase, "many_groups",
7040                                          torture_rpc_samr_many_groups);
7041         torture_rpc_tcase_add_test_creds(tcase, "many_accounts",
7042                                          torture_rpc_samr_many_accounts);
7043
7044         return suite;
7045 }
7046