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