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