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