s4-smbtorture: refactor RPC-SAMR-LARGE-DC test a little more.
[kai/samba.git] / source4 / torture / rpc / samr.c
1 /*
2    Unix SMB/CIFS implementation.
3    test suite for samr rpc operations
4
5    Copyright (C) Andrew Tridgell 2003
6    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
7    Copyright (C) Guenther Deschner 2008,2009
8
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.
21 */
22
23 #include "includes.h"
24 #include "torture/torture.h"
25 #include "system/time.h"
26 #include "librpc/gen_ndr/lsa.h"
27 #include "librpc/gen_ndr/ndr_netlogon.h"
28 #include "librpc/gen_ndr/ndr_netlogon_c.h"
29 #include "librpc/gen_ndr/ndr_samr_c.h"
30 #include "librpc/gen_ndr/ndr_lsa_c.h"
31 #include "../lib/crypto/crypto.h"
32 #include "libcli/auth/libcli_auth.h"
33 #include "libcli/security/security.h"
34 #include "torture/rpc/rpc.h"
35 #include "param/param.h"
36
37 #include <unistd.h>
38
39 #define TEST_ACCOUNT_NAME "samrtorturetest"
40 #define TEST_ACCOUNT_NAME_PWD "samrpwdlastset"
41 #define TEST_ALIASNAME "samrtorturetestalias"
42 #define TEST_GROUPNAME "samrtorturetestgroup"
43 #define TEST_MACHINENAME "samrtestmach$"
44 #define TEST_DOMAINNAME "samrtestdom$"
45
46 enum torture_samr_choice {
47         TORTURE_SAMR_PASSWORDS,
48         TORTURE_SAMR_PASSWORDS_PWDLASTSET,
49         TORTURE_SAMR_USER_ATTRIBUTES,
50         TORTURE_SAMR_USER_PRIVILEGES,
51         TORTURE_SAMR_OTHER,
52         TORTURE_SAMR_MANY_ACCOUNTS,
53         TORTURE_SAMR_MANY_GROUPS,
54         TORTURE_SAMR_MANY_ALIASES
55 };
56
57 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_TestPrivateFunctionsUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2597                                             struct policy_handle *user_handle)
2598 {
2599         struct samr_TestPrivateFunctionsUser r;
2600         NTSTATUS status;
2601
2602         torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2603
2604         r.in.user_handle = user_handle;
2605
2606         status = dcerpc_samr_TestPrivateFunctionsUser(p, tctx, &r);
2607         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2608
2609         return true;
2610 }
2611
2612 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_pipe *p,
2613                                           struct torture_context *tctx,
2614                                           struct policy_handle *handle,
2615                                           bool use_info2,
2616                                           NTTIME *pwdlastset)
2617 {
2618         NTSTATUS status;
2619         uint16_t levels[] = { /* 3, */ 5, 21 };
2620         int i;
2621         NTTIME pwdlastset3 = 0;
2622         NTTIME pwdlastset5 = 0;
2623         NTTIME pwdlastset21 = 0;
2624
2625         torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
2626                         use_info2 ? "2":"");
2627
2628         for (i=0; i<ARRAY_SIZE(levels); i++) {
2629
2630                 struct samr_QueryUserInfo r;
2631                 struct samr_QueryUserInfo2 r2;
2632                 union samr_UserInfo *info;
2633
2634                 if (use_info2) {
2635                         r2.in.user_handle = handle;
2636                         r2.in.level = levels[i];
2637                         r2.out.info = &info;
2638                         status = dcerpc_samr_QueryUserInfo2(p, tctx, &r2);
2639
2640                 } else {
2641                         r.in.user_handle = handle;
2642                         r.in.level = levels[i];
2643                         r.out.info = &info;
2644                         status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
2645                 }
2646
2647                 if (!NT_STATUS_IS_OK(status) &&
2648                     !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2649                         torture_warning(tctx, "QueryUserInfo%s level %u failed - %s\n",
2650                                use_info2 ? "2":"", levels[i], nt_errstr(status));
2651                         return false;
2652                 }
2653
2654                 switch (levels[i]) {
2655                 case 3:
2656                         pwdlastset3 = info->info3.last_password_change;
2657                         break;
2658                 case 5:
2659                         pwdlastset5 = info->info5.last_password_change;
2660                         break;
2661                 case 21:
2662                         pwdlastset21 = info->info21.last_password_change;
2663                         break;
2664                 default:
2665                         return false;
2666                 }
2667         }
2668         /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2669                                     "pwdlastset mixup"); */
2670         torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
2671                                  "pwdlastset mixup");
2672
2673         *pwdlastset = pwdlastset21;
2674
2675         torture_comment(tctx, "(pwdlastset: %lld)\n", *pwdlastset);
2676
2677         return true;
2678 }
2679
2680 static bool test_SamLogon(struct torture_context *tctx,
2681                           struct dcerpc_pipe *p,
2682                           struct cli_credentials *test_credentials,
2683                           NTSTATUS expected_result)
2684 {
2685         NTSTATUS status;
2686         struct netr_LogonSamLogonEx r;
2687         union netr_LogonLevel logon;
2688         union netr_Validation validation;
2689         uint8_t authoritative;
2690         struct netr_NetworkInfo ninfo;
2691         DATA_BLOB names_blob, chal, lm_resp, nt_resp;
2692         int flags = CLI_CRED_NTLM_AUTH;
2693         uint32_t samlogon_flags = 0;
2694
2695         if (lp_client_lanman_auth(tctx->lp_ctx)) {
2696                 flags |= CLI_CRED_LANMAN_AUTH;
2697         }
2698
2699         if (lp_client_ntlmv2_auth(tctx->lp_ctx)) {
2700                 flags |= CLI_CRED_NTLMv2_AUTH;
2701         }
2702
2703         cli_credentials_get_ntlm_username_domain(test_credentials, tctx,
2704                                                  &ninfo.identity_info.account_name.string,
2705                                                  &ninfo.identity_info.domain_name.string);
2706
2707         generate_random_buffer(ninfo.challenge,
2708                                sizeof(ninfo.challenge));
2709         chal = data_blob_const(ninfo.challenge,
2710                                sizeof(ninfo.challenge));
2711
2712         names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(test_credentials),
2713                                                 cli_credentials_get_domain(test_credentials));
2714
2715         status = cli_credentials_get_ntlm_response(test_credentials, tctx,
2716                                                    &flags,
2717                                                    chal,
2718                                                    names_blob,
2719                                                    &lm_resp, &nt_resp,
2720                                                    NULL, NULL);
2721         torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
2722
2723         ninfo.lm.data = lm_resp.data;
2724         ninfo.lm.length = lm_resp.length;
2725
2726         ninfo.nt.data = nt_resp.data;
2727         ninfo.nt.length = nt_resp.length;
2728
2729         ninfo.identity_info.parameter_control =
2730                 MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT |
2731                 MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
2732         ninfo.identity_info.logon_id_low = 0;
2733         ninfo.identity_info.logon_id_high = 0;
2734         ninfo.identity_info.workstation.string = cli_credentials_get_workstation(test_credentials);
2735
2736         logon.network = &ninfo;
2737
2738         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2739         r.in.computer_name = cli_credentials_get_workstation(test_credentials);
2740         r.in.logon_level = NetlogonNetworkInformation;
2741         r.in.logon = &logon;
2742         r.in.flags = &samlogon_flags;
2743         r.out.flags = &samlogon_flags;
2744         r.out.validation = &validation;
2745         r.out.authoritative = &authoritative;
2746
2747         torture_comment(tctx, "Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
2748
2749         r.in.validation_level = 6;
2750
2751         status = dcerpc_netr_LogonSamLogonEx(p, tctx, &r);
2752         if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2753                 r.in.validation_level = 3;
2754                 status = dcerpc_netr_LogonSamLogonEx(p, tctx, &r);
2755         }
2756         if (!NT_STATUS_IS_OK(status)) {
2757                 torture_assert_ntstatus_equal(tctx, status, expected_result, "LogonSamLogonEx failed");
2758                 return true;
2759         } else {
2760                 torture_assert_ntstatus_ok(tctx, status, "LogonSamLogonEx failed");
2761         }
2762
2763         return true;
2764 }
2765
2766 static bool test_SamLogon_with_creds(struct torture_context *tctx,
2767                                      struct dcerpc_pipe *p,
2768                                      struct cli_credentials *machine_creds,
2769                                      const char *acct_name,
2770                                      char *password,
2771                                      NTSTATUS expected_samlogon_result)
2772 {
2773         bool ret = true;
2774         struct cli_credentials *test_credentials;
2775
2776         test_credentials = cli_credentials_init(tctx);
2777
2778         cli_credentials_set_workstation(test_credentials,
2779                                         cli_credentials_get_workstation(machine_creds), CRED_SPECIFIED);
2780         cli_credentials_set_domain(test_credentials,
2781                                    cli_credentials_get_domain(machine_creds), CRED_SPECIFIED);
2782         cli_credentials_set_username(test_credentials,
2783                                      acct_name, CRED_SPECIFIED);
2784         cli_credentials_set_password(test_credentials,
2785                                      password, CRED_SPECIFIED);
2786
2787         torture_comment(tctx, "testing samlogon as %s password: %s\n",
2788                 acct_name, password);
2789
2790         if (!test_SamLogon(tctx, p, test_credentials,
2791                            expected_samlogon_result)) {
2792                 torture_warning(tctx, "new password did not work\n");
2793                 ret = false;
2794         }
2795
2796         return ret;
2797 }
2798
2799 static bool test_SetPassword_level(struct dcerpc_pipe *p,
2800                                    struct dcerpc_pipe *np,
2801                                    struct torture_context *tctx,
2802                                    struct policy_handle *handle,
2803                                    uint16_t level,
2804                                    uint32_t fields_present,
2805                                    uint8_t password_expired,
2806                                    bool *matched_expected_error,
2807                                    bool use_setinfo2,
2808                                    const char *acct_name,
2809                                    char **password,
2810                                    struct cli_credentials *machine_creds,
2811                                    bool use_queryinfo2,
2812                                    NTTIME *pwdlastset,
2813                                    NTSTATUS expected_samlogon_result)
2814 {
2815         const char *fields = NULL;
2816         bool ret = true;
2817
2818         switch (level) {
2819         case 21:
2820         case 23:
2821         case 25:
2822                 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
2823                                          fields_present);
2824                 break;
2825         default:
2826                 break;
2827         }
2828
2829         torture_comment(tctx, "Testing SetUserInfo%s level %d call "
2830                 "(password_expired: %d) %s\n",
2831                 use_setinfo2 ? "2":"", level, password_expired,
2832                 fields ? fields : "");
2833
2834         if (!test_SetUserPass_level_ex(p, tctx, handle, level,
2835                                        fields_present,
2836                                        password,
2837                                        password_expired,
2838                                        use_setinfo2,
2839                                        matched_expected_error)) {
2840                 ret = false;
2841         }
2842
2843         if (!test_QueryUserInfo_pwdlastset(p, tctx, handle,
2844                                            use_queryinfo2,
2845                                            pwdlastset)) {
2846                 ret = false;
2847         }
2848
2849         if (*matched_expected_error == true) {
2850                 return ret;
2851         }
2852
2853         if (!test_SamLogon_with_creds(tctx, np,
2854                                       machine_creds,
2855                                       acct_name,
2856                                       *password,
2857                                       expected_samlogon_result)) {
2858                 ret = false;
2859         }
2860
2861         return ret;
2862 }
2863
2864 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
2865                                         struct torture_context *tctx,
2866                                         uint32_t acct_flags,
2867                                         const char *acct_name,
2868                                         struct policy_handle *handle,
2869                                         char **password,
2870                                         struct cli_credentials *machine_credentials)
2871 {
2872         int s = 0, q = 0, f = 0, l = 0, z = 0;
2873         struct dcerpc_binding *b;
2874         bool ret = true;
2875         int delay = 50000;
2876         bool set_levels[] = { false, true };
2877         bool query_levels[] = { false, true };
2878         uint32_t levels[] = { 18, 21, 26, 23, 24, 25 }; /* Second half only used when TEST_ALL_LEVELS defined */
2879         uint32_t nonzeros[] = { 1, 24 };
2880         uint32_t fields_present[] = {
2881                 0,
2882                 SAMR_FIELD_EXPIRED_FLAG,
2883                 SAMR_FIELD_LAST_PWD_CHANGE,
2884                 SAMR_FIELD_EXPIRED_FLAG | SAMR_FIELD_LAST_PWD_CHANGE,
2885                 SAMR_FIELD_COMMENT,
2886                 SAMR_FIELD_NT_PASSWORD_PRESENT,
2887                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2888                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
2889                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2890                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2891                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2892                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE | SAMR_FIELD_EXPIRED_FLAG
2893         };
2894         NTSTATUS status;
2895         struct dcerpc_pipe *np = NULL;
2896
2897         if (torture_setting_bool(tctx, "samba3", false)) {
2898                 delay = 999999;
2899                 torture_comment(tctx, "Samba3 has second granularity, setting delay to: %d\n",
2900                         delay);
2901         }
2902
2903         status = torture_rpc_binding(tctx, &b);
2904         if (!NT_STATUS_IS_OK(status)) {
2905                 ret = false;
2906                 return ret;
2907         }
2908
2909         /* We have to use schannel, otherwise the SamLogonEx fails
2910          * with INTERNAL_ERROR */
2911
2912         b->flags &= ~DCERPC_AUTH_OPTIONS;
2913         b->flags |= DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_128;
2914
2915         status = dcerpc_pipe_connect_b(tctx, &np, b,
2916                                        &ndr_table_netlogon,
2917                                        machine_credentials, tctx->ev, tctx->lp_ctx);
2918
2919         if (!NT_STATUS_IS_OK(status)) {
2920                 torture_warning(tctx, "RPC pipe connect as domain member failed: %s\n", nt_errstr(status));
2921                 ret = false;
2922                 return ret;
2923         }
2924
2925         /* set to 1 to enable testing for all possible opcode
2926            (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
2927            combinations */
2928 #if 0
2929 #define TEST_ALL_LEVELS 1
2930 #define TEST_SET_LEVELS 1
2931 #define TEST_QUERY_LEVELS 1
2932 #endif
2933 #ifdef TEST_ALL_LEVELS
2934         for (l=0; l<ARRAY_SIZE(levels); l++) {
2935 #else
2936         for (l=0; l<(ARRAY_SIZE(levels))/2; l++) {
2937 #endif
2938         for (z=0; z<ARRAY_SIZE(nonzeros); z++) {
2939         for (f=0; f<ARRAY_SIZE(fields_present); f++) {
2940 #ifdef TEST_SET_LEVELS
2941         for (s=0; s<ARRAY_SIZE(set_levels); s++) {
2942 #endif
2943 #ifdef TEST_QUERY_LEVELS
2944         for (q=0; q<ARRAY_SIZE(query_levels); q++) {
2945 #endif
2946                 NTTIME pwdlastset_old = 0;
2947                 NTTIME pwdlastset_new = 0;
2948                 bool matched_expected_error = false;
2949                 NTSTATUS expected_samlogon_result = NT_STATUS_ACCOUNT_DISABLED;
2950
2951                 torture_comment(tctx, "------------------------------\n"
2952                                 "Testing pwdLastSet attribute for flags: 0x%08x "
2953                                 "(s: %d (l: %d), q: %d)\n",
2954                                 acct_flags, s, levels[l], q);
2955
2956                 switch (levels[l]) {
2957                 case 21:
2958                 case 23:
2959                 case 25:
2960                         if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2961                               (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT))) {
2962                                 expected_samlogon_result = NT_STATUS_WRONG_PASSWORD;
2963                         }
2964                         break;
2965                 }
2966
2967
2968                 /* set #1 */
2969
2970                 /* set a password and force password change (pwdlastset 0) by
2971                  * setting the password expired flag to a non-0 value */
2972
2973                 if (!test_SetPassword_level(p, np, tctx, handle,
2974                                             levels[l],
2975                                             fields_present[f],
2976                                             nonzeros[z],
2977                                             &matched_expected_error,
2978                                             set_levels[s],
2979                                             acct_name,
2980                                             password,
2981                                             machine_credentials,
2982                                             query_levels[q],
2983                                             &pwdlastset_old,
2984                                             expected_samlogon_result)) {
2985                         ret = false;
2986                 }
2987
2988                 if (matched_expected_error == true) {
2989                         /* skipping on expected failure */
2990                         continue;
2991                 }
2992
2993                 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
2994                  * set without the SAMR_FIELD_EXPIRED_FLAG */
2995
2996                 switch (levels[l]) {
2997                 case 21:
2998                 case 23:
2999                 case 25:
3000                         if ((pwdlastset_new != 0) &&
3001                             !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3002                                 torture_comment(tctx, "not considering a non-0 "
3003                                         "pwdLastSet as a an error as the "
3004                                         "SAMR_FIELD_EXPIRED_FLAG has not "
3005                                         "been set\n");
3006                                 break;
3007                         }
3008                 default:
3009                         if (pwdlastset_new != 0) {
3010                                 torture_warning(tctx, "pwdLastSet test failed: "
3011                                         "expected pwdLastSet 0 but got %lld\n",
3012                                         pwdlastset_old);
3013                                 ret = false;
3014                         }
3015                         break;
3016                 }
3017
3018                 switch (levels[l]) {
3019                 case 21:
3020                 case 23:
3021                 case 25:
3022                         if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3023                              (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3024                              (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3025                              (pwdlastset_old >= pwdlastset_new)) {
3026                                 torture_warning(tctx, "pwdlastset not increasing\n");
3027                                 ret = false;
3028                         }
3029                         break;
3030                 default:
3031                         if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3032                             (pwdlastset_old >= pwdlastset_new)) {
3033                                 torture_warning(tctx, "pwdlastset not increasing\n");
3034                                 ret = false;
3035                         }
3036                         break;
3037                 }
3038
3039                 usleep(delay);
3040
3041                 /* set #2 */
3042
3043                 /* set a password, pwdlastset needs to get updated (increased
3044                  * value), password_expired value used here is 0 */
3045
3046                 if (!test_SetPassword_level(p, np, tctx, handle,
3047                                             levels[l],
3048                                             fields_present[f],
3049                                             0,
3050                                             &matched_expected_error,
3051                                             set_levels[s],
3052                                             acct_name,
3053                                             password,
3054                                             machine_credentials,
3055                                             query_levels[q],
3056                                             &pwdlastset_new,
3057                                             expected_samlogon_result)) {
3058                         ret = false;
3059                 }
3060
3061                 /* when a password has been changed, pwdlastset must not be 0 afterwards
3062                  * and must be larger then the old value */
3063
3064                 switch (levels[l]) {
3065                 case 21:
3066                 case 23:
3067                 case 25:
3068
3069                         /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3070                          * password has been changed, old and new pwdlastset
3071                          * need to be the same value */
3072
3073                         if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3074                             !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3075                               (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3076                         {
3077                                 torture_assert_int_equal(tctx, pwdlastset_old,
3078                                         pwdlastset_new, "pwdlastset must be equal");
3079                                 break;
3080                         }
3081                 default:
3082                         if (pwdlastset_old >= pwdlastset_new) {
3083                                 torture_warning(tctx, "pwdLastSet test failed: "
3084                                         "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3085                                         pwdlastset_old, pwdlastset_new);
3086                                 ret = false;
3087                         }
3088                         if (pwdlastset_new == 0) {
3089                                 torture_warning(tctx, "pwdLastSet test failed: "
3090                                         "expected non-0 pwdlastset, got: %lld\n",
3091                                         pwdlastset_new);
3092                                 ret = false;
3093                         }
3094                 }
3095
3096                 switch (levels[l]) {
3097                 case 21:
3098                 case 23:
3099                 case 25:
3100                         if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3101                              (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3102                              (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3103                              (pwdlastset_old >= pwdlastset_new)) {
3104                                 torture_warning(tctx, "pwdlastset not increasing\n");
3105                                 ret = false;
3106                         }
3107                         break;
3108                 default:
3109                         if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3110                             (pwdlastset_old >= pwdlastset_new)) {
3111                                 torture_warning(tctx, "pwdlastset not increasing\n");
3112                                 ret = false;
3113                         }
3114                         break;
3115                 }
3116
3117                 pwdlastset_old = pwdlastset_new;
3118
3119                 usleep(delay);
3120
3121                 /* set #2b */
3122
3123                 /* set a password, pwdlastset needs to get updated (increased
3124                  * value), password_expired value used here is 0 */
3125
3126                 if (!test_SetPassword_level(p, np, tctx, handle,
3127                                             levels[l],
3128                                             fields_present[f],
3129                                             0,
3130                                             &matched_expected_error,
3131                                             set_levels[s],
3132                                             acct_name,
3133                                             password,
3134                                             machine_credentials,
3135                                             query_levels[q],
3136                                             &pwdlastset_new,
3137                                             expected_samlogon_result)) {
3138                         ret = false;
3139                 }
3140
3141                 /* when a password has been changed, pwdlastset must not be 0 afterwards
3142                  * and must be larger then the old value */
3143
3144                 switch (levels[l]) {
3145                 case 21:
3146                 case 23:
3147                 case 25:
3148
3149                         /* if no password has been changed, old and new pwdlastset
3150                          * need to be the same value */
3151
3152                         if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3153                               (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3154                         {
3155                                 torture_assert_int_equal(tctx, pwdlastset_old,
3156                                         pwdlastset_new, "pwdlastset must be equal");
3157                                 break;
3158                         }
3159                 default:
3160                         if (pwdlastset_old >= pwdlastset_new) {
3161                                 torture_warning(tctx, "pwdLastSet test failed: "
3162                                         "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3163                                         pwdlastset_old, pwdlastset_new);
3164                                 ret = false;
3165                         }
3166                         if (pwdlastset_new == 0) {
3167                                 torture_warning(tctx, "pwdLastSet test failed: "
3168                                         "expected non-0 pwdlastset, got: %lld\n",
3169                                         pwdlastset_new);
3170                                 ret = false;
3171                         }
3172                 }
3173
3174                 /* set #3 */
3175
3176                 /* set a password and force password change (pwdlastset 0) by
3177                  * setting the password expired flag to a non-0 value */
3178
3179                 if (!test_SetPassword_level(p, np, tctx, handle,
3180                                             levels[l],
3181                                             fields_present[f],
3182                                             nonzeros[z],
3183                                             &matched_expected_error,
3184                                             set_levels[s],
3185                                             acct_name,
3186                                             password,
3187                                             machine_credentials,
3188                                             query_levels[q],
3189                                             &pwdlastset_new,
3190                                             expected_samlogon_result)) {
3191                         ret = false;
3192                 }
3193
3194                 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3195                  * set without the SAMR_FIELD_EXPIRED_FLAG */
3196
3197                 switch (levels[l]) {
3198                 case 21:
3199                 case 23:
3200                 case 25:
3201                         if ((pwdlastset_new != 0) &&
3202                             !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3203                                 torture_comment(tctx, "not considering a non-0 "
3204                                         "pwdLastSet as a an error as the "
3205                                         "SAMR_FIELD_EXPIRED_FLAG has not "
3206                                         "been set\n");
3207                                 break;
3208                         }
3209
3210                         /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3211                          * password has been changed, old and new pwdlastset
3212                          * need to be the same value */
3213
3214                         if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3215                             !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3216                               (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3217                         {
3218                                 torture_assert_int_equal(tctx, pwdlastset_old,
3219                                         pwdlastset_new, "pwdlastset must be equal");
3220                                 break;
3221                         }
3222                 default:
3223
3224                         if (pwdlastset_old == pwdlastset_new) {
3225                                 torture_warning(tctx, "pwdLastSet test failed: "
3226                                         "expected last pwdlastset (%lld) != new pwdlastset (%lld)\n",
3227                                         pwdlastset_old, pwdlastset_new);
3228                                 ret = false;
3229                         }
3230
3231                         if (pwdlastset_new != 0) {
3232                                 torture_warning(tctx, "pwdLastSet test failed: "
3233                                         "expected pwdLastSet 0, got %lld\n",
3234                                         pwdlastset_old);
3235                                 ret = false;
3236                         }
3237                         break;
3238                 }
3239
3240                 switch (levels[l]) {
3241                 case 21:
3242                 case 23:
3243                 case 25:
3244                         if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3245                              (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3246                              (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3247                              (pwdlastset_old >= pwdlastset_new)) {
3248                                 torture_warning(tctx, "pwdlastset not increasing\n");
3249                                 ret = false;
3250                         }
3251                         break;
3252                 default:
3253                         if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3254                             (pwdlastset_old >= pwdlastset_new)) {
3255                                 torture_warning(tctx, "pwdlastset not increasing\n");
3256                                 ret = false;
3257                         }
3258                         break;
3259                 }
3260
3261                 /* if the level we are testing does not have a fields_present
3262                  * field, skip all fields present tests by setting f to to
3263                  * arraysize */
3264                 switch (levels[l]) {
3265                 case 18:
3266                 case 24:
3267                 case 26:
3268                         f = ARRAY_SIZE(fields_present);
3269                         break;
3270                 }
3271
3272 #ifdef TEST_QUERY_LEVELS
3273         }
3274 #endif
3275 #ifdef TEST_SET_LEVELS
3276         }
3277 #endif
3278         } /* fields present */
3279         } /* nonzeros */
3280         } /* levels */
3281
3282 #undef TEST_SET_LEVELS
3283 #undef TEST_QUERY_LEVELS
3284
3285         talloc_free(np);
3286
3287         return ret;
3288 }
3289
3290 static bool test_DeleteUser_with_privs(struct dcerpc_pipe *p,
3291                                        struct dcerpc_pipe *lp,
3292                                        struct torture_context *tctx,
3293                                        struct policy_handle *domain_handle,
3294                                        struct policy_handle *lsa_handle,
3295                                        struct policy_handle *user_handle,
3296                                        const struct dom_sid *domain_sid,
3297                                        uint32_t rid,
3298                                        struct cli_credentials *machine_credentials)
3299 {
3300         NTSTATUS status;
3301         bool ret = true;
3302
3303         struct policy_handle lsa_acct_handle;
3304         struct dom_sid *user_sid;
3305
3306         user_sid = dom_sid_add_rid(tctx, domain_sid, rid);
3307
3308         {
3309                 struct lsa_EnumAccountRights r;
3310                 struct lsa_RightSet rights;
3311
3312                 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
3313
3314                 r.in.handle = lsa_handle;
3315                 r.in.sid = user_sid;
3316                 r.out.rights = &rights;
3317
3318                 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3319                 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3320                         "Expected enum rights for account to fail");
3321         }
3322
3323         {
3324                 struct lsa_RightSet rights;
3325                 struct lsa_StringLarge names[2];
3326                 struct lsa_AddAccountRights r;
3327
3328                 torture_comment(tctx, "Testing LSA AddAccountRights\n");
3329
3330                 init_lsa_StringLarge(&names[0], "SeMachineAccountPrivilege");
3331                 init_lsa_StringLarge(&names[1], NULL);
3332
3333                 rights.count = 1;
3334                 rights.names = names;
3335
3336                 r.in.handle = lsa_handle;
3337                 r.in.sid = user_sid;
3338                 r.in.rights = &rights;
3339
3340                 status = dcerpc_lsa_AddAccountRights(lp, tctx, &r);
3341                 torture_assert_ntstatus_ok(tctx, status,
3342                         "Failed to add privileges");
3343         }
3344
3345         {
3346                 struct lsa_EnumAccounts r;
3347                 uint32_t resume_handle = 0;
3348                 struct lsa_SidArray lsa_sid_array;
3349                 int i;
3350                 bool found_sid = false;
3351
3352                 torture_comment(tctx, "Testing LSA EnumAccounts\n");
3353
3354                 r.in.handle = lsa_handle;
3355                 r.in.num_entries = 0x1000;
3356                 r.in.resume_handle = &resume_handle;
3357                 r.out.sids = &lsa_sid_array;
3358                 r.out.resume_handle = &resume_handle;
3359
3360                 status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
3361                 torture_assert_ntstatus_ok(tctx, status,
3362                         "Failed to enum accounts");
3363
3364                 for (i=0; i < lsa_sid_array.num_sids; i++) {
3365                         if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
3366                                 found_sid = true;
3367                         }
3368                 }
3369
3370                 torture_assert(tctx, found_sid,
3371                         "failed to list privileged account");
3372         }
3373
3374         {
3375                 struct lsa_EnumAccountRights r;
3376                 struct lsa_RightSet user_rights;
3377
3378                 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
3379
3380                 r.in.handle = lsa_handle;
3381                 r.in.sid = user_sid;
3382                 r.out.rights = &user_rights;
3383
3384                 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3385                 torture_assert_ntstatus_ok(tctx, status,
3386                         "Failed to enum rights for account");
3387
3388                 if (user_rights.count < 1) {
3389                         torture_warning(tctx, "failed to find newly added rights");
3390                         return false;
3391                 }
3392         }
3393
3394         {
3395                 struct lsa_OpenAccount r;
3396
3397                 torture_comment(tctx, "Testing LSA OpenAccount\n");
3398
3399                 r.in.handle = lsa_handle;
3400                 r.in.sid = user_sid;
3401                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3402                 r.out.acct_handle = &lsa_acct_handle;
3403
3404                 status = dcerpc_lsa_OpenAccount(lp, tctx, &r);
3405                 torture_assert_ntstatus_ok(tctx, status,
3406                         "Failed to open lsa account");
3407         }
3408
3409         {
3410                 struct lsa_GetSystemAccessAccount r;
3411                 uint32_t access_mask;
3412
3413                 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
3414
3415                 r.in.handle = &lsa_acct_handle;
3416                 r.out.access_mask = &access_mask;
3417
3418                 status = dcerpc_lsa_GetSystemAccessAccount(lp, tctx, &r);
3419                 torture_assert_ntstatus_ok(tctx, status,
3420                         "Failed to get lsa system access account");
3421         }
3422
3423         {
3424                 struct lsa_Close r;
3425
3426                 torture_comment(tctx, "Testing LSA Close\n");
3427
3428                 r.in.handle = &lsa_acct_handle;
3429                 r.out.handle = &lsa_acct_handle;
3430
3431                 status = dcerpc_lsa_Close(lp, tctx, &r);
3432                 torture_assert_ntstatus_ok(tctx, status,
3433                         "Failed to close lsa");
3434         }
3435
3436         {
3437                 struct samr_DeleteUser r;
3438
3439                 torture_comment(tctx, "Testing SAMR DeleteUser\n");
3440
3441                 r.in.user_handle = user_handle;
3442                 r.out.user_handle = user_handle;
3443
3444                 status = dcerpc_samr_DeleteUser(p, tctx, &r);
3445                 torture_assert_ntstatus_ok(tctx, status, "Delete User failed");
3446         }
3447
3448         {
3449                 struct lsa_EnumAccounts r;
3450                 uint32_t resume_handle = 0;
3451                 struct lsa_SidArray lsa_sid_array;
3452                 int i;
3453                 bool found_sid = false;
3454
3455                 torture_comment(tctx, "Testing LSA EnumAccounts\n");
3456
3457                 r.in.handle = lsa_handle;
3458                 r.in.num_entries = 0x1000;
3459                 r.in.resume_handle = &resume_handle;
3460                 r.out.sids = &lsa_sid_array;
3461                 r.out.resume_handle = &resume_handle;
3462
3463                 status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
3464                 torture_assert_ntstatus_ok(tctx, status,
3465                         "Failed to enum accounts");
3466
3467                 for (i=0; i < lsa_sid_array.num_sids; i++) {
3468                         if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
3469                                 found_sid = true;
3470                         }
3471                 }
3472
3473                 torture_assert(tctx, found_sid,
3474                         "failed to list privileged account");
3475         }
3476
3477         {
3478                 struct lsa_EnumAccountRights r;
3479                 struct lsa_RightSet user_rights;
3480
3481                 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
3482
3483                 r.in.handle = lsa_handle;
3484                 r.in.sid = user_sid;
3485                 r.out.rights = &user_rights;
3486
3487                 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3488                 torture_assert_ntstatus_ok(tctx, status,
3489                         "Failed to enum rights for account");
3490
3491                 if (user_rights.count < 1) {
3492                         torture_warning(tctx, "failed to find newly added rights");
3493                         return false;
3494                 }
3495         }
3496
3497         {
3498                 struct lsa_OpenAccount r;
3499
3500                 torture_comment(tctx, "Testing LSA OpenAccount\n");
3501
3502                 r.in.handle = lsa_handle;
3503                 r.in.sid = user_sid;
3504                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3505                 r.out.acct_handle = &lsa_acct_handle;
3506
3507                 status = dcerpc_lsa_OpenAccount(lp, tctx, &r);
3508                 torture_assert_ntstatus_ok(tctx, status,
3509                         "Failed to open lsa account");
3510         }
3511
3512         {
3513                 struct lsa_GetSystemAccessAccount r;
3514                 uint32_t access_mask;
3515
3516                 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
3517
3518                 r.in.handle = &lsa_acct_handle;
3519                 r.out.access_mask = &access_mask;
3520
3521                 status = dcerpc_lsa_GetSystemAccessAccount(lp, tctx, &r);
3522                 torture_assert_ntstatus_ok(tctx, status,
3523                         "Failed to get lsa system access account");
3524         }
3525
3526         {
3527                 struct lsa_DeleteObject r;
3528
3529                 torture_comment(tctx, "Testing LSA DeleteObject\n");
3530
3531                 r.in.handle = &lsa_acct_handle;
3532                 r.out.handle = &lsa_acct_handle;
3533
3534                 status = dcerpc_lsa_DeleteObject(lp, tctx, &r);
3535                 torture_assert_ntstatus_ok(tctx, status,
3536                         "Failed to delete object");
3537         }
3538
3539         {
3540                 struct lsa_EnumAccounts r;
3541                 uint32_t resume_handle = 0;
3542                 struct lsa_SidArray lsa_sid_array;
3543                 int i;
3544                 bool found_sid = false;
3545
3546                 torture_comment(tctx, "Testing LSA EnumAccounts\n");
3547
3548                 r.in.handle = lsa_handle;
3549                 r.in.num_entries = 0x1000;
3550                 r.in.resume_handle = &resume_handle;
3551                 r.out.sids = &lsa_sid_array;
3552                 r.out.resume_handle = &resume_handle;
3553
3554                 status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
3555                 torture_assert_ntstatus_ok(tctx, status,
3556                         "Failed to enum accounts");
3557
3558                 for (i=0; i < lsa_sid_array.num_sids; i++) {
3559                         if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
3560                                 found_sid = true;
3561                         }
3562                 }
3563
3564                 torture_assert(tctx, !found_sid,
3565                         "should not have listed privileged account");
3566         }
3567
3568         {
3569                 struct lsa_EnumAccountRights r;
3570                 struct lsa_RightSet user_rights;
3571
3572                 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
3573
3574                 r.in.handle = lsa_handle;
3575                 r.in.sid = user_sid;
3576                 r.out.rights = &user_rights;
3577
3578                 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3579                 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3580                         "Failed to enum rights for account");
3581         }
3582
3583         return ret;
3584 }
3585
3586 static bool test_user_ops(struct dcerpc_pipe *p,
3587                           struct torture_context *tctx,
3588                           struct policy_handle *user_handle,
3589                           struct policy_handle *domain_handle,
3590                           const struct dom_sid *domain_sid,
3591                           uint32_t base_acct_flags,
3592                           const char *base_acct_name, enum torture_samr_choice which_ops,
3593                           struct cli_credentials *machine_credentials)
3594 {
3595         char *password = NULL;
3596         struct samr_QueryUserInfo q;
3597         union samr_UserInfo *info;
3598         NTSTATUS status;
3599
3600         bool ret = true;
3601         int i;
3602         uint32_t rid;
3603         const uint32_t password_fields[] = {
3604                 SAMR_FIELD_NT_PASSWORD_PRESENT,
3605                 SAMR_FIELD_LM_PASSWORD_PRESENT,
3606                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
3607                 0
3608         };
3609
3610         status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
3611         if (!NT_STATUS_IS_OK(status)) {
3612                 ret = false;
3613         }
3614
3615         switch (which_ops) {
3616         case TORTURE_SAMR_USER_ATTRIBUTES:
3617                 if (!test_QuerySecurity(p, tctx, user_handle)) {
3618                         ret = false;
3619                 }
3620
3621                 if (!test_QueryUserInfo(p, tctx, user_handle)) {
3622                         ret = false;
3623                 }
3624
3625                 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
3626                         ret = false;
3627                 }
3628
3629                 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
3630                                       base_acct_name)) {
3631                         ret = false;
3632                 }
3633
3634                 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
3635                         ret = false;
3636                 }
3637
3638                 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
3639                         ret = false;
3640                 }
3641
3642                 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
3643                         ret = false;
3644                 }
3645                 break;
3646         case TORTURE_SAMR_PASSWORDS:
3647                 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
3648                         char simple_pass[9];
3649                         char *v = generate_random_str(tctx, 1);
3650
3651                         ZERO_STRUCT(simple_pass);
3652                         memset(simple_pass, *v, sizeof(simple_pass) - 1);
3653
3654                         torture_comment(tctx, "Testing machine account password policy rules\n");
3655
3656                         /* Workstation trust accounts don't seem to need to honour password quality policy */
3657                         if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
3658                                 ret = false;
3659                         }
3660
3661                         if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
3662                                 ret = false;
3663                         }
3664
3665                         /* reset again, to allow another 'user' password change */
3666                         if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
3667                                 ret = false;
3668                         }
3669
3670                         /* Try a 'short' password */
3671                         if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
3672                                 ret = false;
3673                         }
3674
3675                         /* Try a compleatly random password */
3676                         if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
3677                                 ret = false;
3678                         }
3679                 }
3680
3681                 for (i = 0; password_fields[i]; i++) {
3682                         if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
3683                                 ret = false;
3684                         }
3685
3686                         /* check it was set right */
3687                         if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3688                                 ret = false;
3689                         }
3690                 }
3691
3692                 for (i = 0; password_fields[i]; i++) {
3693                         if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
3694                                 ret = false;
3695                         }
3696
3697                         /* check it was set right */
3698                         if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3699                                 ret = false;
3700                         }
3701                 }
3702
3703                 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
3704                         ret = false;
3705                 }
3706
3707                 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
3708                         ret = false;
3709                 }
3710
3711                 if (torture_setting_bool(tctx, "samba4", false)) {
3712                         torture_comment(tctx, "skipping Set Password level 18 and 21 against Samba4\n");
3713                 } else {
3714
3715                         if (!test_SetUserPass_18(p, tctx, user_handle, &password)) {
3716                                 ret = false;
3717                         }
3718
3719                         if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3720                                 ret = false;
3721                         }
3722
3723                         for (i = 0; password_fields[i]; i++) {
3724
3725                                 if (password_fields[i] == SAMR_FIELD_LM_PASSWORD_PRESENT) {
3726                                         /* we need to skip as that would break
3727                                          * the ChangePasswordUser3 verify */
3728                                         continue;
3729                                 }
3730
3731                                 if (!test_SetUserPass_21(p, tctx, user_handle, password_fields[i], &password)) {
3732                                         ret = false;
3733                                 }
3734
3735                                 /* check it was set right */
3736                                 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3737                                         ret = false;
3738                                 }
3739                         }
3740                 }
3741
3742                 q.in.user_handle = user_handle;
3743                 q.in.level = 5;
3744                 q.out.info = &info;
3745
3746                 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
3747                 if (!NT_STATUS_IS_OK(status)) {
3748                         torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
3749                                q.in.level, nt_errstr(status));
3750                         ret = false;
3751                 } else {
3752                         uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
3753                         if ((info->info5.acct_flags) != expected_flags) {
3754                                 torture_warning(tctx, "QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
3755                                        info->info5.acct_flags,
3756                                        expected_flags);
3757                                 /* FIXME: GD */
3758                                 if (!torture_setting_bool(tctx, "samba3", false)) {
3759                                         ret = false;
3760                                 }
3761                         }
3762                         if (info->info5.rid != rid) {
3763                                 torture_warning(tctx, "QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
3764                                        info->info5.rid, rid);
3765
3766                         }
3767                 }
3768
3769                 break;
3770
3771         case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
3772
3773                 /* test last password change timestamp behaviour */
3774                 if (!test_SetPassword_pwdlastset(p, tctx, base_acct_flags,
3775                                                  base_acct_name,
3776                                                  user_handle, &password,
3777                                                  machine_credentials)) {
3778                         ret = false;
3779                 }
3780
3781                 if (ret == true) {
3782                         torture_comment(tctx, "pwdLastSet test succeeded\n");
3783                 } else {
3784                         torture_warning(tctx, "pwdLastSet test failed\n");
3785                 }
3786
3787                 break;
3788
3789         case TORTURE_SAMR_USER_PRIVILEGES: {
3790
3791                 struct dcerpc_pipe *lp;
3792                 struct policy_handle *lsa_handle;
3793
3794                 status = torture_rpc_connection(tctx, &lp, &ndr_table_lsarpc);
3795                 torture_assert_ntstatus_ok(tctx, status, "Failed to open LSA pipe");
3796
3797                 if (!test_lsa_OpenPolicy2(lp, tctx, &lsa_handle)) {
3798                         ret = false;
3799                 }
3800
3801                 if (!test_DeleteUser_with_privs(p, lp, tctx,
3802                                                 domain_handle, lsa_handle, user_handle,
3803                                                 domain_sid, rid,
3804                                                 machine_credentials)) {
3805                         ret = false;
3806                 }
3807
3808                 if (!test_lsa_Close(lp, tctx, lsa_handle)) {
3809                         ret = false;
3810                 }
3811
3812                 if (!ret) {
3813                         torture_warning(tctx, "privileged user delete test failed\n");
3814                 }
3815
3816                 break;
3817         }
3818         case TORTURE_SAMR_OTHER:
3819                 /* We just need the account to exist */
3820                 break;
3821         }
3822         return ret;
3823 }
3824
3825 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
3826                            struct policy_handle *alias_handle,
3827                            const struct dom_sid *domain_sid)
3828 {
3829         bool ret = true;
3830
3831         if (!torture_setting_bool(tctx, "samba3", false)) {
3832                 if (!test_QuerySecurity(p, tctx, alias_handle)) {
3833                         ret = false;
3834                 }
3835         }
3836
3837         if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
3838                 ret = false;
3839         }
3840
3841         if (!test_SetAliasInfo(p, tctx, alias_handle)) {
3842                 ret = false;
3843         }
3844
3845         if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
3846                 ret = false;
3847         }
3848
3849         if (torture_setting_bool(tctx, "samba3", false) ||
3850             torture_setting_bool(tctx, "samba4", false)) {
3851                 torture_comment(tctx, "skipping MultipleMembers Alias tests against Samba\n");
3852                 return ret;
3853         }
3854
3855         if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
3856                 ret = false;
3857         }
3858
3859         return ret;
3860 }
3861
3862
3863 static bool test_DeleteUser(struct dcerpc_pipe *p, struct torture_context *tctx,
3864                                      struct policy_handle *user_handle)
3865 {
3866         struct samr_DeleteUser d;
3867         NTSTATUS status;
3868         torture_comment(tctx, "Testing DeleteUser\n");
3869
3870         d.in.user_handle = user_handle;
3871         d.out.user_handle = user_handle;
3872
3873         status = dcerpc_samr_DeleteUser(p, tctx, &d);
3874         torture_assert_ntstatus_ok(tctx, status, "DeleteUser");
3875
3876         return true;
3877 }
3878
3879 bool test_DeleteUser_byname(struct dcerpc_pipe *p,
3880                             struct torture_context *tctx,
3881                             struct policy_handle *handle, const char *name)
3882 {
3883         NTSTATUS status;
3884         struct samr_DeleteUser d;
3885         struct policy_handle user_handle;
3886         uint32_t rid;
3887
3888         status = test_LookupName(p, tctx, handle, name, &rid);
3889         if (!NT_STATUS_IS_OK(status)) {
3890                 goto failed;
3891         }
3892
3893         status = test_OpenUser_byname(p, tctx, handle, name, &user_handle);
3894         if (!NT_STATUS_IS_OK(status)) {
3895                 goto failed;
3896         }
3897
3898         d.in.user_handle = &user_handle;
3899         d.out.user_handle = &user_handle;
3900         status = dcerpc_samr_DeleteUser(p, tctx, &d);
3901         if (!NT_STATUS_IS_OK(status)) {
3902                 goto failed;
3903         }
3904
3905         return true;
3906
3907 failed:
3908         torture_warning(tctx, "DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
3909         return false;
3910 }
3911
3912
3913 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p,
3914                                     struct torture_context *tctx,
3915                                     struct policy_handle *handle, const char *name)
3916 {
3917         NTSTATUS status;
3918         struct samr_OpenGroup r;
3919         struct samr_DeleteDomainGroup d;
3920         struct policy_handle group_handle;
3921         uint32_t rid;
3922
3923         status = test_LookupName(p, tctx, handle, name, &rid);
3924         if (!NT_STATUS_IS_OK(status)) {
3925                 goto failed;
3926         }
3927
3928         r.in.domain_handle = handle;
3929         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3930         r.in.rid = rid;
3931         r.out.group_handle = &group_handle;
3932         status = dcerpc_samr_OpenGroup(p, tctx, &r);
3933         if (!NT_STATUS_IS_OK(status)) {
3934                 goto failed;
3935         }
3936
3937         d.in.group_handle = &group_handle;
3938         d.out.group_handle = &group_handle;
3939         status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
3940         if (!NT_STATUS_IS_OK(status)) {
3941                 goto failed;
3942         }
3943
3944         return true;
3945
3946 failed:
3947         torture_warning(tctx, "DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
3948         return false;
3949 }
3950
3951
3952 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p,
3953                                     struct torture_context *tctx,
3954                                     struct policy_handle *domain_handle,
3955                                     const char *name)
3956 {
3957         NTSTATUS status;
3958         struct samr_OpenAlias r;
3959         struct samr_DeleteDomAlias d;
3960         struct policy_handle alias_handle;
3961         uint32_t rid;
3962
3963         torture_comment(tctx, "testing DeleteAlias_byname\n");
3964
3965         status = test_LookupName(p, tctx, domain_handle, name, &rid);
3966         if (!NT_STATUS_IS_OK(status)) {
3967                 goto failed;
3968         }
3969
3970         r.in.domain_handle = domain_handle;
3971         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3972         r.in.rid = rid;
3973         r.out.alias_handle = &alias_handle;
3974         status = dcerpc_samr_OpenAlias(p, tctx, &r);
3975         if (!NT_STATUS_IS_OK(status)) {
3976                 goto failed;
3977         }
3978
3979         d.in.alias_handle = &alias_handle;
3980         d.out.alias_handle = &alias_handle;
3981         status = dcerpc_samr_DeleteDomAlias(p, tctx, &d);
3982         if (!NT_STATUS_IS_OK(status)) {
3983                 goto failed;
3984         }
3985
3986         return true;
3987
3988 failed:
3989         torture_warning(tctx, "DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
3990         return false;
3991 }
3992
3993 static bool test_DeleteAlias(struct dcerpc_pipe *p,
3994                              struct torture_context *tctx,
3995                              struct policy_handle *alias_handle)
3996 {
3997         struct samr_DeleteDomAlias d;
3998         NTSTATUS status;
3999         bool ret = true;
4000
4001         torture_comment(tctx, "Testing DeleteAlias\n");
4002
4003         d.in.alias_handle = alias_handle;
4004         d.out.alias_handle = alias_handle;
4005
4006         status = dcerpc_samr_DeleteDomAlias(p, tctx, &d);
4007         if (!NT_STATUS_IS_OK(status)) {
4008                 torture_warning(tctx, "DeleteAlias failed - %s\n", nt_errstr(status));
4009                 ret = false;
4010         }
4011
4012         return ret;
4013 }
4014
4015 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
4016                              struct policy_handle *domain_handle,
4017                              const char *alias_name,
4018                              struct policy_handle *alias_handle,
4019                              const struct dom_sid *domain_sid,
4020                              bool test_alias)
4021 {
4022         NTSTATUS status;
4023         struct samr_CreateDomAlias r;
4024         struct lsa_String name;
4025         uint32_t rid;
4026         bool ret = true;
4027
4028         init_lsa_String(&name, alias_name);
4029         r.in.domain_handle = domain_handle;
4030         r.in.alias_name = &name;
4031         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4032         r.out.alias_handle = alias_handle;
4033         r.out.rid = &rid;
4034
4035         torture_comment(tctx, "Testing CreateAlias (%s)\n", r.in.alias_name->string);
4036
4037         status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
4038
4039         if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4040                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4041                         torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.alias_name->string);
4042                         return true;
4043                 } else {
4044                         torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
4045                                nt_errstr(status));
4046                         return false;
4047                 }
4048         }
4049
4050         if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
4051                 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
4052                         return false;
4053                 }
4054                 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
4055         }
4056
4057         if (!NT_STATUS_IS_OK(status)) {
4058                 torture_warning(tctx, "CreateAlias failed - %s\n", nt_errstr(status));
4059                 return false;
4060         }
4061
4062         if (!test_alias) {
4063                 return ret;
4064         }
4065
4066         if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
4067                 ret = false;
4068         }
4069
4070         return ret;
4071 }
4072
4073 static bool test_ChangePassword(struct dcerpc_pipe *p,
4074                                 struct torture_context *tctx,
4075                                 const char *acct_name,
4076                                 struct policy_handle *domain_handle, char **password)
4077 {
4078         bool ret = true;
4079
4080         if (!*password) {
4081                 return false;
4082         }
4083
4084         if (!test_ChangePasswordUser(p, tctx, acct_name, domain_handle, password)) {
4085                 ret = false;
4086         }
4087
4088         if (!test_ChangePasswordUser2(p, tctx, acct_name, password, 0, true)) {
4089                 ret = false;
4090         }
4091
4092         if (!test_OemChangePasswordUser2(p, tctx, acct_name, domain_handle, password)) {
4093                 ret = false;
4094         }
4095
4096         /* test what happens when setting the old password again */
4097         if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, *password, 0, true)) {
4098                 ret = false;
4099         }
4100
4101         {
4102                 char simple_pass[9];
4103                 char *v = generate_random_str(tctx, 1);
4104
4105                 ZERO_STRUCT(simple_pass);
4106                 memset(simple_pass, *v, sizeof(simple_pass) - 1);
4107
4108                 /* test what happens when picking a simple password */
4109                 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, simple_pass, 0, true)) {
4110                         ret = false;
4111                 }
4112         }
4113
4114         /* set samr_SetDomainInfo level 1 with min_length 5 */
4115         {
4116                 struct samr_QueryDomainInfo r;
4117                 union samr_DomainInfo *info = NULL;
4118                 struct samr_SetDomainInfo s;
4119                 uint16_t len_old, len;
4120                 uint32_t pwd_prop_old;
4121                 int64_t min_pwd_age_old;
4122                 NTSTATUS status;
4123
4124                 len = 5;
4125
4126                 r.in.domain_handle = domain_handle;
4127                 r.in.level = 1;
4128                 r.out.info = &info;
4129
4130                 torture_comment(tctx, "testing samr_QueryDomainInfo level 1\n");
4131                 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
4132                 if (!NT_STATUS_IS_OK(status)) {
4133                         return false;
4134                 }
4135
4136                 s.in.domain_handle = domain_handle;
4137                 s.in.level = 1;
4138                 s.in.info = info;
4139
4140                 /* remember the old min length, so we can reset it */
4141                 len_old = s.in.info->info1.min_password_length;
4142                 s.in.info->info1.min_password_length = len;
4143                 pwd_prop_old = s.in.info->info1.password_properties;
4144                 /* turn off password complexity checks for this test */
4145                 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
4146
4147                 min_pwd_age_old = s.in.info->info1.min_password_age;
4148                 s.in.info->info1.min_password_age = 0;
4149
4150                 torture_comment(tctx, "testing samr_SetDomainInfo level 1\n");
4151                 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
4152                 if (!NT_STATUS_IS_OK(status)) {
4153                         return false;
4154                 }
4155
4156                 torture_comment(tctx, "calling test_ChangePasswordUser3 with too short password\n");
4157
4158                 if (!test_ChangePasswordUser3(p, tctx, acct_name, len - 1, password, NULL, 0, true)) {
4159                         ret = false;
4160                 }
4161
4162                 s.in.info->info1.min_password_length = len_old;
4163                 s.in.info->info1.password_properties = pwd_prop_old;
4164                 s.in.info->info1.min_password_age = min_pwd_age_old;
4165
4166                 torture_comment(tctx, "testing samr_SetDomainInfo level 1\n");
4167                 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
4168                 if (!NT_STATUS_IS_OK(status)) {
4169                         return false;
4170                 }
4171
4172         }
4173
4174         {
4175                 NTSTATUS status;
4176                 struct samr_OpenUser r;
4177                 struct samr_QueryUserInfo q;
4178                 union samr_UserInfo *info;
4179                 struct samr_LookupNames n;
4180                 struct policy_handle user_handle;
4181                 struct samr_Ids rids, types;
4182
4183                 n.in.domain_handle = domain_handle;
4184                 n.in.num_names = 1;
4185                 n.in.names = talloc_array(tctx, struct lsa_String, 1);
4186                 n.in.names[0].string = acct_name;
4187                 n.out.rids = &rids;
4188                 n.out.types = &types;
4189
4190                 status = dcerpc_samr_LookupNames(p, tctx, &n);
4191                 if (!NT_STATUS_IS_OK(status)) {
4192                         torture_warning(tctx, "LookupNames failed - %s\n", nt_errstr(status));
4193                         return false;
4194                 }
4195
4196                 r.in.domain_handle = domain_handle;
4197                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4198                 r.in.rid = n.out.rids->ids[0];
4199                 r.out.user_handle = &user_handle;
4200
4201                 status = dcerpc_samr_OpenUser(p, tctx, &r);
4202                 if (!NT_STATUS_IS_OK(status)) {
4203                         torture_warning(tctx, "OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(status));
4204                         return false;
4205                 }
4206
4207                 q.in.user_handle = &user_handle;
4208                 q.in.level = 5;
4209                 q.out.info = &info;
4210
4211                 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
4212                 if (!NT_STATUS_IS_OK(status)) {
4213                         torture_warning(tctx, "QueryUserInfo failed - %s\n", nt_errstr(status));
4214                         return false;
4215                 }
4216
4217                 torture_comment(tctx, "calling test_ChangePasswordUser3 with too early password change\n");
4218
4219                 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL,
4220                                               info->info5.last_password_change, true)) {
4221                         ret = false;
4222                 }
4223         }
4224
4225         /* we change passwords twice - this has the effect of verifying
4226            they were changed correctly for the final call */
4227         if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
4228                 ret = false;
4229         }
4230
4231         if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
4232                 ret = false;
4233         }
4234
4235         return ret;
4236 }
4237
4238 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
4239                             struct policy_handle *domain_handle,
4240                             const char *user_name,
4241                             struct policy_handle *user_handle_out,
4242                             struct dom_sid *domain_sid,
4243                             enum torture_samr_choice which_ops,
4244                             struct cli_credentials *machine_credentials,
4245                             bool test_user)
4246 {
4247
4248         TALLOC_CTX *user_ctx;
4249
4250         NTSTATUS status;
4251         struct samr_CreateUser r;
4252         struct samr_QueryUserInfo q;
4253         union samr_UserInfo *info;
4254         struct samr_DeleteUser d;
4255         uint32_t rid;
4256
4257         /* This call creates a 'normal' account - check that it really does */
4258         const uint32_t acct_flags = ACB_NORMAL;
4259         struct lsa_String name;
4260         bool ret = true;
4261
4262         struct policy_handle user_handle;
4263         user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
4264         init_lsa_String(&name, user_name);
4265
4266         r.in.domain_handle = domain_handle;
4267         r.in.account_name = &name;
4268         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4269         r.out.user_handle = &user_handle;
4270         r.out.rid = &rid;
4271
4272         torture_comment(tctx, "Testing CreateUser(%s)\n", r.in.account_name->string);
4273
4274         status = dcerpc_samr_CreateUser(p, user_ctx, &r);
4275
4276         if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4277                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
4278                         torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
4279                         return true;
4280                 } else {
4281                         torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
4282                                nt_errstr(status));
4283                         return false;
4284                 }
4285         }
4286
4287         if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4288                 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
4289                         talloc_free(user_ctx);
4290                         return false;
4291                 }
4292                 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
4293         }
4294
4295         if (!NT_STATUS_IS_OK(status)) {
4296                 talloc_free(user_ctx);
4297                 torture_warning(tctx, "CreateUser failed - %s\n", nt_errstr(status));
4298                 return false;
4299         }
4300
4301         if (!test_user) {
4302                 if (user_handle_out) {
4303                         *user_handle_out = user_handle;
4304                 }
4305                 return ret;
4306         }
4307
4308         {
4309                 q.in.user_handle = &user_handle;
4310                 q.in.level = 16;
4311                 q.out.info = &info;
4312
4313                 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
4314                 if (!NT_STATUS_IS_OK(status)) {
4315                         torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
4316                                q.in.level, nt_errstr(status));
4317                         ret = false;
4318                 } else {
4319                         if ((info->info16.acct_flags & acct_flags) != acct_flags) {
4320                                 torture_warning(tctx, "QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4321                                        info->info16.acct_flags,
4322                                        acct_flags);
4323                                 ret = false;
4324                         }
4325                 }
4326
4327                 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
4328                                    domain_sid, acct_flags, name.string, which_ops,
4329                                    machine_credentials)) {
4330                         ret = false;
4331                 }
4332
4333                 if (user_handle_out) {
4334                         *user_handle_out = user_handle;
4335                 } else {
4336                         torture_comment(tctx, "Testing DeleteUser (createuser test)\n");
4337
4338                         d.in.user_handle = &user_handle;
4339                         d.out.user_handle = &user_handle;
4340
4341                         status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
4342                         if (!NT_STATUS_IS_OK(status)) {
4343                                 torture_warning(tctx, "DeleteUser failed - %s\n", nt_errstr(status));
4344                                 ret = false;
4345                         }
4346                 }
4347
4348         }
4349
4350         talloc_free(user_ctx);
4351
4352         return ret;
4353 }
4354
4355
4356 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
4357                              struct policy_handle *domain_handle,
4358                              struct dom_sid *domain_sid,
4359                              enum torture_samr_choice which_ops,
4360                              struct cli_credentials *machine_credentials)
4361 {
4362         NTSTATUS status;
4363         struct samr_CreateUser2 r;
4364         struct samr_QueryUserInfo q;
4365         union samr_UserInfo *info;
4366         struct samr_DeleteUser d;
4367         struct policy_handle user_handle;
4368         uint32_t rid;
4369         struct lsa_String name;
4370         bool ret = true;
4371         int i;
4372
4373         struct {
4374                 uint32_t acct_flags;
4375                 const char *account_name;
4376                 NTSTATUS nt_status;
4377         } account_types[] = {
4378                 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
4379                 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4380                 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4381                 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
4382                 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4383                 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4384                 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
4385                 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4386                 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4387                 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_ACCESS_DENIED },
4388                 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
4389                 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
4390                 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4391                 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4392                 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
4393         };
4394
4395         for (i = 0; account_types[i].account_name; i++) {
4396                 TALLOC_CTX *user_ctx;
4397                 uint32_t acct_flags = account_types[i].acct_flags;
4398                 uint32_t access_granted;
4399                 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
4400                 init_lsa_String(&name, account_types[i].account_name);
4401
4402                 r.in.domain_handle = domain_handle;
4403                 r.in.account_name = &name;
4404                 r.in.acct_flags = acct_flags;
4405                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4406                 r.out.user_handle = &user_handle;
4407                 r.out.access_granted = &access_granted;
4408                 r.out.rid = &rid;
4409
4410                 torture_comment(tctx, "Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
4411
4412                 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
4413
4414                 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4415                         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
4416                                 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
4417                                 continue;
4418                         } else {
4419                                 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
4420                                        nt_errstr(status));
4421                                 ret = false;
4422                                 continue;
4423                         }
4424                 }
4425
4426                 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4427                         if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
4428                                 talloc_free(user_ctx);
4429                                 ret = false;
4430                                 continue;
4431                         }
4432                         status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
4433
4434                 }
4435                 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
4436                         torture_warning(tctx, "CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
4437                                nt_errstr(status), nt_errstr(account_types[i].nt_status));
4438                         ret = false;
4439                 }
4440
4441                 if (NT_STATUS_IS_OK(status)) {
4442                         q.in.user_handle = &user_handle;
4443                         q.in.level = 5;
4444                         q.out.info = &info;
4445
4446                         status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
4447                         if (!NT_STATUS_IS_OK(status)) {
4448                                 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
4449                                        q.in.level, nt_errstr(status));
4450                                 ret = false;
4451                         } else {
4452                                 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
4453                                 if (acct_flags == ACB_NORMAL) {
4454                                         expected_flags |= ACB_PW_EXPIRED;
4455                                 }
4456                                 if ((info->info5.acct_flags) != expected_flags) {
4457                                         torture_warning(tctx, "QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4458                                                info->info5.acct_flags,
4459                                                expected_flags);
4460                                         ret = false;
4461                                 }
4462                                 switch (acct_flags) {
4463                                 case ACB_SVRTRUST:
4464                                         if (info->info5.primary_gid != DOMAIN_RID_DCS) {
4465                                                 torture_warning(tctx, "QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
4466                                                        DOMAIN_RID_DCS, info->info5.primary_gid);
4467                                                 ret = false;
4468                                         }
4469                                         break;
4470                                 case ACB_WSTRUST:
4471                                         if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
4472                                                 torture_warning(tctx, "QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
4473                                                        DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
4474                                                 ret = false;
4475                                         }
4476                                         break;
4477                                 case ACB_NORMAL:
4478                                         if (info->info5.primary_gid != DOMAIN_RID_USERS) {
4479                                                 torture_warning(tctx, "QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
4480                                                        DOMAIN_RID_USERS, info->info5.primary_gid);
4481                                                 ret = false;
4482                                         }
4483                                         break;
4484                                 }
4485                         }
4486
4487                         if (!test_user_ops(p, tctx, &user_handle, domain_handle,
4488                                            domain_sid, acct_flags, name.string, which_ops,
4489                                            machine_credentials)) {
4490                                 ret = false;
4491                         }
4492
4493                         if (!policy_handle_empty(&user_handle)) {
4494                                 torture_comment(tctx, "Testing DeleteUser (createuser2 test)\n");
4495
4496                                 d.in.user_handle = &user_handle;
4497                                 d.out.user_handle = &user_handle;
4498
4499                                 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
4500                                 if (!NT_STATUS_IS_OK(status)) {
4501                                         torture_warning(tctx, "DeleteUser failed - %s\n", nt_errstr(status));
4502                                         ret = false;
4503                                 }
4504                         }
4505                 }
4506                 talloc_free(user_ctx);
4507         }
4508
4509         return ret;
4510 }
4511
4512 static bool test_QueryAliasInfo(struct dcerpc_pipe *p,
4513                                 struct torture_context *tctx,
4514                                 struct policy_handle *handle)
4515 {
4516         NTSTATUS status;
4517         struct samr_QueryAliasInfo r;
4518         union samr_AliasInfo *info;
4519         uint16_t levels[] = {1, 2, 3};
4520         int i;
4521         bool ret = true;
4522
4523         for (i=0;i<ARRAY_SIZE(levels);i++) {
4524                 torture_comment(tctx, "Testing QueryAliasInfo level %u\n", levels[i]);
4525
4526                 r.in.alias_handle = handle;
4527                 r.in.level = levels[i];
4528                 r.out.info = &info;
4529
4530                 status = dcerpc_samr_QueryAliasInfo(p, tctx, &r);
4531                 if (!NT_STATUS_IS_OK(status)) {
4532                         torture_warning(tctx, "QueryAliasInfo level %u failed - %s\n",
4533                                levels[i], nt_errstr(status));
4534                         ret = false;
4535                 }
4536         }
4537
4538         return ret;
4539 }
4540
4541 static bool test_QueryGroupInfo(struct dcerpc_pipe *p,
4542                                 struct torture_context *tctx,
4543                                 struct policy_handle *handle)
4544 {
4545         NTSTATUS status;
4546         struct samr_QueryGroupInfo r;
4547         union samr_GroupInfo *info;
4548         uint16_t levels[] = {1, 2, 3, 4, 5};
4549         int i;
4550         bool ret = true;
4551
4552         for (i=0;i<ARRAY_SIZE(levels);i++) {
4553                 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
4554
4555                 r.in.group_handle = handle;
4556                 r.in.level = levels[i];
4557                 r.out.info = &info;
4558
4559                 status = dcerpc_samr_QueryGroupInfo(p, tctx, &r);
4560                 if (!NT_STATUS_IS_OK(status)) {
4561                         torture_warning(tctx, "QueryGroupInfo level %u failed - %s\n",
4562                                levels[i], nt_errstr(status));
4563                         ret = false;
4564                 }
4565         }
4566
4567         return ret;
4568 }
4569
4570 static bool test_QueryGroupMember(struct dcerpc_pipe *p,
4571                                   struct torture_context *tctx,
4572                                   struct policy_handle *handle)
4573 {
4574         NTSTATUS status;
4575         struct samr_QueryGroupMember r;
4576         struct samr_RidTypeArray *rids = NULL;
4577         bool ret = true;
4578
4579         torture_comment(tctx, "Testing QueryGroupMember\n");
4580
4581         r.in.group_handle = handle;
4582         r.out.rids = &rids;
4583
4584         status = dcerpc_samr_QueryGroupMember(p, tctx, &r);
4585         if (!NT_STATUS_IS_OK(status)) {
4586                 torture_warning(tctx, "QueryGroupInfo failed - %s\n", nt_errstr(status));
4587                 ret = false;
4588         }
4589
4590         return ret;
4591 }
4592
4593
4594 static bool test_SetGroupInfo(struct dcerpc_pipe *p,
4595                               struct torture_context *tctx,
4596                               struct policy_handle *handle)
4597 {
4598         NTSTATUS status;
4599         struct samr_QueryGroupInfo r;
4600         union samr_GroupInfo *info;
4601         struct samr_SetGroupInfo s;
4602         uint16_t levels[] = {1, 2, 3, 4};
4603         uint16_t set_ok[] = {0, 1, 1, 1};
4604         int i;
4605         bool ret = true;
4606
4607         for (i=0;i<ARRAY_SIZE(levels);i++) {
4608                 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
4609
4610                 r.in.group_handle = handle;
4611                 r.in.level = levels[i];
4612                 r.out.info = &info;
4613
4614                 status = dcerpc_samr_QueryGroupInfo(p, tctx, &r);
4615                 if (!NT_STATUS_IS_OK(status)) {
4616                         torture_warning(tctx, "QueryGroupInfo level %u failed - %s\n",
4617                                levels[i], nt_errstr(status));
4618                         ret = false;
4619                 }
4620
4621                 torture_comment(tctx, "Testing SetGroupInfo level %u\n", levels[i]);
4622
4623                 s.in.group_handle = handle;
4624                 s.in.level = levels[i];
4625                 s.in.info = *r.out.info;
4626
4627 #if 0
4628                 /* disabled this, as it changes the name only from the point of view of samr,
4629                    but leaves the name from the point of view of w2k3 internals (and ldap). This means
4630                    the name is still reserved, so creating the old name fails, but deleting by the old name
4631                    also fails */
4632                 if (s.in.level == 2) {
4633                         init_lsa_String(&s.in.info->string, "NewName");
4634                 }
4635 #endif
4636
4637                 if (s.in.level == 4) {
4638                         init_lsa_String(&s.in.info->description, "test description");
4639                 }
4640
4641                 status = dcerpc_samr_SetGroupInfo(p, tctx, &s);
4642                 if (set_ok[i]) {
4643                         if (!NT_STATUS_IS_OK(status)) {
4644                                 torture_warning(tctx, "SetGroupInfo level %u failed - %s\n",
4645                                        r.in.level, nt_errstr(status));
4646                                 ret = false;
4647                                 continue;
4648                         }
4649                 } else {
4650                         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
4651                                 torture_warning(tctx, "SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
4652                                        r.in.level, nt_errstr(status));
4653                                 ret = false;
4654                                 continue;
4655                         }
4656                 }
4657         }
4658
4659         return ret;
4660 }
4661
4662 static bool test_QueryUserInfo(struct dcerpc_pipe *p,
4663                                struct torture_context *tctx,
4664                                struct policy_handle *handle)
4665 {
4666         NTSTATUS status;
4667         struct samr_QueryUserInfo r;
4668         union samr_UserInfo *info;
4669         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4670                            11, 12, 13, 14, 16, 17, 20, 21};
4671         int i;
4672         bool ret = true;
4673
4674         for (i=0;i<ARRAY_SIZE(levels);i++) {
4675                 torture_comment(tctx, "Testing QueryUserInfo level %u\n", levels[i]);
4676
4677                 r.in.user_handle = handle;
4678                 r.in.level = levels[i];
4679                 r.out.info = &info;
4680
4681                 status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
4682                 if (!NT_STATUS_IS_OK(status)) {
4683                         torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
4684                                levels[i], nt_errstr(status));
4685                         ret = false;
4686                 }
4687         }
4688
4689         return ret;
4690 }
4691
4692 static bool test_QueryUserInfo2(struct dcerpc_pipe *p,
4693                                 struct torture_context *tctx,
4694                                 struct policy_handle *handle)
4695 {
4696         NTSTATUS status;
4697         struct samr_QueryUserInfo2 r;
4698         union samr_UserInfo *info;
4699         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4700                            11, 12, 13, 14, 16, 17, 20, 21};
4701         int i;
4702         bool ret = true;
4703
4704         for (i=0;i<ARRAY_SIZE(levels);i++) {
4705                 torture_comment(tctx, "Testing QueryUserInfo2 level %u\n", levels[i]);
4706
4707                 r.in.user_handle = handle;
4708                 r.in.level = levels[i];
4709                 r.out.info = &info;
4710
4711                 status = dcerpc_samr_QueryUserInfo2(p, tctx, &r);
4712                 if (!NT_STATUS_IS_OK(status)) {
4713                         torture_warning(tctx, "QueryUserInfo2 level %u failed - %s\n",
4714                                levels[i], nt_errstr(status));
4715                         ret = false;
4716                 }
4717         }
4718
4719         return ret;
4720 }
4721
4722 static bool test_OpenUser(struct dcerpc_pipe *p,
4723                           struct torture_context *tctx,
4724                           struct policy_handle *handle, uint32_t rid)
4725 {
4726         NTSTATUS status;
4727         struct samr_OpenUser r;
4728         struct policy_handle user_handle;
4729         bool ret = true;
4730
4731         torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
4732
4733         r.in.domain_handle = handle;
4734         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4735         r.in.rid = rid;
4736         r.out.user_handle = &user_handle;
4737
4738         status = dcerpc_samr_OpenUser(p, tctx, &r);
4739         if (!NT_STATUS_IS_OK(status)) {
4740                 torture_warning(tctx, "OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
4741                 return false;
4742         }
4743
4744         if (!test_QuerySecurity(p, tctx, &user_handle)) {
4745                 ret = false;
4746         }
4747
4748         if (!test_QueryUserInfo(p, tctx, &user_handle)) {
4749                 ret = false;
4750         }
4751
4752         if (!test_QueryUserInfo2(p, tctx, &user_handle)) {
4753                 ret = false;
4754         }
4755
4756         if (!test_GetUserPwInfo(p, tctx, &user_handle)) {
4757                 ret = false;
4758         }
4759
4760         if (!test_GetGroupsForUser(p,tctx, &user_handle)) {
4761                 ret = false;
4762         }
4763
4764         if (!test_samr_handle_Close(p, tctx, &user_handle)) {
4765                 ret = false;
4766         }
4767
4768         return ret;
4769 }
4770
4771 static bool test_OpenGroup(struct dcerpc_pipe *p,
4772                            struct torture_context *tctx,
4773                            struct policy_handle *handle, uint32_t rid)
4774 {
4775         NTSTATUS status;
4776         struct samr_OpenGroup r;
4777         struct policy_handle group_handle;
4778         bool ret = true;
4779
4780         torture_comment(tctx, "Testing OpenGroup(%u)\n", rid);
4781
4782         r.in.domain_handle = handle;
4783         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4784         r.in.rid = rid;
4785         r.out.group_handle = &group_handle;
4786
4787         status = dcerpc_samr_OpenGroup(p, tctx, &r);
4788         if (!NT_STATUS_IS_OK(status)) {
4789                 torture_warning(tctx, "OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
4790                 return false;
4791         }
4792
4793         if (!torture_setting_bool(tctx, "samba3", false)) {
4794                 if (!test_QuerySecurity(p, tctx, &group_handle)) {
4795                         ret = false;
4796                 }
4797         }
4798
4799         if (!test_QueryGroupInfo(p, tctx, &group_handle)) {
4800                 ret = false;
4801         }
4802
4803         if (!test_QueryGroupMember(p, tctx, &group_handle)) {
4804                 ret = false;
4805         }
4806
4807         if (!test_samr_handle_Close(p, tctx, &group_handle)) {
4808                 ret = false;
4809         }
4810
4811         return ret;
4812 }
4813
4814 static bool test_OpenAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
4815                            struct policy_handle *handle, uint32_t rid)
4816 {
4817         NTSTATUS status;
4818         struct samr_OpenAlias r;
4819         struct policy_handle alias_handle;
4820         bool ret = true;
4821
4822         torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
4823
4824         r.in.domain_handle = handle;
4825         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4826         r.in.rid = rid;
4827         r.out.alias_handle = &alias_handle;
4828
4829         status = dcerpc_samr_OpenAlias(p, tctx, &r);
4830         if (!NT_STATUS_IS_OK(status)) {
4831                 torture_warning(tctx, "OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
4832                 return false;
4833         }
4834
4835         if (!torture_setting_bool(tctx, "samba3", false)) {
4836                 if (!test_QuerySecurity(p, tctx, &alias_handle)) {
4837                         ret = false;
4838                 }
4839         }
4840
4841         if (!test_QueryAliasInfo(p, tctx, &alias_handle)) {
4842                 ret = false;
4843         }
4844
4845         if (!test_GetMembersInAlias(p, tctx, &alias_handle)) {
4846                 ret = false;
4847         }
4848
4849         if (!test_samr_handle_Close(p, tctx, &alias_handle)) {
4850                 ret = false;
4851         }
4852
4853         return ret;
4854 }
4855
4856 static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
4857                        struct policy_handle *handle, uint32_t rid,
4858                        uint32_t acct_flag_mask)
4859 {
4860         NTSTATUS status;
4861         struct samr_OpenUser r;
4862         struct samr_QueryUserInfo q;
4863         union samr_UserInfo *info;
4864         struct policy_handle user_handle;
4865         bool ret = true;
4866
4867         torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
4868
4869         r.in.domain_handle = handle;
4870         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4871         r.in.rid = rid;
4872         r.out.user_handle = &user_handle;
4873
4874         status = dcerpc_samr_OpenUser(p, tctx, &r);
4875         if (!NT_STATUS_IS_OK(status)) {
4876                 torture_warning(tctx, "OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
4877                 return false;
4878         }
4879
4880         q.in.user_handle = &user_handle;
4881         q.in.level = 16;
4882         q.out.info = &info;
4883
4884         status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
4885         if (!NT_STATUS_IS_OK(status)) {
4886                 torture_warning(tctx, "QueryUserInfo level 16 failed - %s\n",
4887                        nt_errstr(status));
4888                 ret = false;
4889         } else {
4890                 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
4891                         torture_warning(tctx, "Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
4892                                acct_flag_mask, info->info16.acct_flags, rid);
4893                         ret = false;
4894                 }
4895         }
4896
4897         if (!test_samr_handle_Close(p, tctx, &user_handle)) {
4898                 ret = false;
4899         }
4900
4901         return ret;
4902 }
4903
4904 static bool test_EnumDomainUsers_all(struct dcerpc_pipe *p,
4905                                      struct torture_context *tctx,
4906                                      struct policy_handle *handle)
4907 {
4908         NTSTATUS status = STATUS_MORE_ENTRIES;
4909         struct samr_EnumDomainUsers r;
4910         uint32_t mask, resume_handle=0;
4911         int i, mask_idx;
4912         bool ret = true;
4913         struct samr_LookupNames n;
4914         struct samr_LookupRids  lr ;
4915         struct lsa_Strings names;
4916         struct samr_Ids rids, types;
4917         struct samr_SamArray *sam = NULL;
4918         uint32_t num_entries = 0;
4919
4920         uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
4921                             ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
4922                             ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
4923                             ACB_PWNOEXP, 0};
4924
4925         torture_comment(tctx, "Testing EnumDomainUsers\n");
4926
4927         for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
4928                 r.in.domain_handle = handle;
4929                 r.in.resume_handle = &resume_handle;
4930                 r.in.acct_flags = mask = masks[mask_idx];
4931                 r.in.max_size = (uint32_t)-1;
4932                 r.out.resume_handle = &resume_handle;
4933                 r.out.num_entries = &num_entries;
4934                 r.out.sam = &sam;
4935
4936                 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
4937                 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
4938                     !NT_STATUS_IS_OK(status)) {
4939                         torture_warning(tctx, "EnumDomainUsers failed - %s\n", nt_errstr(status));
4940                         return false;
4941                 }
4942
4943                 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
4944
4945                 if (sam->count == 0) {
4946                         continue;
4947                 }
4948
4949                 for (i=0;i<sam->count;i++) {
4950                         if (mask) {
4951                                 if (!check_mask(p, tctx, handle, sam->entries[i].idx, mask)) {
4952                                         ret = false;
4953                                 }
4954                         } else if (!test_OpenUser(p, tctx, handle, sam->entries[i].idx)) {
4955                                 ret = false;
4956                         }
4957                 }
4958         }
4959
4960         torture_comment(tctx, "Testing LookupNames\n");
4961         n.in.domain_handle = handle;
4962         n.in.num_names = sam->count;
4963         n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
4964         n.out.rids = &rids;
4965         n.out.types = &types;
4966         for (i=0;i<sam->count;i++) {
4967                 n.in.names[i].string = sam->entries[i].name.string;
4968         }
4969         status = dcerpc_samr_LookupNames(p, tctx, &n);
4970         if (!NT_STATUS_IS_OK(status)) {
4971                 torture_warning(tctx, "LookupNames failed - %s\n", nt_errstr(status));
4972                 ret = false;
4973         }
4974
4975
4976         torture_comment(tctx, "Testing LookupRids\n");
4977         lr.in.domain_handle = handle;
4978         lr.in.num_rids = sam->count;
4979         lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
4980         lr.out.names = &names;
4981         lr.out.types = &types;
4982         for (i=0;i<sam->count;i++) {
4983                 lr.in.rids[i] = sam->entries[i].idx;
4984         }
4985         status = dcerpc_samr_LookupRids(p, tctx, &lr);
4986         torture_assert_ntstatus_ok(tctx, status, "LookupRids");
4987
4988         return ret;
4989 }
4990
4991 /*
4992   try blasting the server with a bunch of sync requests
4993 */
4994 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
4995                                        struct policy_handle *handle)
4996 {
4997         NTSTATUS status;
4998         struct samr_EnumDomainUsers r;
4999         uint32_t resume_handle=0;
5000         int i;
5001 #define ASYNC_COUNT 100
5002         struct rpc_request *req[ASYNC_COUNT];
5003
5004         if (!torture_setting_bool(tctx, "dangerous", false)) {
5005                 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
5006         }
5007
5008         torture_comment(tctx, "Testing EnumDomainUsers_async\n");
5009
5010         r.in.domain_handle = handle;
5011         r.in.resume_handle = &resume_handle;
5012         r.in.acct_flags = 0;
5013         r.in.max_size = (uint32_t)-1;
5014         r.out.resume_handle = &resume_handle;
5015
5016         for (i=0;i<ASYNC_COUNT;i++) {
5017                 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
5018         }
5019
5020         for (i=0;i<ASYNC_COUNT;i++) {
5021                 status = dcerpc_ndr_request_recv(req[i]);
5022                 if (!NT_STATUS_IS_OK(status)) {
5023                         torture_warning(tctx, "EnumDomainUsers[%d] failed - %s\n",
5024                                i, nt_errstr(status));
5025                         return false;
5026                 }
5027         }
5028
5029         torture_comment(tctx, "%d async requests OK\n", i);
5030
5031         return true;
5032 }
5033
5034 static bool test_EnumDomainGroups_all(struct dcerpc_pipe *p,
5035                                       struct torture_context *tctx,
5036                                       struct policy_handle *handle)
5037 {
5038         NTSTATUS status;
5039         struct samr_EnumDomainGroups r;
5040         uint32_t resume_handle=0;
5041         struct samr_SamArray *sam = NULL;
5042         uint32_t num_entries = 0;
5043         int i;
5044         bool ret = true;
5045
5046         torture_comment(tctx, "Testing EnumDomainGroups\n");
5047
5048         r.in.domain_handle = handle;
5049         r.in.resume_handle = &resume_handle;
5050         r.in.max_size = (uint32_t)-1;
5051         r.out.resume_handle = &resume_handle;
5052         r.out.num_entries = &num_entries;
5053         r.out.sam = &sam;
5054
5055         status = dcerpc_samr_EnumDomainGroups(p, tctx, &r);
5056         if (!NT_STATUS_IS_OK(status)) {
5057                 torture_warning(tctx, "EnumDomainGroups failed - %s\n", nt_errstr(status));
5058                 return false;
5059         }
5060
5061         if (!sam) {
5062                 return false;
5063         }
5064
5065         for (i=0;i<sam->count;i++) {
5066                 if (!test_OpenGroup(p, tctx, handle, sam->entries[i].idx)) {
5067                         ret = false;
5068                 }
5069         }
5070
5071         return ret;
5072 }
5073
5074 static bool test_EnumDomainAliases_all(struct dcerpc_pipe *p,
5075                                        struct torture_context *tctx,
5076                                        struct policy_handle *handle)
5077 {
5078         NTSTATUS status;
5079         struct samr_EnumDomainAliases r;
5080         uint32_t resume_handle=0;
5081         struct samr_SamArray *sam = NULL;
5082         uint32_t num_entries = 0;
5083         int i;
5084         bool ret = true;
5085
5086         torture_comment(tctx, "Testing EnumDomainAliases\n");
5087
5088         r.in.domain_handle = handle;
5089         r.in.resume_handle = &resume_handle;
5090         r.in.max_size = (uint32_t)-1;
5091         r.out.sam = &sam;
5092         r.out.num_entries = &num_entries;
5093         r.out.resume_handle = &resume_handle;
5094
5095         status = dcerpc_samr_EnumDomainAliases(p, tctx, &r);
5096         if (!NT_STATUS_IS_OK(status)) {
5097                 torture_warning(tctx, "EnumDomainAliases failed - %s\n", nt_errstr(status));
5098                 return false;
5099         }
5100
5101         if (!sam) {
5102                 return false;
5103         }
5104
5105         for (i=0;i<sam->count;i++) {
5106                 if (!test_OpenAlias(p, tctx, handle, sam->entries[i].idx)) {
5107                         ret = false;
5108                 }
5109         }
5110
5111         return ret;
5112 }
5113
5114 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p,
5115                                             struct torture_context *tctx,
5116                                             struct policy_handle *handle)
5117 {
5118         NTSTATUS status;
5119         struct samr_GetDisplayEnumerationIndex r;
5120         bool ret = true;
5121         uint16_t levels[] = {1, 2, 3, 4, 5};
5122         uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
5123         struct lsa_String name;
5124         uint32_t idx = 0;
5125         int i;
5126
5127         for (i=0;i<ARRAY_SIZE(levels);i++) {
5128                 torture_comment(tctx, "Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
5129
5130                 init_lsa_String(&name, TEST_ACCOUNT_NAME);
5131
5132                 r.in.domain_handle = handle;
5133                 r.in.level = levels[i];
5134                 r.in.name = &name;
5135                 r.out.idx = &idx;
5136
5137                 status = dcerpc_samr_GetDisplayEnumerationIndex(p, tctx, &r);
5138
5139                 if (ok_lvl[i] &&
5140                     !NT_STATUS_IS_OK(status) &&
5141                     !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5142                         torture_warning(tctx, "GetDisplayEnumerationIndex level %u failed - %s\n",
5143                                levels[i], nt_errstr(status));
5144                         ret = false;
5145                 }
5146
5147                 init_lsa_String(&name, "zzzzzzzz");
5148
5149                 status = dcerpc_samr_GetDisplayEnumerationIndex(p, tctx, &r);
5150
5151                 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5152                         torture_warning(tctx, "GetDisplayEnumerationIndex level %u failed - %s\n",
5153                                levels[i], nt_errstr(status));
5154                         ret = false;
5155                 }
5156         }
5157
5158         return ret;
5159 }
5160
5161 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p,
5162                                              struct torture_context *tctx,
5163                                              struct policy_handle *handle)
5164 {
5165         NTSTATUS status;
5166         struct samr_GetDisplayEnumerationIndex2 r;
5167         bool ret = true;
5168         uint16_t levels[] = {1, 2, 3, 4, 5};
5169         uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
5170         struct lsa_String name;
5171         uint32_t idx = 0;
5172         int i;
5173
5174         for (i=0;i<ARRAY_SIZE(levels);i++) {
5175                 torture_comment(tctx, "Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
5176
5177                 init_lsa_String(&name, TEST_ACCOUNT_NAME);
5178
5179                 r.in.domain_handle = handle;
5180                 r.in.level = levels[i];
5181                 r.in.name = &name;
5182                 r.out.idx = &idx;
5183
5184                 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, tctx, &r);
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, "GetDisplayEnumerationIndex2 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_GetDisplayEnumerationIndex2(p, tctx, &r);
5196                 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5197                         torture_warning(tctx, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
5198                                levels[i], nt_errstr(status));
5199                         ret = false;
5200                 }
5201         }
5202
5203         return ret;
5204 }
5205
5206 #define STRING_EQUAL_QUERY(s1, s2, user)                                        \
5207         if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
5208                 /* odd, but valid */                                            \
5209         } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
5210                         torture_warning(tctx, "%s mismatch for %s: %s != %s (%s)\n", \
5211                                #s1, user.string,  s1.string, s2.string, __location__);   \
5212                         ret = false; \
5213         }
5214 #define INT_EQUAL_QUERY(s1, s2, user)           \
5215                 if (s1 != s2) { \
5216                         torture_warning(tctx, "%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
5217                                #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
5218                         ret = false; \
5219                 }
5220
5221 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p,
5222                                        struct torture_context *tctx,
5223                                        struct samr_QueryDisplayInfo *querydisplayinfo,
5224                                        bool *seen_testuser)
5225 {
5226         struct samr_OpenUser r;
5227         struct samr_QueryUserInfo q;
5228         union samr_UserInfo *info;
5229         struct policy_handle user_handle;
5230         int i, ret = true;
5231         NTSTATUS status;
5232         r.in.domain_handle = querydisplayinfo->in.domain_handle;
5233         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5234         for (i = 0; ; i++) {
5235                 switch (querydisplayinfo->in.level) {
5236                 case 1:
5237                         if (i >= querydisplayinfo->out.info->info1.count) {
5238                                 return ret;
5239                         }
5240                         r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
5241                         break;
5242                 case 2:
5243                         if (i >= querydisplayinfo->out.info->info2.count) {
5244                                 return ret;
5245                         }
5246                         r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
5247                         break;
5248                 case 3:
5249                         /* Groups */
5250                 case 4:
5251                 case 5:
5252                         /* Not interested in validating just the account name */
5253                         return true;
5254                 }
5255
5256                 r.out.user_handle = &user_handle;
5257
5258                 switch (querydisplayinfo->in.level) {
5259                 case 1:
5260                 case 2:
5261                         status = dcerpc_samr_OpenUser(p, tctx, &r);
5262                         if (!NT_STATUS_IS_OK(status)) {
5263                                 torture_warning(tctx, "OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
5264                                 return false;
5265                         }
5266                 }
5267
5268                 q.in.user_handle = &user_handle;
5269                 q.in.level = 21;
5270                 q.out.info = &info;
5271                 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
5272                 if (!NT_STATUS_IS_OK(status)) {
5273                         torture_warning(tctx, "QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
5274                         return false;
5275                 }
5276
5277                 switch (querydisplayinfo->in.level) {
5278                 case 1:
5279                         if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
5280                                 *seen_testuser = true;
5281                         }
5282                         STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
5283                                            info->info21.full_name, info->info21.account_name);
5284                         STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
5285                                            info->info21.account_name, info->info21.account_name);
5286                         STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
5287                                            info->info21.description, info->info21.account_name);
5288                         INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
5289                                         info->info21.rid, info->info21.account_name);
5290                         INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
5291                                         info->info21.acct_flags, info->info21.account_name);
5292
5293                         break;
5294                 case 2:
5295                         STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
5296                                            info->info21.account_name, info->info21.account_name);
5297                         STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
5298                                            info->info21.description, info->info21.account_name);
5299                         INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
5300                                         info->info21.rid, info->info21.account_name);
5301                         INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
5302                                         info->info21.acct_flags, info->info21.account_name);
5303
5304                         if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
5305                                 torture_warning(tctx, "Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
5306                                        info->info21.account_name.string);
5307                         }
5308
5309                         if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
5310                                 torture_warning(tctx, "Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
5311                                        info->info21.account_name.string,
5312                                        querydisplayinfo->out.info->info2.entries[i].acct_flags,
5313                                        info->info21.acct_flags);
5314                                 return false;
5315                         }
5316
5317                         break;
5318                 }
5319
5320                 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
5321                         return false;
5322                 }
5323         }
5324         return ret;
5325 }
5326
5327 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p,
5328                                   struct torture_context *tctx,
5329                                   struct policy_handle *handle)
5330 {
5331         NTSTATUS status;
5332         struct samr_QueryDisplayInfo r;
5333         struct samr_QueryDomainInfo dom_info;
5334         union samr_DomainInfo *info = NULL;
5335         bool ret = true;
5336         uint16_t levels[] = {1, 2, 3, 4, 5};
5337         int i;
5338         bool seen_testuser = false;
5339         uint32_t total_size;
5340         uint32_t returned_size;
5341         union samr_DispInfo disp_info;
5342
5343
5344         for (i=0;i<ARRAY_SIZE(levels);i++) {
5345                 torture_comment(tctx, "Testing QueryDisplayInfo level %u\n", levels[i]);
5346
5347                 r.in.start_idx = 0;
5348                 status = STATUS_MORE_ENTRIES;
5349                 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5350                         r.in.domain_handle = handle;
5351                         r.in.level = levels[i];
5352                         r.in.max_entries = 2;
5353                         r.in.buf_size = (uint32_t)-1;
5354                         r.out.total_size = &total_size;
5355                         r.out.returned_size = &returned_size;
5356                         r.out.info = &disp_info;
5357
5358                         status = dcerpc_samr_QueryDisplayInfo(p, tctx, &r);
5359                         if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
5360                                 torture_warning(tctx, "QueryDisplayInfo level %u failed - %s\n",
5361                                        levels[i], nt_errstr(status));
5362                                 ret = false;
5363                         }
5364                         switch (r.in.level) {
5365                         case 1:
5366                                 if (!test_each_DisplayInfo_user(p, tctx, &r, &seen_testuser)) {
5367                                         ret = false;
5368                                 }
5369                                 r.in.start_idx += r.out.info->info1.count;
5370                                 break;
5371                         case 2:
5372                                 if (!test_each_DisplayInfo_user(p, tctx, &r, NULL)) {
5373                                         ret = false;
5374                                 }
5375                                 r.in.start_idx += r.out.info->info2.count;
5376                                 break;
5377                         case 3:
5378                                 r.in.start_idx += r.out.info->info3.count;
5379                                 break;
5380                         case 4:
5381                                 r.in.start_idx += r.out.info->info4.count;
5382                                 break;
5383                         case 5:
5384                                 r.in.start_idx += r.out.info->info5.count;
5385                                 break;
5386                         }
5387                 }
5388                 dom_info.in.domain_handle = handle;
5389                 dom_info.in.level = 2;
5390                 dom_info.out.info = &info;
5391
5392                 /* Check number of users returned is correct */
5393                 status = dcerpc_samr_QueryDomainInfo(p, tctx, &dom_info);
5394                 if (!NT_STATUS_IS_OK(status)) {
5395                         torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
5396                                r.in.level, nt_errstr(status));
5397                                 ret = false;
5398                                 break;
5399                 }
5400                 switch (r.in.level) {
5401                 case 1:
5402                 case 4:
5403                         if (info->general.num_users < r.in.start_idx) {
5404                                 torture_warning(tctx, "QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
5405                                        r.in.start_idx, info->general.num_groups,
5406                                        info->general.domain_name.string);
5407                                 ret = false;
5408                         }
5409                         if (!seen_testuser) {
5410                                 struct policy_handle user_handle;
5411                                 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, tctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
5412                                         torture_warning(tctx, "Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
5413                                                info->general.domain_name.string);
5414                                         ret = false;
5415                                         test_samr_handle_Close(p, tctx, &user_handle);
5416                                 }
5417                         }
5418                         break;
5419                 case 3:
5420                 case 5:
5421                         if (info->general.num_groups != r.in.start_idx) {
5422                                 torture_warning(tctx, "QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
5423                                        r.in.start_idx, info->general.num_groups,
5424                                        info->general.domain_name.string);
5425                                 ret = false;
5426                         }
5427
5428                         break;
5429                 }
5430
5431         }
5432
5433         return ret;
5434 }
5435
5436 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p,
5437                                    struct torture_context *tctx,
5438                                    struct policy_handle *handle)
5439 {
5440         NTSTATUS status;
5441         struct samr_QueryDisplayInfo2 r;
5442         bool ret = true;
5443         uint16_t levels[] = {1, 2, 3, 4, 5};
5444         int i;
5445         uint32_t total_size;
5446         uint32_t returned_size;
5447         union samr_DispInfo info;
5448
5449         for (i=0;i<ARRAY_SIZE(levels);i++) {
5450                 torture_comment(tctx, "Testing QueryDisplayInfo2 level %u\n", levels[i]);
5451
5452                 r.in.domain_handle = handle;
5453                 r.in.level = levels[i];
5454                 r.in.start_idx = 0;
5455                 r.in.max_entries = 1000;
5456                 r.in.buf_size = (uint32_t)-1;
5457                 r.out.total_size = &total_size;
5458                 r.out.returned_size = &returned_size;
5459                 r.out.info = &info;
5460
5461                 status = dcerpc_samr_QueryDisplayInfo2(p, tctx, &r);
5462                 if (!NT_STATUS_IS_OK(status)) {
5463                         torture_warning(tctx, "QueryDisplayInfo2 level %u failed - %s\n",
5464                                levels[i], nt_errstr(status));
5465                         ret = false;
5466                 }
5467         }
5468
5469         return ret;
5470 }
5471
5472 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context *tctx,
5473                                   struct policy_handle *handle)
5474 {
5475         NTSTATUS status;
5476         struct samr_QueryDisplayInfo3 r;
5477         bool ret = true;
5478         uint16_t levels[] = {1, 2, 3, 4, 5};
5479         int i;
5480         uint32_t total_size;
5481         uint32_t returned_size;
5482         union samr_DispInfo info;
5483
5484         for (i=0;i<ARRAY_SIZE(levels);i++) {
5485                 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
5486
5487                 r.in.domain_handle = handle;
5488                 r.in.level = levels[i];
5489                 r.in.start_idx = 0;
5490                 r.in.max_entries = 1000;
5491                 r.in.buf_size = (uint32_t)-1;
5492                 r.out.total_size = &total_size;
5493                 r.out.returned_size = &returned_size;
5494                 r.out.info = &info;
5495
5496                 status = dcerpc_samr_QueryDisplayInfo3(p, tctx, &r);
5497                 if (!NT_STATUS_IS_OK(status)) {
5498                         torture_warning(tctx, "QueryDisplayInfo3 level %u failed - %s\n",
5499                                levels[i], nt_errstr(status));
5500                         ret = false;
5501                 }
5502         }
5503
5504         return ret;
5505 }
5506
5507
5508 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p,
5509                                            struct torture_context *tctx,
5510                                            struct policy_handle *handle)
5511 {
5512         NTSTATUS status;
5513         struct samr_QueryDisplayInfo r;
5514         bool ret = true;
5515         uint32_t total_size;
5516         uint32_t returned_size;
5517         union samr_DispInfo info;
5518
5519         torture_comment(tctx, "Testing QueryDisplayInfo continuation\n");
5520
5521         r.in.domain_handle = handle;
5522         r.in.level = 1;
5523         r.in.start_idx = 0;
5524         r.in.max_entries = 1;
5525         r.in.buf_size = (uint32_t)-1;
5526         r.out.total_size = &total_size;
5527         r.out.returned_size = &returned_size;
5528         r.out.info = &info;
5529
5530         do {
5531                 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &r);
5532                 if (NT_STATUS_IS_OK(status) && *r.out.returned_size != 0) {
5533                         if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
5534                                 torture_warning(tctx, "expected idx %d but got %d\n",
5535                                        r.in.start_idx + 1,
5536                                        r.out.info->info1.entries[0].idx);
5537                                 break;
5538                         }
5539                 }
5540                 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
5541                     !NT_STATUS_IS_OK(status)) {
5542                         torture_warning(tctx, "QueryDisplayInfo level %u failed - %s\n",
5543                                r.in.level, nt_errstr(status));
5544                         ret = false;
5545                         break;
5546                 }
5547                 r.in.start_idx++;
5548         } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
5549                   NT_STATUS_IS_OK(status)) &&
5550                  *r.out.returned_size != 0);
5551
5552         return ret;
5553 }
5554
5555 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
5556                                  struct policy_handle *handle)
5557 {
5558         NTSTATUS status;
5559         struct samr_QueryDomainInfo r;
5560         union samr_DomainInfo *info = NULL;
5561         struct samr_SetDomainInfo s;
5562         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5563         uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1,  0,  1,  0};
5564         int i;
5565         bool ret = true;
5566         const char *domain_comment = talloc_asprintf(tctx,
5567                                   "Tortured by Samba4 RPC-SAMR: %s",
5568                                   timestring(tctx, time(NULL)));
5569
5570         s.in.domain_handle = handle;
5571         s.in.level = 4;
5572         s.in.info = talloc(tctx, union samr_DomainInfo);
5573
5574         s.in.info->oem.oem_information.string = domain_comment;
5575         status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5576         if (!NT_STATUS_IS_OK(status)) {
5577                 torture_warning(tctx, "SetDomainInfo level %u (set comment) failed - %s\n",
5578                        s.in.level, nt_errstr(status));
5579                 return false;
5580         }
5581
5582         for (i=0;i<ARRAY_SIZE(levels);i++) {
5583                 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
5584
5585                 r.in.domain_handle = handle;
5586                 r.in.level = levels[i];
5587                 r.out.info = &info;
5588
5589                 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
5590                 if (!NT_STATUS_IS_OK(status)) {
5591                         torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
5592                                r.in.level, nt_errstr(status));
5593                         ret = false;
5594                         continue;
5595                 }
5596
5597                 switch (levels[i]) {
5598                 case 2:
5599                         if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
5600                                 torture_warning(tctx, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
5601                                        levels[i], info->general.oem_information.string, domain_comment);
5602                                 if (!torture_setting_bool(tctx, "samba3", false)) {
5603                                         ret = false;
5604                                 }
5605                         }
5606                         if (!info->general.primary.string) {
5607                                 torture_warning(tctx, "QueryDomainInfo level %u returned no PDC name\n",
5608                                        levels[i]);
5609                                 ret = false;
5610                         } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
5611                                 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
5612                                         torture_warning(tctx, "QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
5613                                                levels[i], info->general.primary.string, dcerpc_server_name(p));
5614                                 }
5615                         }
5616                         break;
5617                 case 4:
5618                         if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
5619                                 torture_warning(tctx, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
5620                                        levels[i], info->oem.oem_information.string, domain_comment);
5621                                 if (!torture_setting_bool(tctx, "samba3", false)) {
5622                                         ret = false;
5623                                 }
5624                         }
5625                         break;
5626                 case 6:
5627                         if (!info->info6.primary.string) {
5628                                 torture_warning(tctx, "QueryDomainInfo level %u returned no PDC name\n",
5629                                        levels[i]);
5630                                 ret = false;
5631                         }
5632                         break;
5633                 case 11:
5634                         if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
5635                                 torture_warning(tctx, "QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
5636                                        levels[i], info->general2.general.oem_information.string, domain_comment);
5637                                 if (!torture_setting_bool(tctx, "samba3", false)) {
5638                                         ret = false;
5639                                 }
5640                         }
5641                         break;
5642                 }
5643
5644                 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
5645
5646                 s.in.domain_handle = handle;
5647                 s.in.level = levels[i];
5648                 s.in.info = info;
5649
5650                 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5651                 if (set_ok[i]) {
5652                         if (!NT_STATUS_IS_OK(status)) {
5653                                 torture_warning(tctx, "SetDomainInfo level %u failed - %s\n",
5654                                        r.in.level, nt_errstr(status));
5655                                 ret = false;
5656                                 continue;
5657                         }
5658                 } else {
5659                         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
5660                                 torture_warning(tctx, "SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
5661                                        r.in.level, nt_errstr(status));
5662                                 ret = false;
5663                                 continue;
5664                         }
5665                 }
5666
5667                 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
5668                 if (!NT_STATUS_IS_OK(status)) {
5669                         torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
5670                                r.in.level, nt_errstr(status));
5671                         ret = false;
5672                         continue;
5673                 }
5674         }
5675
5676         return ret;
5677 }
5678
5679
5680 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context *tctx,
5681                                   struct policy_handle *handle)
5682 {
5683         NTSTATUS status;
5684         struct samr_QueryDomainInfo2 r;
5685         union samr_DomainInfo *info = NULL;
5686         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5687         int i;
5688         bool ret = true;
5689
5690         for (i=0;i<ARRAY_SIZE(levels);i++) {
5691                 torture_comment(tctx, "Testing QueryDomainInfo2 level %u\n", levels[i]);
5692
5693                 r.in.domain_handle = handle;
5694                 r.in.level = levels[i];
5695                 r.out.info = &info;
5696
5697                 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
5698                 if (!NT_STATUS_IS_OK(status)) {
5699                         torture_warning(tctx, "QueryDomainInfo2 level %u failed - %s\n",
5700                                r.in.level, nt_errstr(status));
5701                         ret = false;
5702                         continue;
5703                 }
5704         }
5705
5706         return true;
5707 }
5708
5709 /* Test whether querydispinfo level 5 and enumdomgroups return the same
5710    set of group names. */
5711 static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
5712                            struct policy_handle *handle)
5713 {
5714         struct samr_EnumDomainGroups q1;
5715         struct samr_QueryDisplayInfo q2;
5716         NTSTATUS status;
5717         uint32_t resume_handle=0;
5718         struct samr_SamArray *sam = NULL;
5719         uint32_t num_entries = 0;
5720         int i;
5721         bool ret = true;
5722         uint32_t total_size;
5723         uint32_t returned_size;
5724         union samr_DispInfo info;
5725
5726         int num_names = 0;
5727         const char **names = NULL;
5728
5729         torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
5730
5731         q1.in.domain_handle = handle;
5732         q1.in.resume_handle = &resume_handle;
5733         q1.in.max_size = 5;
5734         q1.out.resume_handle = &resume_handle;
5735         q1.out.num_entries = &num_entries;
5736         q1.out.sam = &sam;
5737
5738         status = STATUS_MORE_ENTRIES;
5739         while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5740                 status = dcerpc_samr_EnumDomainGroups(p, tctx, &q1);
5741
5742                 if (!NT_STATUS_IS_OK(status) &&
5743                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
5744                         break;
5745
5746                 for (i=0; i<*q1.out.num_entries; i++) {
5747                         add_string_to_array(tctx,
5748                                             sam->entries[i].name.string,
5749                                             &names, &num_names);
5750                 }
5751         }
5752
5753         torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
5754
5755         torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
5756
5757         q2.in.domain_handle = handle;
5758         q2.in.level = 5;
5759         q2.in.start_idx = 0;
5760         q2.in.max_entries = 5;
5761         q2.in.buf_size = (uint32_t)-1;
5762         q2.out.total_size = &total_size;
5763         q2.out.returned_size = &returned_size;
5764         q2.out.info = &info;
5765
5766         status = STATUS_MORE_ENTRIES;
5767         while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5768                 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &q2);
5769
5770                 if (!NT_STATUS_IS_OK(status) &&
5771                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
5772                         break;
5773
5774                 for (i=0; i<q2.out.info->info5.count; i++) {
5775                         int j;
5776                         const char *name = q2.out.info->info5.entries[i].account_name.string;
5777                         bool found = false;
5778                         for (j=0; j<num_names; j++) {
5779                                 if (names[j] == NULL)
5780                                         continue;
5781                                 if (strequal(names[j], name)) {
5782                                         names[j] = NULL;
5783                                         found = true;
5784                                         break;
5785                                 }
5786                         }
5787
5788                         if (!found) {
5789                                 torture_warning(tctx, "QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
5790                                        name);
5791                                 ret = false;
5792                         }
5793                 }
5794                 q2.in.start_idx += q2.out.info->info5.count;
5795         }
5796
5797         if (!NT_STATUS_IS_OK(status)) {
5798                 torture_warning(tctx, "QueryDisplayInfo level 5 failed - %s\n",
5799                        nt_errstr(status));
5800                 ret = false;
5801         }
5802
5803         for (i=0; i<num_names; i++) {
5804                 if (names[i] != NULL) {
5805                         torture_warning(tctx, "EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
5806                                names[i]);
5807                         ret = false;
5808                 }
5809         }
5810
5811         return ret;
5812 }
5813
5814 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, struct torture_context *tctx,
5815                                    struct policy_handle *group_handle)
5816 {
5817         struct samr_DeleteDomainGroup d;
5818         NTSTATUS status;
5819
5820         torture_comment(tctx, "Testing DeleteDomainGroup\n");
5821
5822         d.in.group_handle = group_handle;
5823         d.out.group_handle = group_handle;
5824
5825         status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
5826         torture_assert_ntstatus_ok(tctx, status, "DeleteDomainGroup");
5827
5828         return true;
5829 }
5830
5831 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5832                                             struct policy_handle *domain_handle)
5833 {
5834         struct samr_TestPrivateFunctionsDomain r;
5835         NTSTATUS status;
5836         bool ret = true;
5837
5838         torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
5839
5840         r.in.domain_handle = domain_handle;
5841
5842         status = dcerpc_samr_TestPrivateFunctionsDomain(p, tctx, &r);
5843         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsDomain");
5844
5845         return ret;
5846 }
5847
5848 static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
5849                           struct dom_sid *domain_sid,
5850                           struct policy_handle *domain_handle)
5851 {
5852         struct samr_RidToSid r;
5853         NTSTATUS status;
5854         bool ret = true;
5855         struct dom_sid *calc_sid, *out_sid;
5856         int rids[] = { 0, 42, 512, 10200 };
5857         int i;
5858
5859         for (i=0;i<ARRAY_SIZE(rids);i++) {
5860                 torture_comment(tctx, "Testing RidToSid\n");
5861
5862                 calc_sid = dom_sid_dup(tctx, domain_sid);
5863                 r.in.domain_handle = domain_handle;
5864                 r.in.rid = rids[i];
5865                 r.out.sid = &out_sid;
5866
5867                 status = dcerpc_samr_RidToSid(p, tctx, &r);
5868                 if (!NT_STATUS_IS_OK(status)) {
5869                         torture_warning(tctx, "RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
5870                         ret = false;
5871                 } else {
5872                         calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
5873
5874                         if (!dom_sid_equal(calc_sid, out_sid)) {
5875                                 torture_warning(tctx, "RidToSid for %d failed - got %s, expected %s\n", rids[i],
5876                                        dom_sid_string(tctx, out_sid),
5877                                        dom_sid_string(tctx, calc_sid));
5878                                 ret = false;
5879                         }
5880                 }
5881         }
5882
5883         return ret;
5884 }
5885
5886 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, struct torture_context *tctx,
5887                                        struct policy_handle *domain_handle)
5888 {
5889         struct samr_GetBootKeyInformation r;
5890         NTSTATUS status;
5891         bool ret = true;
5892         uint32_t unknown = 0;
5893
5894         torture_comment(tctx, "Testing GetBootKeyInformation\n");
5895
5896         r.in.domain_handle = domain_handle;
5897         r.out.unknown = &unknown;
5898
5899         status = dcerpc_samr_GetBootKeyInformation(p, tctx, &r);
5900         if (!NT_STATUS_IS_OK(status)) {
5901                 /* w2k3 seems to fail this sometimes and pass it sometimes */
5902                 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
5903         }
5904
5905         return ret;
5906 }
5907
5908 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx,
5909                                 struct policy_handle *domain_handle,
5910                                 struct policy_handle *group_handle)
5911 {
5912         NTSTATUS status;
5913         struct samr_AddGroupMember r;
5914         struct samr_DeleteGroupMember d;
5915         struct samr_QueryGroupMember q;
5916         struct samr_RidTypeArray *rids = NULL;
5917         struct samr_SetMemberAttributesOfGroup s;
5918         uint32_t rid;
5919         bool found_member = false;
5920         int i;
5921
5922         status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
5923         torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
5924
5925         r.in.group_handle = group_handle;
5926         r.in.rid = rid;
5927         r.in.flags = 0; /* ??? */
5928
5929         torture_comment(tctx, "Testing AddGroupMember, QueryGroupMember and DeleteGroupMember\n");
5930
5931         d.in.group_handle = group_handle;
5932         d.in.rid = rid;
5933
5934         status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
5935         torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, status, "DeleteGroupMember");
5936
5937         status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5938         torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
5939
5940         status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5941         torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, status, "AddGroupMember");
5942
5943         if (torture_setting_bool(tctx, "samba4", false) ||
5944             torture_setting_bool(tctx, "samba3", false)) {
5945                 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba\n");
5946         } else {
5947                 /* this one is quite strange. I am using random inputs in the
5948                    hope of triggering an error that might give us a clue */
5949
5950                 s.in.group_handle = group_handle;
5951                 s.in.unknown1 = random();
5952                 s.in.unknown2 = random();
5953
5954                 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
5955                 torture_assert_ntstatus_ok(tctx, status, "SetMemberAttributesOfGroup");
5956         }
5957
5958         q.in.group_handle = group_handle;
5959         q.out.rids = &rids;
5960
5961         status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
5962         torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
5963         torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
5964
5965         for (i=0; i < rids->count; i++) {
5966                 if (rids->rids[i] == rid) {
5967                         found_member = true;
5968                 }
5969         }
5970
5971         torture_assert(tctx, found_member, "QueryGroupMember did not list newly added member");
5972
5973         status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
5974         torture_assert_ntstatus_ok(tctx, status, "DeleteGroupMember");
5975
5976         rids = NULL;
5977         found_member = false;
5978
5979         status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
5980         torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
5981         torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
5982
5983         for (i=0; i < rids->count; i++) {
5984                 if (rids->rids[i] == rid) {
5985                         found_member = true;
5986                 }
5987         }
5988
5989         torture_assert(tctx, !found_member, "QueryGroupMember does still list removed member");
5990
5991         status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5992         torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
5993
5994         return true;
5995 }
5996
5997
5998 static bool test_CreateDomainGroup(struct dcerpc_pipe *p,
5999                                    struct torture_context *tctx,
6000                                    struct policy_handle *domain_handle,
6001                                    const char *group_name,
6002                                    struct policy_handle *group_handle,
6003                                    struct dom_sid *domain_sid,
6004                                    bool test_group)
6005 {
6006         NTSTATUS status;
6007         struct samr_CreateDomainGroup r;
6008         uint32_t rid;
6009         struct lsa_String name;
6010         bool ret = true;
6011
6012         init_lsa_String(&name, group_name);
6013
6014         r.in.domain_handle = domain_handle;
6015         r.in.name = &name;
6016         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6017         r.out.group_handle = group_handle;
6018         r.out.rid = &rid;
6019
6020         torture_comment(tctx, "Testing CreateDomainGroup(%s)\n", r.in.name->string);
6021
6022         status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
6023
6024         if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
6025                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6026                         torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
6027                         return true;
6028                 } else {
6029                         torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.name->string,
6030                                nt_errstr(status));
6031                         return false;
6032                 }
6033         }
6034
6035         if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
6036                 if (!test_DeleteGroup_byname(p, tctx, domain_handle, r.in.name->string)) {
6037                         torture_warning(tctx, "CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
6038                                nt_errstr(status));
6039                         return false;
6040                 }
6041                 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
6042         }
6043         if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
6044                 if (!test_DeleteUser_byname(p, tctx, domain_handle, r.in.name->string)) {
6045
6046                         torture_warning(tctx, "CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
6047                                nt_errstr(status));
6048                         return false;
6049                 }
6050                 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
6051         }
6052         torture_assert_ntstatus_ok(tctx, status, "CreateDomainGroup");
6053
6054         if (!test_group) {
6055                 return ret;
6056         }
6057
6058         if (!test_AddGroupMember(p, tctx, domain_handle, group_handle)) {
6059                 torture_warning(tctx, "CreateDomainGroup failed - %s\n", nt_errstr(status));
6060                 ret = false;
6061         }
6062
6063         if (!test_SetGroupInfo(p, tctx, group_handle)) {
6064                 ret = false;
6065         }
6066
6067         return ret;
6068 }
6069
6070
6071 /*
6072   its not totally clear what this does. It seems to accept any sid you like.
6073 */
6074 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
6075                                                struct torture_context *tctx,
6076                                                struct policy_handle *domain_handle)
6077 {
6078         NTSTATUS status;
6079         struct samr_RemoveMemberFromForeignDomain r;
6080
6081         r.in.domain_handle = domain_handle;
6082         r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
6083
6084         status = dcerpc_samr_RemoveMemberFromForeignDomain(p, tctx, &r);
6085         torture_assert_ntstatus_ok(tctx, status, "RemoveMemberFromForeignDomain");
6086
6087         return true;
6088 }
6089
6090 static bool test_EnumDomainUsers(struct dcerpc_pipe *p,
6091                                  struct torture_context *tctx,
6092                                  struct policy_handle *domain_handle,
6093                                  uint32_t *total_num_entries_p)
6094 {
6095         NTSTATUS status;
6096         struct samr_EnumDomainUsers r;
6097         uint32_t resume_handle = 0;
6098         uint32_t num_entries = 0;
6099         uint32_t total_num_entries = 0;
6100         struct samr_SamArray *sam;
6101
6102         r.in.domain_handle = domain_handle;
6103         r.in.acct_flags = 0;
6104         r.in.max_size = (uint32_t)-1;
6105         r.in.resume_handle = &resume_handle;
6106
6107         r.out.sam = &sam;
6108         r.out.num_entries = &num_entries;
6109         r.out.resume_handle = &resume_handle;
6110
6111         torture_comment(tctx, "Testing EnumDomainUsers\n");
6112
6113         do {
6114                 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
6115                 if (NT_STATUS_IS_ERR(status)) {
6116                         torture_assert_ntstatus_ok(tctx, status,
6117                                 "failed to enumerate users");
6118                 }
6119
6120                 total_num_entries += num_entries;
6121         } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
6122
6123         if (total_num_entries_p) {
6124                 *total_num_entries_p = total_num_entries;
6125         }
6126
6127         return true;
6128 }
6129
6130 static bool test_EnumDomainGroups(struct dcerpc_pipe *p,
6131                                   struct torture_context *tctx,
6132                                   struct policy_handle *domain_handle,
6133                                   uint32_t *total_num_entries_p)
6134 {
6135         NTSTATUS status;
6136         struct samr_EnumDomainGroups r;
6137         uint32_t resume_handle = 0;
6138         uint32_t num_entries = 0;
6139         uint32_t total_num_entries = 0;
6140         struct samr_SamArray *sam;
6141
6142         r.in.domain_handle = domain_handle;
6143         r.in.max_size = (uint32_t)-1;
6144         r.in.resume_handle = &resume_handle;
6145
6146         r.out.sam = &sam;
6147         r.out.num_entries = &num_entries;
6148         r.out.resume_handle = &resume_handle;
6149
6150         torture_comment(tctx, "Testing EnumDomainGroups\n");
6151
6152         do {
6153                 status = dcerpc_samr_EnumDomainGroups(p, tctx, &r);
6154                 if (NT_STATUS_IS_ERR(status)) {
6155                         torture_assert_ntstatus_ok(tctx, status,
6156                                 "failed to enumerate groups");
6157                 }
6158
6159                 total_num_entries += num_entries;
6160         } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
6161
6162         if (total_num_entries_p) {
6163                 *total_num_entries_p = total_num_entries;
6164         }
6165
6166         return true;
6167 }
6168
6169 static bool test_EnumDomainAliases(struct dcerpc_pipe *p,
6170                                    struct torture_context *tctx,
6171                                    struct policy_handle *domain_handle,
6172                                    uint32_t *total_num_entries_p)
6173 {
6174         NTSTATUS status;
6175         struct samr_EnumDomainAliases r;
6176         uint32_t resume_handle = 0;
6177         uint32_t num_entries = 0;
6178         uint32_t total_num_entries = 0;
6179         struct samr_SamArray *sam;
6180
6181         r.in.domain_handle = domain_handle;
6182         r.in.max_size = (uint32_t)-1;
6183         r.in.resume_handle = &resume_handle;
6184
6185         r.out.sam = &sam;
6186         r.out.num_entries = &num_entries;
6187         r.out.resume_handle = &resume_handle;
6188
6189         torture_comment(tctx, "Testing EnumDomainAliases\n");
6190
6191         do {
6192                 status = dcerpc_samr_EnumDomainAliases(p, tctx, &r);
6193                 if (NT_STATUS_IS_ERR(status)) {
6194                         torture_assert_ntstatus_ok(tctx, status,
6195                                 "failed to enumerate aliases");
6196                 }
6197
6198                 total_num_entries += num_entries;
6199         } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
6200
6201         if (total_num_entries_p) {
6202                 *total_num_entries_p = total_num_entries;
6203         }
6204
6205         return true;
6206 }
6207
6208 static bool test_QueryDisplayInfo_level(struct dcerpc_pipe *p,
6209                                         struct torture_context *tctx,
6210                                         struct policy_handle *handle,
6211                                         uint16_t level,
6212                                         uint32_t *total_num_entries_p)
6213 {
6214         NTSTATUS status;
6215         struct samr_QueryDisplayInfo r;
6216         uint32_t total_num_entries = 0;
6217
6218         r.in.domain_handle = handle;
6219         r.in.level = level;
6220         r.in.start_idx = 0;
6221         r.in.max_entries = (uint32_t)-1;
6222         r.in.buf_size = (uint32_t)-1;
6223
6224         torture_comment(tctx, "Testing QueryDisplayInfo\n");
6225
6226         do {
6227                 uint32_t total_size;
6228                 uint32_t returned_size;
6229                 union samr_DispInfo info;
6230
6231                 r.out.total_size = &total_size;
6232                 r.out.returned_size = &returned_size;
6233                 r.out.info = &info;
6234
6235                 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &r);
6236                 if (NT_STATUS_IS_ERR(status)) {
6237                         torture_assert_ntstatus_ok(tctx, status,
6238                                 "failed to query displayinfo");
6239                 }
6240
6241                 if (*r.out.returned_size == 0) {
6242                         break;
6243                 }
6244
6245                 switch (r.in.level) {
6246                 case 1:
6247                         total_num_entries += info.info1.count;
6248                         r.in.start_idx += info.info1.entries[info.info1.count - 1].idx + 1;
6249                         break;
6250                 case 2:
6251                         total_num_entries += info.info2.count;
6252                         r.in.start_idx += info.info2.entries[info.info2.count - 1].idx + 1;
6253                         break;
6254                 case 3:
6255                         total_num_entries += info.info3.count;
6256                         r.in.start_idx += info.info3.entries[info.info3.count - 1].idx + 1;
6257                         break;
6258                 case 4:
6259                         total_num_entries += info.info4.count;
6260                         r.in.start_idx += info.info4.entries[info.info4.count - 1].idx + 1;
6261                         break;
6262                 case 5:
6263                         total_num_entries += info.info5.count;
6264                         r.in.start_idx += info.info5.entries[info.info5.count - 1].idx + 1;
6265                         break;
6266                 default:
6267                         return false;
6268                 }
6269
6270         } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
6271
6272         if (total_num_entries_p) {
6273                 *total_num_entries_p = total_num_entries;
6274         }
6275
6276         return true;
6277 }
6278
6279 static bool test_ManyObjects(struct dcerpc_pipe *p,
6280                              struct torture_context *tctx,
6281                              struct policy_handle *domain_handle,
6282                              struct dom_sid *domain_sid,
6283                              struct torture_samr_context *ctx)
6284 {
6285         uint32_t num_total = ctx->num_objects_large_dc;
6286         uint32_t num_enum = 0;
6287         uint32_t num_disp = 0;
6288         uint32_t num_created = 0;
6289         uint32_t num_anounced = 0;
6290         bool ret = true;
6291         NTSTATUS status;
6292         uint32_t i;
6293
6294         struct policy_handle *handles = talloc_zero_array(tctx, struct policy_handle, num_total);
6295
6296         /* query */
6297
6298         {
6299                 struct samr_QueryDomainInfo2 r;
6300                 union samr_DomainInfo *info;
6301                 r.in.domain_handle = domain_handle;
6302                 r.in.level = 2;
6303                 r.out.info = &info;
6304
6305                 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
6306                 torture_assert_ntstatus_ok(tctx, status,
6307                         "failed to query domain info");
6308
6309                 switch (ctx->choice) {
6310                 case TORTURE_SAMR_MANY_ACCOUNTS:
6311                         num_anounced = info->general.num_users;
6312                         break;
6313                 case TORTURE_SAMR_MANY_GROUPS:
6314                         num_anounced = info->general.num_groups;
6315                         break;
6316                 case TORTURE_SAMR_MANY_ALIASES:
6317                         num_anounced = info->general.num_aliases;
6318                         break;
6319                 default:
6320                         return false;
6321                 }
6322         }
6323
6324         /* create */
6325
6326         for (i=0; i < num_total; i++) {
6327
6328                 const char *name = NULL;
6329
6330                 switch (ctx->choice) {
6331                 case TORTURE_SAMR_MANY_ACCOUNTS:
6332                         name = talloc_asprintf(tctx, "%s%04d", TEST_ACCOUNT_NAME, i);
6333                         ret &= test_CreateUser(p, tctx, domain_handle, name, &handles[i], domain_sid, 0, NULL, false);
6334                         break;
6335                 case TORTURE_SAMR_MANY_GROUPS:
6336                         name = talloc_asprintf(tctx, "%s%04d", TEST_GROUPNAME, i);
6337                         ret &= test_CreateDomainGroup(p, tctx, domain_handle, name, &handles[i], domain_sid, false);
6338                         break;
6339                 case TORTURE_SAMR_MANY_ALIASES:
6340                         name = talloc_asprintf(tctx, "%s%04d", TEST_ALIASNAME, i);
6341                         ret &= test_CreateAlias(p, tctx, domain_handle, name, &handles[i], domain_sid, false);
6342                         break;
6343                 default:
6344                         return false;
6345                 }
6346                 if (!policy_handle_empty(&handles[i])) {
6347                         num_created++;
6348                 }
6349         }
6350
6351         /* enum */
6352
6353         switch (ctx->choice) {
6354         case TORTURE_SAMR_MANY_ACCOUNTS:
6355                 ret &= test_EnumDomainUsers(p, tctx, domain_handle, &num_enum);
6356                 break;
6357         case TORTURE_SAMR_MANY_GROUPS:
6358                 ret &= test_EnumDomainGroups(p, tctx, domain_handle, &num_enum);
6359                 break;
6360         case TORTURE_SAMR_MANY_ALIASES:
6361                 ret &= test_EnumDomainAliases(p, tctx, domain_handle, &num_enum);
6362                 break;
6363         default:
6364                 return false;
6365         }
6366
6367         /* dispinfo */
6368
6369         switch (ctx->choice) {
6370         case TORTURE_SAMR_MANY_ACCOUNTS:
6371                 ret &= test_QueryDisplayInfo_level(p, tctx, domain_handle, 1, &num_disp);
6372                 break;
6373         case TORTURE_SAMR_MANY_GROUPS:
6374                 ret &= test_QueryDisplayInfo_level(p, tctx, domain_handle, 3, &num_disp);
6375                 break;
6376         case TORTURE_SAMR_MANY_ALIASES:
6377                 /* no aliases in dispinfo */
6378                 break;
6379         default:
6380                 return false;
6381         }
6382
6383         /* close or delete */
6384
6385         for (i=0; i < num_total; i++) {
6386
6387                 if (policy_handle_empty(&handles[i])) {
6388                         continue;
6389                 }
6390
6391                 if (torture_setting_bool(tctx, "samba3", false)) {
6392                         ret &= test_samr_handle_Close(p, tctx, &handles[i]);
6393                 } else {
6394                         switch (ctx->choice) {
6395                         case TORTURE_SAMR_MANY_ACCOUNTS:
6396                                 ret &= test_DeleteUser(p, tctx, &handles[i]);
6397                                 break;
6398                         case TORTURE_SAMR_MANY_GROUPS:
6399                                 ret &= test_DeleteDomainGroup(p, tctx, &handles[i]);
6400                                 break;
6401                         case TORTURE_SAMR_MANY_ALIASES:
6402                                 ret &= test_DeleteAlias(p, tctx, &handles[i]);
6403                                 break;
6404                         default:
6405                                 return false;
6406                         }
6407                 }
6408         }
6409
6410         talloc_free(handles);
6411
6412         if (ctx->choice == TORTURE_SAMR_MANY_ACCOUNTS && num_enum != num_anounced + num_created) {
6413                 torture_comment(tctx,
6414                                 "unexpected number of results (%u) returned in enum call, expected %u\n",
6415                                 num_enum, num_anounced + num_created);
6416
6417                 torture_comment(tctx,
6418                                 "unexpected number of results (%u) returned in dispinfo, call, expected %u\n",
6419                                 num_disp, num_anounced + num_created);
6420         }
6421         return ret;
6422 }
6423
6424 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
6425                          struct policy_handle *handle);
6426
6427 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
6428                             struct torture_samr_context *ctx, struct dom_sid *sid)
6429 {
6430         NTSTATUS status;
6431         struct samr_OpenDomain r;
6432         struct policy_handle domain_handle;
6433         struct policy_handle alias_handle;
6434         struct policy_handle user_handle;
6435         struct policy_handle group_handle;
6436         bool ret = true;
6437
6438         ZERO_STRUCT(alias_handle);
6439         ZERO_STRUCT(user_handle);
6440         ZERO_STRUCT(group_handle);
6441         ZERO_STRUCT(domain_handle);
6442
6443         torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
6444
6445         r.in.connect_handle = &ctx->handle;
6446         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6447         r.in.sid = sid;
6448         r.out.domain_handle = &domain_handle;
6449
6450         status = dcerpc_samr_OpenDomain(p, tctx, &r);
6451         torture_assert_ntstatus_ok(tctx, status, "OpenDomain");
6452
6453         /* run the domain tests with the main handle closed - this tests
6454            the servers reference counting */
6455         torture_assert(tctx, test_samr_handle_Close(p, tctx, &ctx->handle), "Failed to close SAMR handle");
6456
6457         switch (ctx->choice) {
6458         case TORTURE_SAMR_PASSWORDS:
6459         case TORTURE_SAMR_USER_PRIVILEGES:
6460                 if (!torture_setting_bool(tctx, "samba3", false)) {
6461                         ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, NULL);
6462                 }
6463                 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
6464                 if (!ret) {
6465                         torture_warning(tctx, "Testing PASSWORDS or PRIVILEGES on domain %s failed!\n", dom_sid_string(tctx, sid));
6466                 }
6467                 break;
6468         case TORTURE_SAMR_USER_ATTRIBUTES:
6469                 if (!torture_setting_bool(tctx, "samba3", false)) {
6470                         ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, NULL);
6471                 }
6472                 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
6473                 /* This test needs 'complex' users to validate */
6474                 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
6475                 if (!ret) {
6476                         torture_warning(tctx, "Testing ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
6477                 }
6478                 break;
6479         case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
6480                 if (!torture_setting_bool(tctx, "samba3", false)) {
6481                         ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, ctx->machine_credentials);
6482                 }
6483                 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, ctx->machine_credentials, true);
6484                 if (!ret) {
6485                         torture_warning(tctx, "Testing PASSWORDS PWDLASTSET on domain %s failed!\n", dom_sid_string(tctx, sid));
6486                 }
6487                 break;
6488         case TORTURE_SAMR_MANY_ACCOUNTS:
6489         case TORTURE_SAMR_MANY_GROUPS:
6490         case TORTURE_SAMR_MANY_ALIASES:
6491                 ret &= test_ManyObjects(p, tctx, &domain_handle, sid, ctx);
6492                 if (!ret) {
6493                         torture_warning(tctx, "Testing MANY-{ACCOUNTS,GROUPS,ALIASES} on domain %s failed!\n", dom_sid_string(tctx, sid));
6494                 }
6495                 break;
6496         case TORTURE_SAMR_OTHER:
6497                 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
6498                 if (!ret) {
6499                         torture_warning(tctx, "Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
6500                 }
6501                 if (!torture_setting_bool(tctx, "samba3", false)) {
6502                         ret &= test_QuerySecurity(p, tctx, &domain_handle);
6503                 }
6504                 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
6505                 ret &= test_CreateAlias(p, tctx, &domain_handle, TEST_ALIASNAME, &alias_handle, sid, true);
6506                 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, TEST_GROUPNAME, &group_handle, sid, true);
6507                 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
6508                 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
6509                 ret &= test_EnumDomainUsers_all(p, tctx, &domain_handle);
6510                 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
6511                 ret &= test_EnumDomainGroups_all(p, tctx, &domain_handle);
6512                 ret &= test_EnumDomainAliases_all(p, tctx, &domain_handle);
6513                 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
6514                 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
6515                 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
6516
6517                 if (torture_setting_bool(tctx, "samba4", false)) {
6518                         torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
6519                 } else {
6520                         ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
6521                         ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
6522                 }
6523                 ret &= test_GroupList(p, tctx, &domain_handle);
6524                 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
6525                 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
6526                 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
6527                 if (!ret) {
6528                         torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
6529                 }
6530                 break;
6531         }
6532
6533         if (!policy_handle_empty(&user_handle) &&
6534             !test_DeleteUser(p, tctx, &user_handle)) {
6535                 ret = false;
6536         }
6537
6538         if (!policy_handle_empty(&alias_handle) &&
6539             !test_DeleteAlias(p, tctx, &alias_handle)) {
6540                 ret = false;
6541         }
6542
6543         if (!policy_handle_empty(&group_handle) &&
6544             !test_DeleteDomainGroup(p, tctx, &group_handle)) {
6545                 ret = false;
6546         }
6547
6548         torture_assert(tctx, test_samr_handle_Close(p, tctx, &domain_handle), "Failed to close SAMR domain handle");
6549
6550         torture_assert(tctx, test_Connect(p, tctx, &ctx->handle), "Faile to re-connect SAMR handle");
6551         /* reconnect the main handle */
6552
6553         if (!ret) {
6554                 torture_warning(tctx, "Testing domain %s failed!\n", dom_sid_string(tctx, sid));
6555         }
6556
6557         return ret;
6558 }
6559
6560 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
6561                               struct torture_samr_context *ctx, const char *domain)
6562 {
6563         NTSTATUS status;
6564         struct samr_LookupDomain r;
6565         struct dom_sid2 *sid = NULL;
6566         struct lsa_String n1;
6567         struct lsa_String n2;
6568         bool ret = true;
6569
6570         torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
6571
6572         /* check for correct error codes */
6573         r.in.connect_handle = &ctx->handle;
6574         r.in.domain_name = &n2;
6575         r.out.sid = &sid;
6576         n2.string = NULL;
6577
6578         status = dcerpc_samr_LookupDomain(p, tctx, &r);
6579         torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, status, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
6580
6581         init_lsa_String(&n2, "xxNODOMAINxx");
6582
6583         status = dcerpc_samr_LookupDomain(p, tctx, &r);
6584         torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, status, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
6585
6586         r.in.connect_handle = &ctx->handle;
6587
6588         init_lsa_String(&n1, domain);
6589         r.in.domain_name = &n1;
6590
6591         status = dcerpc_samr_LookupDomain(p, tctx, &r);
6592         torture_assert_ntstatus_ok(tctx, status, "LookupDomain");
6593
6594         if (!test_GetDomPwInfo(p, tctx, &n1)) {
6595                 ret = false;
6596         }
6597
6598         if (!test_OpenDomain(p, tctx, ctx, *r.out.sid)) {
6599                 ret = false;
6600         }
6601
6602         return ret;
6603 }
6604
6605
6606 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
6607                              struct torture_samr_context *ctx)
6608 {
6609         NTSTATUS status;
6610         struct samr_EnumDomains r;
6611         uint32_t resume_handle = 0;
6612         uint32_t num_entries = 0;
6613         struct samr_SamArray *sam = NULL;
6614         int i;
6615         bool ret = true;
6616
6617         r.in.connect_handle = &ctx->handle;
6618         r.in.resume_handle = &resume_handle;
6619         r.in.buf_size = (uint32_t)-1;
6620         r.out.resume_handle = &resume_handle;
6621         r.out.num_entries = &num_entries;
6622         r.out.sam = &sam;
6623
6624         status = dcerpc_samr_EnumDomains(p, tctx, &r);
6625         torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
6626
6627         if (!*r.out.sam) {
6628                 return false;
6629         }
6630
6631         for (i=0;i<sam->count;i++) {
6632                 if (!test_LookupDomain(p, tctx, ctx,
6633                                        sam->entries[i].name.string)) {
6634                         ret = false;
6635                 }
6636         }
6637
6638         status = dcerpc_samr_EnumDomains(p, tctx, &r);
6639         torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
6640
6641         return ret;
6642 }
6643
6644
6645 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
6646                          struct policy_handle *handle)
6647 {
6648         NTSTATUS status;
6649         struct samr_Connect r;
6650         struct samr_Connect2 r2;
6651         struct samr_Connect3 r3;
6652         struct samr_Connect4 r4;
6653         struct samr_Connect5 r5;
6654         union samr_ConnectInfo info;
6655         struct policy_handle h;
6656         uint32_t level_out = 0;
6657         bool ret = true, got_handle = false;
6658
6659         torture_comment(tctx, "testing samr_Connect\n");
6660
6661         r.in.system_name = 0;
6662         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6663         r.out.connect_handle = &h;
6664
6665         status = dcerpc_samr_Connect(p, tctx, &r);
6666         if (!NT_STATUS_IS_OK(status)) {
6667                 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(status));
6668                 ret = false;
6669         } else {
6670                 got_handle = true;
6671                 *handle = h;
6672         }
6673
6674         torture_comment(tctx, "testing samr_Connect2\n");
6675
6676         r2.in.system_name = NULL;
6677         r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6678         r2.out.connect_handle = &h;
6679
6680         status = dcerpc_samr_Connect2(p, tctx, &r2);
6681         if (!NT_STATUS_IS_OK(status)) {
6682                 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(status));
6683                 ret = false;
6684         } else {
6685                 if (got_handle) {
6686                         test_samr_handle_Close(p, tctx, handle);
6687                 }
6688                 got_handle = true;
6689                 *handle = h;
6690         }
6691
6692         torture_comment(tctx, "testing samr_Connect3\n");
6693
6694         r3.in.system_name = NULL;
6695         r3.in.unknown = 0;
6696         r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6697         r3.out.connect_handle = &h;
6698
6699         status = dcerpc_samr_Connect3(p, tctx, &r3);
6700         if (!NT_STATUS_IS_OK(status)) {
6701                 torture_warning(tctx, "Connect3 failed - %s\n", nt_errstr(status));
6702                 ret = false;
6703         } else {
6704                 if (got_handle) {
6705                         test_samr_handle_Close(p, tctx, handle);
6706                 }
6707                 got_handle = true;
6708                 *handle = h;
6709         }
6710
6711         torture_comment(tctx, "testing samr_Connect4\n");
6712
6713         r4.in.system_name = "";
6714         r4.in.client_version = 0;
6715         r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6716         r4.out.connect_handle = &h;
6717
6718         status = dcerpc_samr_Connect4(p, tctx, &r4);
6719         if (!NT_STATUS_IS_OK(status)) {
6720                 torture_warning(tctx, "Connect4 failed - %s\n", nt_errstr(status));
6721                 ret = false;
6722         } else {
6723                 if (got_handle) {
6724                         test_samr_handle_Close(p, tctx, handle);
6725                 }
6726                 got_handle = true;
6727                 *handle = h;
6728         }
6729
6730         torture_comment(tctx, "testing samr_Connect5\n");
6731
6732         info.info1.client_version = 0;
6733         info.info1.unknown2 = 0;
6734
6735         r5.in.system_name = "";
6736         r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6737         r5.in.level_in = 1;
6738         r5.out.level_out = &level_out;
6739         r5.in.info_in = &info;
6740         r5.out.info_out = &info;
6741         r5.out.connect_handle = &h;
6742
6743         status = dcerpc_samr_Connect5(p, tctx, &r5);
6744         if (!NT_STATUS_IS_OK(status)) {
6745                 torture_warning(tctx, "Connect5 failed - %s\n", nt_errstr(status));
6746                 ret = false;
6747         } else {
6748                 if (got_handle) {
6749                         test_samr_handle_Close(p, tctx, handle);
6750                 }
6751                 got_handle = true;
6752                 *handle = h;
6753         }
6754
6755         return ret;
6756 }
6757
6758
6759 static bool test_samr_ValidatePassword(struct dcerpc_pipe *p, struct torture_context *tctx)
6760 {
6761         struct samr_ValidatePassword r;
6762         union samr_ValidatePasswordReq req;
6763         union samr_ValidatePasswordRep *repp = NULL;
6764         NTSTATUS status;
6765         const char *passwords[] = { "penguin", "p@ssw0rd", "p@ssw0rd123$", NULL };
6766         int i;
6767
6768         torture_comment(tctx, "testing samr_ValidatePassword\n");
6769
6770         ZERO_STRUCT(r);
6771         r.in.level = NetValidatePasswordReset;
6772         r.in.req = &req;
6773         r.out.rep = &repp;
6774
6775         ZERO_STRUCT(req);
6776         req.req3.account.string = "non-existant-account-aklsdji";
6777
6778         for (i=0; passwords[i]; i++) {
6779                 req.req3.password.string = passwords[i];
6780                 status = dcerpc_samr_ValidatePassword(p, tctx, &r);
6781                 torture_assert_ntstatus_ok(tctx, status, "samr_ValidatePassword");
6782                 torture_comment(tctx, "Server %s password '%s' with code %i\n",
6783                                 repp->ctr3.status==SAMR_VALIDATION_STATUS_SUCCESS?"allowed":"refused",
6784                                 req.req3.password.string, repp->ctr3.status);
6785         }
6786
6787         return true;
6788 }
6789
6790 bool torture_rpc_samr(struct torture_context *torture)
6791 {
6792         NTSTATUS status;
6793         struct dcerpc_pipe *p;
6794         bool ret = true;
6795         struct torture_samr_context *ctx;
6796
6797         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6798         if (!NT_STATUS_IS_OK(status)) {
6799                 return false;
6800         }
6801
6802         ctx = talloc_zero(torture, struct torture_samr_context);
6803
6804         ctx->choice = TORTURE_SAMR_OTHER;
6805
6806         ret &= test_Connect(p, torture, &ctx->handle);
6807
6808         if (!torture_setting_bool(torture, "samba3", false)) {
6809                 ret &= test_QuerySecurity(p, torture, &ctx->handle);
6810         }
6811
6812         ret &= test_EnumDomains(p, torture, ctx);
6813
6814         ret &= test_SetDsrmPassword(p, torture, &ctx->handle);
6815
6816         ret &= test_Shutdown(p, torture, &ctx->handle);
6817
6818         ret &= test_samr_handle_Close(p, torture, &ctx->handle);
6819
6820         return ret;
6821 }
6822
6823
6824 bool torture_rpc_samr_users(struct torture_context *torture)
6825 {
6826         NTSTATUS status;
6827         struct dcerpc_pipe *p;
6828         bool ret = true;
6829         struct torture_samr_context *ctx;
6830
6831         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6832         if (!NT_STATUS_IS_OK(status)) {
6833                 return false;
6834         }
6835
6836         ctx = talloc_zero(torture, struct torture_samr_context);
6837
6838         ctx->choice = TORTURE_SAMR_USER_ATTRIBUTES;
6839
6840         ret &= test_Connect(p, torture, &ctx->handle);
6841
6842         if (!torture_setting_bool(torture, "samba3", false)) {
6843                 ret &= test_QuerySecurity(p, torture, &ctx->handle);
6844         }
6845
6846         ret &= test_EnumDomains(p, torture, ctx);
6847
6848         ret &= test_SetDsrmPassword(p, torture, &ctx->handle);
6849
6850         ret &= test_Shutdown(p, torture, &ctx->handle);
6851
6852         ret &= test_samr_handle_Close(p, torture, &ctx->handle);
6853
6854         return ret;
6855 }
6856
6857
6858 bool torture_rpc_samr_passwords(struct torture_context *torture)
6859 {
6860         NTSTATUS status;
6861         struct dcerpc_pipe *p;
6862         bool ret = true;
6863         struct torture_samr_context *ctx;
6864
6865         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6866         if (!NT_STATUS_IS_OK(status)) {
6867                 return false;
6868         }
6869
6870         ctx = talloc_zero(torture, struct torture_samr_context);
6871
6872         ctx->choice = TORTURE_SAMR_PASSWORDS;
6873
6874         ret &= test_Connect(p, torture, &ctx->handle);
6875
6876         ret &= test_EnumDomains(p, torture, ctx);
6877
6878         ret &= test_samr_handle_Close(p, torture, &ctx->handle);
6879
6880         ret &= test_samr_ValidatePassword(p, torture);
6881
6882         return ret;
6883 }
6884
6885 static bool torture_rpc_samr_pwdlastset(struct torture_context *torture,
6886                                         struct dcerpc_pipe *p2,
6887                                         struct cli_credentials *machine_credentials)
6888 {
6889         NTSTATUS status;
6890         struct dcerpc_pipe *p;
6891         bool ret = true;
6892         struct torture_samr_context *ctx;
6893
6894         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6895         if (!NT_STATUS_IS_OK(status)) {
6896                 return false;
6897         }
6898
6899         ctx = talloc_zero(torture, struct torture_samr_context);
6900
6901         ctx->choice = TORTURE_SAMR_PASSWORDS_PWDLASTSET;
6902         ctx->machine_credentials = machine_credentials;
6903
6904         ret &= test_Connect(p, torture, &ctx->handle);
6905
6906         ret &= test_EnumDomains(p, torture, ctx);
6907
6908         ret &= test_samr_handle_Close(p, torture, &ctx->handle);
6909
6910         return ret;
6911 }
6912
6913 struct torture_suite *torture_rpc_samr_passwords_pwdlastset(TALLOC_CTX *mem_ctx)
6914 {
6915         struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-PASSWORDS-PWDLASTSET");
6916         struct torture_rpc_tcase *tcase;
6917
6918         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
6919                                                           &ndr_table_samr,
6920                                                           TEST_ACCOUNT_NAME_PWD);
6921
6922         torture_rpc_tcase_add_test_creds(tcase, "pwdLastSet",
6923                                          torture_rpc_samr_pwdlastset);
6924
6925         return suite;
6926 }
6927
6928 static bool torture_rpc_samr_users_privileges_delete_user(struct torture_context *torture,
6929                                                           struct dcerpc_pipe *p2,
6930                                                           struct cli_credentials *machine_credentials)
6931 {
6932         NTSTATUS status;
6933         struct dcerpc_pipe *p;
6934         bool ret = true;
6935         struct torture_samr_context *ctx;
6936
6937         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6938         if (!NT_STATUS_IS_OK(status)) {
6939                 return false;
6940         }
6941
6942         ctx = talloc_zero(torture, struct torture_samr_context);
6943
6944         ctx->choice = TORTURE_SAMR_USER_PRIVILEGES;
6945         ctx->machine_credentials = machine_credentials;
6946
6947         ret &= test_Connect(p, torture, &ctx->handle);
6948
6949         ret &= test_EnumDomains(p, torture, ctx);
6950
6951         ret &= test_samr_handle_Close(p, torture, &ctx->handle);
6952
6953         return ret;
6954 }
6955
6956 struct torture_suite *torture_rpc_samr_user_privileges(TALLOC_CTX *mem_ctx)
6957 {
6958         struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-USERS-PRIVILEGES");
6959         struct torture_rpc_tcase *tcase;
6960
6961         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
6962                                                           &ndr_table_samr,
6963                                                           TEST_ACCOUNT_NAME_PWD);
6964
6965         torture_rpc_tcase_add_test_creds(tcase, "delete_privileged_user",
6966                                          torture_rpc_samr_users_privileges_delete_user);
6967
6968         return suite;
6969 }
6970
6971 static bool torture_rpc_samr_many_accounts(struct torture_context *torture,
6972                                            struct dcerpc_pipe *p2,
6973                                            void *data)
6974 {
6975         NTSTATUS status;
6976         struct dcerpc_pipe *p;
6977         bool ret = true;
6978         struct torture_samr_context *ctx =
6979                 talloc_get_type_abort(data, struct torture_samr_context);
6980
6981         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6982         if (!NT_STATUS_IS_OK(status)) {
6983                 return false;
6984         }
6985
6986         ctx->choice = TORTURE_SAMR_MANY_ACCOUNTS;
6987         ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
6988                                                         ctx->num_objects_large_dc);
6989
6990         ret &= test_Connect(p, torture, &ctx->handle);
6991
6992         ret &= test_EnumDomains(p, torture, ctx);
6993
6994         ret &= test_samr_handle_Close(p, torture, &ctx->handle);
6995
6996         return ret;
6997 }
6998
6999 static bool torture_rpc_samr_many_groups(struct torture_context *torture,
7000                                          struct dcerpc_pipe *p2,
7001                                          void *data)
7002 {
7003         NTSTATUS status;
7004         struct dcerpc_pipe *p;
7005         bool ret = true;
7006         struct torture_samr_context *ctx =
7007                 talloc_get_type_abort(data, struct torture_samr_context);
7008
7009         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
7010         if (!NT_STATUS_IS_OK(status)) {
7011                 return false;
7012         }
7013
7014         ctx->choice = TORTURE_SAMR_MANY_GROUPS;
7015         ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
7016                                                         ctx->num_objects_large_dc);
7017
7018         ret &= test_Connect(p, torture, &ctx->handle);
7019
7020         ret &= test_EnumDomains(p, torture, ctx);
7021
7022         ret &= test_samr_handle_Close(p, torture, &ctx->handle);
7023
7024         return ret;
7025 }
7026
7027 static bool torture_rpc_samr_many_aliases(struct torture_context *torture,
7028                                           struct dcerpc_pipe *p2,
7029                                           void *data)
7030 {
7031         NTSTATUS status;
7032         struct dcerpc_pipe *p;
7033         bool ret = true;
7034         struct torture_samr_context *ctx =
7035                 talloc_get_type_abort(data, struct torture_samr_context);
7036
7037         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
7038         if (!NT_STATUS_IS_OK(status)) {
7039                 return false;
7040         }
7041
7042         ctx->choice = TORTURE_SAMR_MANY_ALIASES;
7043         ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
7044                                                         ctx->num_objects_large_dc);
7045
7046         ret &= test_Connect(p, torture, &ctx->handle);
7047
7048         ret &= test_EnumDomains(p, torture, ctx);
7049
7050         ret &= test_samr_handle_Close(p, torture, &ctx->handle);
7051
7052         return ret;
7053 }
7054
7055 struct torture_suite *torture_rpc_samr_large_dc(TALLOC_CTX *mem_ctx)
7056 {
7057         struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-LARGE-DC");
7058         struct torture_rpc_tcase *tcase;
7059         struct torture_samr_context *ctx;
7060
7061         tcase = torture_suite_add_rpc_iface_tcase(suite, "samr", &ndr_table_samr);
7062
7063         ctx = talloc_zero(suite, struct torture_samr_context);
7064         ctx->num_objects_large_dc = 150;
7065
7066         torture_rpc_tcase_add_test_ex(tcase, "many_aliases",
7067                                       torture_rpc_samr_many_aliases, ctx);
7068         torture_rpc_tcase_add_test_ex(tcase, "many_groups",
7069                                       torture_rpc_samr_many_groups, ctx);
7070         torture_rpc_tcase_add_test_ex(tcase, "many_accounts",
7071                                       torture_rpc_samr_many_accounts, ctx);
7072
7073         return suite;
7074 }