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