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