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