CVE-2013-4496:samr: Remove ChangePasswordUser
[mat/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         torture_comment(tctx, "\nTesting account lockout: %s\n", comment);
4107
4108         /* set policies */
4109
4110         info.info1 = *info1;
4111
4112         torture_comment(tctx, "setting password history length.\n");
4113         info.info1.password_history_length = password_history_length;
4114
4115         torture_assert(tctx,
4116                        test_SetDomainInfo(b, tctx, domain_handle,
4117                                           DomainPasswordInformation, &info),
4118                        "failed to set password history length");
4119
4120         info.info12 = *info12;
4121         info.info12.lockout_threshold = lockout_threshold;
4122
4123         /* set lockout duration < lockout window: should fail */
4124         info.info12.lockout_duration = ~(lockout_seconds * delta_time_factor);
4125         info.info12.lockout_window = ~((lockout_seconds + 1) * delta_time_factor);
4126
4127         torture_assert(tctx,
4128                 test_SetDomainInfo_ntstatus(b, tctx, domain_handle,
4129                                             DomainLockoutInformation, &info,
4130                                             NT_STATUS_INVALID_PARAMETER),
4131                 "setting lockout duration < lockout window gave unexpected result");
4132
4133         info.info12.lockout_duration = 0;
4134         info.info12.lockout_window = 0;
4135
4136         torture_assert(tctx,
4137                        test_SetDomainInfo(b, tctx, domain_handle,
4138                                           DomainLockoutInformation, &info),
4139                        "failed to set lockout window and duration to 0");
4140
4141
4142         /* set lockout duration of 5 seconds */
4143         info.info12.lockout_duration = ~(lockout_seconds * delta_time_factor);
4144         info.info12.lockout_window = ~(lockout_seconds * delta_time_factor);
4145
4146         torture_assert(tctx,
4147                        test_SetDomainInfo(b, tctx, domain_handle,
4148                                           DomainLockoutInformation, &info),
4149                        "failed to set lockout window and duration to 5 seconds");
4150
4151         /* reset bad pwd count */
4152
4153         torture_assert(tctx,
4154                 test_reset_badpwdcount(p, tctx, user_handle, acct_flags, password), "");
4155
4156
4157         /* enable or disable account */
4158
4159         if (disable) {
4160                 torture_assert(tctx,
4161                                test_SetUserInfo_acct_flags(b, tctx, user_handle,
4162                                                 acct_flags | ACB_DISABLED),
4163                                "failed to disable user");
4164         } else {
4165                 torture_assert(tctx,
4166                                test_SetUserInfo_acct_flags(b, tctx, user_handle,
4167                                                 acct_flags & ~ACB_DISABLED),
4168                                "failed to enable user");
4169         }
4170
4171
4172         /* test logon with right password */
4173
4174         if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4175                                       acct_name, *password,
4176                                       expected_success_status, interactive)) {
4177                 torture_fail(tctx, "failed to auth with latest password");
4178         }
4179
4180         torture_assert(tctx,
4181                 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4182         torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
4183
4184
4185         /* test with wrong password ==> lockout */
4186
4187         if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4188                                       acct_name, "random_crap",
4189                                       NT_STATUS_WRONG_PASSWORD, interactive)) {
4190                 torture_fail(tctx, "succeeded to authenticate with wrong password");
4191         }
4192
4193         torture_assert(tctx,
4194                 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4195         torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
4196
4197         torture_assert(tctx,
4198                 test_QueryUserInfo_acct_flags(b, tctx, user_handle, &acct_flags), "");
4199         torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
4200                                  "expected account to be locked");
4201
4202
4203         /* test with good password */
4204
4205         if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
4206                                      *password,
4207                                      NT_STATUS_ACCOUNT_LOCKED_OUT, interactive))
4208         {
4209                 torture_fail(tctx, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
4210         }
4211
4212         /* bad pwd count should not get updated */
4213         torture_assert(tctx,
4214                 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4215         torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
4216
4217         /* curiously, windows does _not_ set the autlock flag */
4218         torture_assert(tctx,
4219                 test_QueryUserInfo_acct_flags(b, tctx, user_handle, &acct_flags), "");
4220         torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
4221                                  "expected account to be locked");
4222
4223
4224         /* with bad password */
4225
4226         if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4227                                       acct_name, "random_crap2",
4228                                       NT_STATUS_ACCOUNT_LOCKED_OUT, interactive))
4229         {
4230                 torture_fail(tctx, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
4231         }
4232
4233         /* bad pwd count should not get updated */
4234         torture_assert(tctx,
4235                 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4236         torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
4237
4238         /* curiously, windows does _not_ set the autlock flag */
4239         torture_assert(tctx,
4240                 test_QueryUserInfo_acct_flags(b, tctx, user_handle, &acct_flags), "");
4241         torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
4242                                  "expected account to be locked");
4243
4244
4245         /* let lockout duration expire ==> unlock */
4246
4247         torture_comment(tctx, "let lockout duration expire...\n");
4248         sleep(lockout_seconds + 1);
4249
4250         if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
4251                                      *password,
4252                                      expected_success_status, interactive))
4253         {
4254                 torture_fail(tctx, "failed to authenticate after lockout expired");
4255         }
4256
4257         torture_assert(tctx,
4258                 test_QueryUserInfo_acct_flags(b, tctx, user_handle, &acct_flags), "");
4259         torture_assert_int_equal(tctx, acct_flags & ACB_AUTOLOCK, 0,
4260                                  "expected account not to be locked");
4261
4262         return true;
4263 }
4264
4265 static bool test_Password_lockout_wrap(struct dcerpc_pipe *p,
4266                                        struct torture_context *tctx,
4267                                        uint32_t acct_flags,
4268                                        const char *acct_name,
4269                                        struct policy_handle *domain_handle,
4270                                        struct policy_handle *user_handle,
4271                                        char **password,
4272                                        struct cli_credentials *machine_credentials)
4273 {
4274         union samr_DomainInfo *q_info, s_info;
4275         struct samr_DomInfo1 info1, _info1;
4276         struct samr_DomInfo12 info12, _info12;
4277         bool ret = true;
4278         struct dcerpc_binding_handle *b = p->binding_handle;
4279         struct dcerpc_pipe *np;
4280         int i;
4281
4282         struct {
4283                 const char *comment;
4284                 bool disabled;
4285                 bool interactive;
4286                 NTSTATUS expected_success_status;
4287         } creds[] = {
4288                 {
4289                         .comment                = "network logon (disabled account)",
4290                         .disabled               = true,
4291                         .interactive            = false,
4292                         .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4293                 },
4294                 {
4295                         .comment                = "network logon (enabled account)",
4296                         .disabled               = false,
4297                         .interactive            = false,
4298                         .expected_success_status= NT_STATUS_OK
4299                 },
4300                 {
4301                         .comment                = "interactive logon (disabled account)",
4302                         .disabled               = true,
4303                         .interactive            = true,
4304                         .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4305                 },
4306                 {
4307                         .comment                = "interactive logon (enabled account)",
4308                         .disabled               = false,
4309                         .interactive            = true,
4310                         .expected_success_status= NT_STATUS_OK
4311                 },
4312         };
4313
4314         torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
4315
4316         /* backup old policies */
4317
4318         torture_assert(tctx,
4319                 test_QueryDomainInfo2_level(b, tctx, domain_handle,
4320                                             DomainPasswordInformation, &q_info),
4321                 "failed to query domain info level 1");
4322
4323         info1 = q_info->info1;
4324         _info1 = info1;
4325
4326         torture_assert(tctx,
4327                 test_QueryDomainInfo2_level(b, tctx, domain_handle,
4328                                             DomainLockoutInformation, &q_info),
4329                 "failed to query domain info level 12");
4330
4331         info12 = q_info->info12;
4332         _info12 = info12;
4333
4334         /* run tests */
4335
4336         for (i=0; i < ARRAY_SIZE(creds); i++) {
4337
4338                 /* skip trust tests for now */
4339                 if (acct_flags & ACB_WSTRUST ||
4340                     acct_flags & ACB_SVRTRUST ||
4341                     acct_flags & ACB_DOMTRUST) {
4342                         continue;
4343                 }
4344
4345                 ret &= test_Password_lockout(p, np, tctx, acct_flags, acct_name,
4346                                              domain_handle, user_handle, password,
4347                                              machine_credentials,
4348                                              creds[i].comment,
4349                                              creds[i].disabled,
4350                                              creds[i].interactive,
4351                                              creds[i].expected_success_status,
4352                                              &_info1, &_info12);
4353                 if (!ret) {
4354                         torture_warning(tctx, "TEST #%d (%s) failed\n", i, creds[i].comment);
4355                 } else {
4356                         torture_comment(tctx, "TEST #%d (%s) succeeded\n", i, creds[i].comment);
4357                 }
4358         }
4359
4360         /* restore policies */
4361
4362         s_info.info1 = info1;
4363
4364         torture_assert(tctx,
4365                        test_SetDomainInfo(b, tctx, domain_handle,
4366                                           DomainPasswordInformation, &s_info),
4367                        "failed to set password information");
4368
4369         s_info.info12 = info12;
4370
4371         torture_assert(tctx,
4372                        test_SetDomainInfo(b, tctx, domain_handle,
4373                                           DomainLockoutInformation, &s_info),
4374                        "failed to set lockout information");
4375
4376         return ret;
4377 }
4378
4379 static bool test_DeleteUser_with_privs(struct dcerpc_pipe *p,
4380                                        struct dcerpc_pipe *lp,
4381                                        struct torture_context *tctx,
4382                                        struct policy_handle *domain_handle,
4383                                        struct policy_handle *lsa_handle,
4384                                        struct policy_handle *user_handle,
4385                                        const struct dom_sid *domain_sid,
4386                                        uint32_t rid,
4387                                        struct cli_credentials *machine_credentials)
4388 {
4389         bool ret = true;
4390         struct dcerpc_binding_handle *b = p->binding_handle;
4391         struct dcerpc_binding_handle *lb = lp->binding_handle;
4392
4393         struct policy_handle lsa_acct_handle;
4394         struct dom_sid *user_sid;
4395
4396         user_sid = dom_sid_add_rid(tctx, domain_sid, rid);
4397
4398         {
4399                 struct lsa_EnumAccountRights r;
4400                 struct lsa_RightSet rights;
4401
4402                 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4403
4404                 r.in.handle = lsa_handle;
4405                 r.in.sid = user_sid;
4406                 r.out.rights = &rights;
4407
4408                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4409                         "lsa_EnumAccountRights failed");
4410                 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4411                         "Expected enum rights for account to fail");
4412         }
4413
4414         {
4415                 struct lsa_RightSet rights;
4416                 struct lsa_StringLarge names[2];
4417                 struct lsa_AddAccountRights r;
4418
4419                 torture_comment(tctx, "Testing LSA AddAccountRights\n");
4420
4421                 init_lsa_StringLarge(&names[0], "SeMachineAccountPrivilege");
4422                 init_lsa_StringLarge(&names[1], NULL);
4423
4424                 rights.count = 1;
4425                 rights.names = names;
4426
4427                 r.in.handle = lsa_handle;
4428                 r.in.sid = user_sid;
4429                 r.in.rights = &rights;
4430
4431                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_AddAccountRights_r(lb, tctx, &r),
4432                         "lsa_AddAccountRights failed");
4433                 torture_assert_ntstatus_ok(tctx, r.out.result,
4434                         "Failed to add privileges");
4435         }
4436
4437         {
4438                 struct lsa_EnumAccounts r;
4439                 uint32_t resume_handle = 0;
4440                 struct lsa_SidArray lsa_sid_array;
4441                 int i;
4442                 bool found_sid = false;
4443
4444                 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4445
4446                 r.in.handle = lsa_handle;
4447                 r.in.num_entries = 0x1000;
4448                 r.in.resume_handle = &resume_handle;
4449                 r.out.sids = &lsa_sid_array;
4450                 r.out.resume_handle = &resume_handle;
4451
4452                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
4453                         "lsa_EnumAccounts failed");
4454                 torture_assert_ntstatus_ok(tctx, r.out.result,
4455                         "Failed to enum accounts");
4456
4457                 for (i=0; i < lsa_sid_array.num_sids; i++) {
4458                         if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
4459                                 found_sid = true;
4460                         }
4461                 }
4462
4463                 torture_assert(tctx, found_sid,
4464                         "failed to list privileged account");
4465         }
4466
4467         {
4468                 struct lsa_EnumAccountRights r;
4469                 struct lsa_RightSet user_rights;
4470
4471                 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4472
4473                 r.in.handle = lsa_handle;
4474                 r.in.sid = user_sid;
4475                 r.out.rights = &user_rights;
4476
4477                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4478                         "lsa_EnumAccountRights failed");
4479                 torture_assert_ntstatus_ok(tctx, r.out.result,
4480                         "Failed to enum rights for account");
4481
4482                 if (user_rights.count < 1) {
4483                         torture_warning(tctx, "failed to find newly added rights");
4484                         return false;
4485                 }
4486         }
4487
4488         {
4489                 struct lsa_OpenAccount r;
4490
4491                 torture_comment(tctx, "Testing LSA OpenAccount\n");
4492
4493                 r.in.handle = lsa_handle;
4494                 r.in.sid = user_sid;
4495                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4496                 r.out.acct_handle = &lsa_acct_handle;
4497
4498                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(lb, tctx, &r),
4499                         "lsa_OpenAccount failed");
4500                 torture_assert_ntstatus_ok(tctx, r.out.result,
4501                         "Failed to open lsa account");
4502         }
4503
4504         {
4505                 struct lsa_GetSystemAccessAccount r;
4506                 uint32_t access_mask;
4507
4508                 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
4509
4510                 r.in.handle = &lsa_acct_handle;
4511                 r.out.access_mask = &access_mask;
4512
4513                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetSystemAccessAccount_r(lb, tctx, &r),
4514                         "lsa_GetSystemAccessAccount failed");
4515                 torture_assert_ntstatus_ok(tctx, r.out.result,
4516                         "Failed to get lsa system access account");
4517         }
4518
4519         {
4520                 struct lsa_Close r;
4521
4522                 torture_comment(tctx, "Testing LSA Close\n");
4523
4524                 r.in.handle = &lsa_acct_handle;
4525                 r.out.handle = &lsa_acct_handle;
4526
4527                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Close_r(lb, tctx, &r),
4528                         "lsa_Close failed");
4529                 torture_assert_ntstatus_ok(tctx, r.out.result,
4530                         "Failed to close lsa");
4531         }
4532
4533         {
4534                 struct samr_DeleteUser r;
4535
4536                 torture_comment(tctx, "Testing SAMR DeleteUser\n");
4537
4538                 r.in.user_handle = user_handle;
4539                 r.out.user_handle = user_handle;
4540
4541                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &r),
4542                         "DeleteUser failed");
4543                 torture_assert_ntstatus_ok(tctx, r.out.result,
4544                         "DeleteUser failed");
4545         }
4546
4547         {
4548                 struct lsa_EnumAccounts r;
4549                 uint32_t resume_handle = 0;
4550                 struct lsa_SidArray lsa_sid_array;
4551                 int i;
4552                 bool found_sid = false;
4553
4554                 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4555
4556                 r.in.handle = lsa_handle;
4557                 r.in.num_entries = 0x1000;
4558                 r.in.resume_handle = &resume_handle;
4559                 r.out.sids = &lsa_sid_array;
4560                 r.out.resume_handle = &resume_handle;
4561
4562                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
4563                         "lsa_EnumAccounts failed");
4564                 torture_assert_ntstatus_ok(tctx, r.out.result,
4565                         "Failed to enum accounts");
4566
4567                 for (i=0; i < lsa_sid_array.num_sids; i++) {
4568                         if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
4569                                 found_sid = true;
4570                         }
4571                 }
4572
4573                 torture_assert(tctx, found_sid,
4574                         "failed to list privileged account");
4575         }
4576
4577         {
4578                 struct lsa_EnumAccountRights r;
4579                 struct lsa_RightSet user_rights;
4580
4581                 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4582
4583                 r.in.handle = lsa_handle;
4584                 r.in.sid = user_sid;
4585                 r.out.rights = &user_rights;
4586
4587                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4588                         "lsa_EnumAccountRights failed");
4589                 torture_assert_ntstatus_ok(tctx, r.out.result,
4590                         "Failed to enum rights for account");
4591
4592                 if (user_rights.count < 1) {
4593                         torture_warning(tctx, "failed to find newly added rights");
4594                         return false;
4595                 }
4596         }
4597
4598         {
4599                 struct lsa_OpenAccount r;
4600
4601                 torture_comment(tctx, "Testing LSA OpenAccount\n");
4602
4603                 r.in.handle = lsa_handle;
4604                 r.in.sid = user_sid;
4605                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4606                 r.out.acct_handle = &lsa_acct_handle;
4607
4608                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(lb, tctx, &r),
4609                         "lsa_OpenAccount failed");
4610                 torture_assert_ntstatus_ok(tctx, r.out.result,
4611                         "Failed to open lsa account");
4612         }
4613
4614         {
4615                 struct lsa_GetSystemAccessAccount r;
4616                 uint32_t access_mask;
4617
4618                 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
4619
4620                 r.in.handle = &lsa_acct_handle;
4621                 r.out.access_mask = &access_mask;
4622
4623                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetSystemAccessAccount_r(lb, tctx, &r),
4624                         "lsa_GetSystemAccessAccount failed");
4625                 torture_assert_ntstatus_ok(tctx, r.out.result,
4626                         "Failed to get lsa system access account");
4627         }
4628
4629         {
4630                 struct lsa_DeleteObject r;
4631
4632                 torture_comment(tctx, "Testing LSA DeleteObject\n");
4633
4634                 r.in.handle = &lsa_acct_handle;
4635                 r.out.handle = &lsa_acct_handle;
4636
4637                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_DeleteObject_r(lb, tctx, &r),
4638                         "lsa_DeleteObject failed");
4639                 torture_assert_ntstatus_ok(tctx, r.out.result,
4640                         "Failed to delete object");
4641         }
4642
4643         {
4644                 struct lsa_EnumAccounts r;
4645                 uint32_t resume_handle = 0;
4646                 struct lsa_SidArray lsa_sid_array;
4647                 int i;
4648                 bool found_sid = false;
4649
4650                 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4651
4652                 r.in.handle = lsa_handle;
4653                 r.in.num_entries = 0x1000;
4654                 r.in.resume_handle = &resume_handle;
4655                 r.out.sids = &lsa_sid_array;
4656                 r.out.resume_handle = &resume_handle;
4657
4658                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
4659                         "lsa_EnumAccounts failed");
4660                 torture_assert_ntstatus_ok(tctx, r.out.result,
4661                         "Failed to enum accounts");
4662
4663                 for (i=0; i < lsa_sid_array.num_sids; i++) {
4664                         if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
4665                                 found_sid = true;
4666                         }
4667                 }
4668
4669                 torture_assert(tctx, !found_sid,
4670                         "should not have listed privileged account");
4671         }
4672
4673         {
4674                 struct lsa_EnumAccountRights r;
4675                 struct lsa_RightSet user_rights;
4676
4677                 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4678
4679                 r.in.handle = lsa_handle;
4680                 r.in.sid = user_sid;
4681                 r.out.rights = &user_rights;
4682
4683                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4684                         "lsa_EnumAccountRights failed");
4685                 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4686                         "Failed to enum rights for account");
4687         }
4688
4689         return ret;
4690 }
4691
4692 static bool test_user_ops(struct dcerpc_pipe *p,
4693                           struct torture_context *tctx,
4694                           struct policy_handle *user_handle,
4695                           struct policy_handle *domain_handle,
4696                           const struct dom_sid *domain_sid,
4697                           uint32_t base_acct_flags,
4698                           const char *base_acct_name, enum torture_samr_choice which_ops,
4699                           struct cli_credentials *machine_credentials)
4700 {
4701         char *password = NULL;
4702         struct samr_QueryUserInfo q;
4703         union samr_UserInfo *info;
4704         NTSTATUS status;
4705         struct dcerpc_binding_handle *b = p->binding_handle;
4706
4707         bool ret = true;
4708         int i;
4709         uint32_t rid;
4710         const uint32_t password_fields[] = {
4711                 SAMR_FIELD_NT_PASSWORD_PRESENT,
4712                 SAMR_FIELD_LM_PASSWORD_PRESENT,
4713                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
4714                 0
4715         };
4716
4717         status = test_LookupName(b, tctx, domain_handle, base_acct_name, &rid);
4718         if (!NT_STATUS_IS_OK(status)) {
4719                 ret = false;
4720         }
4721
4722         switch (which_ops) {
4723         case TORTURE_SAMR_USER_ATTRIBUTES:
4724                 if (!test_QuerySecurity(b, tctx, user_handle)) {
4725                         ret = false;
4726                 }
4727
4728                 if (!test_QueryUserInfo(b, tctx, user_handle)) {
4729                         ret = false;
4730                 }
4731
4732                 if (!test_QueryUserInfo2(b, tctx, user_handle)) {
4733                         ret = false;
4734                 }
4735
4736                 if (!test_SetUserInfo(b, tctx, user_handle, base_acct_flags,
4737                                       base_acct_name)) {
4738                         ret = false;
4739                 }
4740
4741                 if (!test_GetUserPwInfo(b, tctx, user_handle)) {
4742                         ret = false;
4743                 }
4744
4745                 if (!test_TestPrivateFunctionsUser(b, tctx, user_handle)) {
4746                         ret = false;
4747                 }
4748
4749                 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
4750                         ret = false;
4751                 }
4752                 break;
4753         case TORTURE_SAMR_PASSWORDS:
4754                 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
4755                         char simple_pass[9];
4756                         char *v = generate_random_str(tctx, 1);
4757
4758                         ZERO_STRUCT(simple_pass);
4759                         memset(simple_pass, *v, sizeof(simple_pass) - 1);
4760
4761                         torture_comment(tctx, "Testing machine account password policy rules\n");
4762
4763                         /* Workstation trust accounts don't seem to need to honour password quality policy */
4764                         if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
4765                                 ret = false;
4766                         }
4767
4768                         if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
4769                                 ret = false;
4770                         }
4771
4772                         /* reset again, to allow another 'user' password change */
4773                         if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
4774                                 ret = false;
4775                         }
4776
4777                         /* Try a 'short' password */
4778                         if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
4779                                 ret = false;
4780                         }
4781
4782                         /* Try a compleatly random password */
4783                         if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
4784                                 ret = false;
4785                         }
4786                 }
4787
4788                 for (i = 0; password_fields[i]; i++) {
4789                         if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
4790                                 ret = false;
4791                         }
4792
4793                         /* check it was set right */
4794                         if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4795                                 ret = false;
4796                         }
4797                 }
4798
4799                 for (i = 0; password_fields[i]; i++) {
4800                         if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
4801                                 ret = false;
4802                         }
4803
4804                         /* check it was set right */
4805                         if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4806                                 ret = false;
4807                         }
4808                 }
4809
4810                 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
4811                         ret = false;
4812                 }
4813
4814                 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
4815                         ret = false;
4816                 }
4817
4818                 if (!test_SetUserPass_18(p, tctx, user_handle, &password)) {
4819                         ret = false;
4820                 }
4821
4822                 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4823                         ret = false;
4824                 }
4825
4826                 for (i = 0; password_fields[i]; i++) {
4827
4828                         if (password_fields[i] == SAMR_FIELD_LM_PASSWORD_PRESENT) {
4829                                 /* we need to skip as that would break
4830                                  * the ChangePasswordUser3 verify */
4831                                 continue;
4832                         }
4833
4834                         if (!test_SetUserPass_21(p, tctx, user_handle, password_fields[i], &password)) {
4835                                 ret = false;
4836                         }
4837
4838                         /* check it was set right */
4839                         if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
4840                                 ret = false;
4841                         }
4842                 }
4843
4844                 q.in.user_handle = user_handle;
4845                 q.in.level = 5;
4846                 q.out.info = &info;
4847
4848                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
4849                         "QueryUserInfo failed");
4850                 if (!NT_STATUS_IS_OK(q.out.result)) {
4851                         torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
4852                                q.in.level, nt_errstr(q.out.result));
4853                         ret = false;
4854                 } else {
4855                         uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
4856                         if ((info->info5.acct_flags) != expected_flags) {
4857                                 torture_warning(tctx, "QueryUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4858                                        info->info5.acct_flags,
4859                                        expected_flags);
4860                                 /* FIXME: GD */
4861                                 if (!torture_setting_bool(tctx, "samba3", false)) {
4862                                         ret = false;
4863                                 }
4864                         }
4865                         if (info->info5.rid != rid) {
4866                                 torture_warning(tctx, "QueryUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
4867                                        info->info5.rid, rid);
4868
4869                         }
4870                 }
4871
4872                 break;
4873
4874         case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
4875
4876                 /* test last password change timestamp behaviour */
4877                 if (!test_SetPassword_pwdlastset(p, tctx, base_acct_flags,
4878                                                  base_acct_name,
4879                                                  user_handle, &password,
4880                                                  machine_credentials)) {
4881                         ret = false;
4882                 }
4883
4884                 if (ret == true) {
4885                         torture_comment(tctx, "pwdLastSet test succeeded\n");
4886                 } else {
4887                         torture_warning(tctx, "pwdLastSet test failed\n");
4888                 }
4889
4890                 break;
4891
4892         case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT:
4893
4894                 /* test bad pwd count change behaviour */
4895                 if (!test_Password_badpwdcount_wrap(p, tctx, base_acct_flags,
4896                                                     base_acct_name,
4897                                                     domain_handle,
4898                                                     user_handle, &password,
4899                                                     machine_credentials)) {
4900                         ret = false;
4901                 }
4902
4903                 if (ret == true) {
4904                         torture_comment(tctx, "badPwdCount test succeeded\n");
4905                 } else {
4906                         torture_warning(tctx, "badPwdCount test failed\n");
4907                 }
4908
4909                 break;
4910
4911         case TORTURE_SAMR_PASSWORDS_LOCKOUT:
4912
4913                 if (!test_Password_lockout_wrap(p, tctx, base_acct_flags,
4914                                                 base_acct_name,
4915                                                 domain_handle,
4916                                                 user_handle, &password,
4917                                                 machine_credentials))
4918                 {
4919                         ret = false;
4920                 }
4921
4922                 if (ret == true) {
4923                         torture_comment(tctx, "lockout test succeeded\n");
4924                 } else {
4925                         torture_warning(tctx, "lockout test failed\n");
4926                 }
4927
4928                 break;
4929
4930
4931         case TORTURE_SAMR_USER_PRIVILEGES: {
4932
4933                 struct dcerpc_pipe *lp;
4934                 struct policy_handle *lsa_handle;
4935                 struct dcerpc_binding_handle *lb;
4936
4937                 status = torture_rpc_connection(tctx, &lp, &ndr_table_lsarpc);
4938                 torture_assert_ntstatus_ok(tctx, status, "Failed to open LSA pipe");
4939                 lb = lp->binding_handle;
4940
4941                 if (!test_lsa_OpenPolicy2(lb, tctx, &lsa_handle)) {
4942                         ret = false;
4943                 }
4944
4945                 if (!test_DeleteUser_with_privs(p, lp, tctx,
4946                                                 domain_handle, lsa_handle, user_handle,
4947                                                 domain_sid, rid,
4948                                                 machine_credentials)) {
4949                         ret = false;
4950                 }
4951
4952                 if (!test_lsa_Close(lb, tctx, lsa_handle)) {
4953                         ret = false;
4954                 }
4955
4956                 if (!ret) {
4957                         torture_warning(tctx, "privileged user delete test failed\n");
4958                 }
4959
4960                 break;
4961         }
4962         case TORTURE_SAMR_OTHER:
4963         case TORTURE_SAMR_MANY_ACCOUNTS:
4964         case TORTURE_SAMR_MANY_GROUPS:
4965         case TORTURE_SAMR_MANY_ALIASES:
4966                 /* We just need the account to exist */
4967                 break;
4968         }
4969         return ret;
4970 }
4971
4972 static bool test_alias_ops(struct dcerpc_binding_handle *b,
4973                            struct torture_context *tctx,
4974                            struct policy_handle *alias_handle,
4975                            const struct dom_sid *domain_sid)
4976 {
4977         bool ret = true;
4978
4979         if (!torture_setting_bool(tctx, "samba3", false)) {
4980                 if (!test_QuerySecurity(b, tctx, alias_handle)) {
4981                         ret = false;
4982                 }
4983         }
4984
4985         if (!test_QueryAliasInfo(b, tctx, alias_handle)) {
4986                 ret = false;
4987         }
4988
4989         if (!test_SetAliasInfo(b, tctx, alias_handle)) {
4990                 ret = false;
4991         }
4992
4993         if (!test_AddMemberToAlias(b, tctx, alias_handle, domain_sid)) {
4994                 ret = false;
4995         }
4996
4997         if (torture_setting_bool(tctx, "samba3", false) ||
4998             torture_setting_bool(tctx, "samba4", false)) {
4999                 torture_comment(tctx, "skipping MultipleMembers Alias tests against Samba\n");
5000                 return ret;
5001         }
5002
5003         if (!test_AddMultipleMembersToAlias(b, tctx, alias_handle)) {
5004                 ret = false;
5005         }
5006
5007         return ret;
5008 }
5009
5010
5011 static bool test_DeleteUser(struct dcerpc_binding_handle *b,
5012                             struct torture_context *tctx,
5013                             struct policy_handle *user_handle)
5014 {
5015         struct samr_DeleteUser d;
5016         torture_comment(tctx, "Testing DeleteUser\n");
5017
5018         d.in.user_handle = user_handle;
5019         d.out.user_handle = user_handle;
5020
5021         torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &d),
5022                 "DeleteUser failed");
5023         torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteUser");
5024
5025         return true;
5026 }
5027
5028 bool test_DeleteUser_byname(struct dcerpc_binding_handle *b,
5029                             struct torture_context *tctx,
5030                             struct policy_handle *handle, const char *name)
5031 {
5032         NTSTATUS status;
5033         struct samr_DeleteUser d;
5034         struct policy_handle user_handle;
5035         uint32_t rid;
5036
5037         status = test_LookupName(b, tctx, handle, name, &rid);
5038         if (!NT_STATUS_IS_OK(status)) {
5039                 goto failed;
5040         }
5041
5042         status = test_OpenUser_byname(b, tctx, handle, name, &user_handle);
5043         if (!NT_STATUS_IS_OK(status)) {
5044                 goto failed;
5045         }
5046
5047         d.in.user_handle = &user_handle;
5048         d.out.user_handle = &user_handle;
5049         torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &d),
5050                 "DeleteUser failed");
5051         if (!NT_STATUS_IS_OK(d.out.result)) {
5052                 status = d.out.result;
5053                 goto failed;
5054         }
5055
5056         return true;
5057
5058 failed:
5059         torture_warning(tctx, "DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
5060         return false;
5061 }
5062
5063
5064 static bool test_DeleteGroup_byname(struct dcerpc_binding_handle *b,
5065                                     struct torture_context *tctx,
5066                                     struct policy_handle *handle, const char *name)
5067 {
5068         NTSTATUS status;
5069         struct samr_OpenGroup r;
5070         struct samr_DeleteDomainGroup d;
5071         struct policy_handle group_handle;
5072         uint32_t rid;
5073
5074         status = test_LookupName(b, tctx, handle, name, &rid);
5075         if (!NT_STATUS_IS_OK(status)) {
5076                 goto failed;
5077         }
5078
5079         r.in.domain_handle = handle;
5080         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5081         r.in.rid = rid;
5082         r.out.group_handle = &group_handle;
5083         torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenGroup_r(b, tctx, &r),
5084                 "OpenGroup failed");
5085         if (!NT_STATUS_IS_OK(r.out.result)) {
5086                 status = r.out.result;
5087                 goto failed;
5088         }
5089
5090         d.in.group_handle = &group_handle;
5091         d.out.group_handle = &group_handle;
5092         torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomainGroup_r(b, tctx, &d),
5093                 "DeleteDomainGroup failed");
5094         if (!NT_STATUS_IS_OK(d.out.result)) {
5095                 status = d.out.result;
5096                 goto failed;
5097         }
5098
5099         return true;
5100
5101 failed:
5102         torture_warning(tctx, "DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
5103         return false;
5104 }
5105
5106
5107 static bool test_DeleteAlias_byname(struct dcerpc_binding_handle *b,
5108                                     struct torture_context *tctx,
5109                                     struct policy_handle *domain_handle,
5110                                     const char *name)
5111 {
5112         NTSTATUS status;
5113         struct samr_OpenAlias r;
5114         struct samr_DeleteDomAlias d;
5115         struct policy_handle alias_handle;
5116         uint32_t rid;
5117
5118         torture_comment(tctx, "Testing DeleteAlias_byname\n");
5119
5120         status = test_LookupName(b, tctx, domain_handle, name, &rid);
5121         if (!NT_STATUS_IS_OK(status)) {
5122                 goto failed;
5123         }
5124
5125         r.in.domain_handle = domain_handle;
5126         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5127         r.in.rid = rid;
5128         r.out.alias_handle = &alias_handle;
5129         torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenAlias_r(b, tctx, &r),
5130                 "OpenAlias failed");
5131         if (!NT_STATUS_IS_OK(r.out.result)) {
5132                 status = r.out.result;
5133                 goto failed;
5134         }
5135
5136         d.in.alias_handle = &alias_handle;
5137         d.out.alias_handle = &alias_handle;
5138         torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomAlias_r(b, tctx, &d),
5139                 "DeleteDomAlias failed");
5140         if (!NT_STATUS_IS_OK(d.out.result)) {
5141                 status = d.out.result;
5142                 goto failed;
5143         }
5144
5145         return true;
5146
5147 failed:
5148         torture_warning(tctx, "DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
5149         return false;
5150 }
5151
5152 static bool test_DeleteAlias(struct dcerpc_binding_handle *b,
5153                              struct torture_context *tctx,
5154                              struct policy_handle *alias_handle)
5155 {
5156         struct samr_DeleteDomAlias d;
5157         bool ret = true;
5158
5159         torture_comment(tctx, "Testing DeleteAlias\n");
5160
5161         d.in.alias_handle = alias_handle;
5162         d.out.alias_handle = alias_handle;
5163
5164         torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomAlias_r(b, tctx, &d),
5165                 "DeleteDomAlias failed");
5166         if (!NT_STATUS_IS_OK(d.out.result)) {
5167                 torture_warning(tctx, "DeleteAlias failed - %s\n", nt_errstr(d.out.result));
5168                 ret = false;
5169         }
5170
5171         return ret;
5172 }
5173
5174 static bool test_CreateAlias(struct dcerpc_binding_handle *b,
5175                              struct torture_context *tctx,
5176                              struct policy_handle *domain_handle,
5177                              const char *alias_name,
5178                              struct policy_handle *alias_handle,
5179                              const struct dom_sid *domain_sid,
5180                              bool test_alias)
5181 {
5182         struct samr_CreateDomAlias r;
5183         struct lsa_String name;
5184         uint32_t rid;
5185         bool ret = true;
5186
5187         init_lsa_String(&name, alias_name);
5188         r.in.domain_handle = domain_handle;
5189         r.in.alias_name = &name;
5190         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5191         r.out.alias_handle = alias_handle;
5192         r.out.rid = &rid;
5193
5194         torture_comment(tctx, "Testing CreateAlias (%s)\n", r.in.alias_name->string);
5195
5196         torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomAlias_r(b, tctx, &r),
5197                 "CreateDomAlias failed");
5198
5199         if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5200                 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED)) {
5201                         torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.alias_name->string);
5202                         return true;
5203                 } else {
5204                         torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
5205                                nt_errstr(r.out.result));
5206                         return false;
5207                 }
5208         }
5209
5210         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ALIAS_EXISTS)) {
5211                 if (!test_DeleteAlias_byname(b, tctx, domain_handle, r.in.alias_name->string)) {
5212                         return false;
5213                 }
5214                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomAlias_r(b, tctx, &r),
5215                         "CreateDomAlias failed");
5216         }
5217
5218         if (!NT_STATUS_IS_OK(r.out.result)) {
5219                 torture_warning(tctx, "CreateAlias failed - %s\n", nt_errstr(r.out.result));
5220                 return false;
5221         }
5222
5223         if (!test_alias) {
5224                 return ret;
5225         }
5226
5227         if (!test_alias_ops(b, tctx, alias_handle, domain_sid)) {
5228                 ret = false;
5229         }
5230
5231         return ret;
5232 }
5233
5234 static bool test_ChangePassword(struct dcerpc_pipe *p,
5235                                 struct torture_context *tctx,
5236                                 const char *acct_name,
5237                                 struct policy_handle *domain_handle, char **password)
5238 {
5239         bool ret = true;
5240         struct dcerpc_binding_handle *b = p->binding_handle;
5241
5242         if (!*password) {
5243                 return false;
5244         }
5245
5246         if (!test_ChangePasswordUser(b, tctx, acct_name, domain_handle, password)) {
5247                 ret = false;
5248         }
5249
5250         if (!test_ChangePasswordUser2(p, tctx, acct_name, password, 0, true)) {
5251                 ret = false;
5252         }
5253
5254         if (!test_OemChangePasswordUser2(p, tctx, acct_name, domain_handle, password)) {
5255                 ret = false;
5256         }
5257
5258         /* test what happens when setting the old password again */
5259         if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, *password, 0, true)) {
5260                 ret = false;
5261         }
5262
5263         {
5264                 char simple_pass[9];
5265                 char *v = generate_random_str(tctx, 1);
5266
5267                 ZERO_STRUCT(simple_pass);
5268                 memset(simple_pass, *v, sizeof(simple_pass) - 1);
5269
5270                 /* test what happens when picking a simple password */
5271                 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, simple_pass, 0, true)) {
5272                         ret = false;
5273                 }
5274         }
5275
5276         /* set samr_SetDomainInfo level 1 with min_length 5 */
5277         {
5278                 struct samr_QueryDomainInfo r;
5279                 union samr_DomainInfo *info = NULL;
5280                 struct samr_SetDomainInfo s;
5281                 uint16_t len_old, len;
5282                 uint32_t pwd_prop_old;
5283                 int64_t min_pwd_age_old;
5284
5285                 len = 5;
5286
5287                 r.in.domain_handle = domain_handle;
5288                 r.in.level = 1;
5289                 r.out.info = &info;
5290
5291                 torture_comment(tctx, "Testing samr_QueryDomainInfo level 1\n");
5292                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
5293                         "QueryDomainInfo failed");
5294                 if (!NT_STATUS_IS_OK(r.out.result)) {
5295                         return false;
5296                 }
5297
5298                 s.in.domain_handle = domain_handle;
5299                 s.in.level = 1;
5300                 s.in.info = info;
5301
5302                 /* remember the old min length, so we can reset it */
5303                 len_old = s.in.info->info1.min_password_length;
5304                 s.in.info->info1.min_password_length = len;
5305                 pwd_prop_old = s.in.info->info1.password_properties;
5306                 /* turn off password complexity checks for this test */
5307                 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
5308
5309                 min_pwd_age_old = s.in.info->info1.min_password_age;
5310                 s.in.info->info1.min_password_age = 0;
5311
5312                 torture_comment(tctx, "Testing samr_SetDomainInfo level 1\n");
5313                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
5314                         "SetDomainInfo failed");
5315                 if (!NT_STATUS_IS_OK(s.out.result)) {
5316                         return false;
5317                 }
5318
5319                 torture_comment(tctx, "calling test_ChangePasswordUser3 with too short password\n");
5320
5321                 if (!test_ChangePasswordUser3(p, tctx, acct_name, len - 1, password, NULL, 0, true)) {
5322                         ret = false;
5323                 }
5324
5325                 s.in.info->info1.min_password_length = len_old;
5326                 s.in.info->info1.password_properties = pwd_prop_old;
5327                 s.in.info->info1.min_password_age = min_pwd_age_old;
5328
5329                 torture_comment(tctx, "Testing samr_SetDomainInfo level 1\n");
5330                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
5331                         "SetDomainInfo failed");
5332                 if (!NT_STATUS_IS_OK(s.out.result)) {
5333                         return false;
5334                 }
5335
5336         }
5337
5338         {
5339                 struct samr_OpenUser r;
5340                 struct samr_QueryUserInfo q;
5341                 union samr_UserInfo *info;
5342                 struct samr_LookupNames n;
5343                 struct policy_handle user_handle;
5344                 struct samr_Ids rids, types;
5345
5346                 n.in.domain_handle = domain_handle;
5347                 n.in.num_names = 1;
5348                 n.in.names = talloc_array(tctx, struct lsa_String, 1);
5349                 n.in.names[0].string = acct_name;
5350                 n.out.rids = &rids;
5351                 n.out.types = &types;
5352
5353                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupNames_r(b, tctx, &n),
5354                         "LookupNames failed");
5355                 if (!NT_STATUS_IS_OK(n.out.result)) {
5356                         torture_warning(tctx, "LookupNames failed - %s\n", nt_errstr(n.out.result));
5357                         return false;
5358                 }
5359
5360                 r.in.domain_handle = domain_handle;
5361                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5362                 r.in.rid = n.out.rids->ids[0];
5363                 r.out.user_handle = &user_handle;
5364
5365                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
5366                         "OpenUser failed");
5367                 if (!NT_STATUS_IS_OK(r.out.result)) {
5368                         torture_warning(tctx, "OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(r.out.result));
5369                         return false;
5370                 }
5371
5372                 q.in.user_handle = &user_handle;
5373                 q.in.level = 5;
5374                 q.out.info = &info;
5375
5376                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
5377                         "QueryUserInfo failed");
5378                 if (!NT_STATUS_IS_OK(q.out.result)) {
5379                         torture_warning(tctx, "QueryUserInfo failed - %s\n", nt_errstr(q.out.result));
5380                         return false;
5381                 }
5382
5383                 torture_comment(tctx, "calling test_ChangePasswordUser3 with too early password change\n");
5384
5385                 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL,
5386                                               info->info5.last_password_change, true)) {
5387                         ret = false;
5388                 }
5389         }
5390
5391         /* we change passwords twice - this has the effect of verifying
5392            they were changed correctly for the final call */
5393         if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
5394                 ret = false;
5395         }
5396
5397         if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
5398                 ret = false;
5399         }
5400
5401         return ret;
5402 }
5403
5404 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
5405                             struct policy_handle *domain_handle,
5406                             const char *user_name,
5407                             struct policy_handle *user_handle_out,
5408                             struct dom_sid *domain_sid,
5409                             enum torture_samr_choice which_ops,
5410                             struct cli_credentials *machine_credentials,
5411                             bool test_user)
5412 {
5413
5414         TALLOC_CTX *user_ctx;
5415
5416         struct samr_CreateUser r;
5417         struct samr_QueryUserInfo q;
5418         union samr_UserInfo *info;
5419         struct samr_DeleteUser d;
5420         uint32_t rid;
5421
5422         /* This call creates a 'normal' account - check that it really does */
5423         const uint32_t acct_flags = ACB_NORMAL;
5424         struct lsa_String name;
5425         bool ret = true;
5426         struct dcerpc_binding_handle *b = p->binding_handle;
5427
5428         struct policy_handle user_handle;
5429         user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
5430         init_lsa_String(&name, user_name);
5431
5432         r.in.domain_handle = domain_handle;
5433         r.in.account_name = &name;
5434         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5435         r.out.user_handle = &user_handle;
5436         r.out.rid = &rid;
5437
5438         torture_comment(tctx, "Testing CreateUser(%s)\n", r.in.account_name->string);
5439
5440         torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser_r(b, user_ctx, &r),
5441                 "CreateUser failed");
5442
5443         if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5444                 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
5445                         torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
5446                         return true;
5447                 } else {
5448                         torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
5449                                nt_errstr(r.out.result));
5450                         return false;
5451                 }
5452         }
5453
5454         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
5455                 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.account_name->string)) {
5456                         talloc_free(user_ctx);
5457                         return false;
5458                 }
5459                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser_r(b, user_ctx, &r),
5460                         "CreateUser failed");
5461         }
5462
5463         if (!NT_STATUS_IS_OK(r.out.result)) {
5464                 talloc_free(user_ctx);
5465                 torture_warning(tctx, "CreateUser failed - %s\n", nt_errstr(r.out.result));
5466                 return false;
5467         }
5468
5469         if (!test_user) {
5470                 if (user_handle_out) {
5471                         *user_handle_out = user_handle;
5472                 }
5473                 return ret;
5474         }
5475
5476         {
5477                 q.in.user_handle = &user_handle;
5478                 q.in.level = 16;
5479                 q.out.info = &info;
5480
5481                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, user_ctx, &q),
5482                         "QueryUserInfo failed");
5483                 if (!NT_STATUS_IS_OK(q.out.result)) {
5484                         torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
5485                                q.in.level, nt_errstr(q.out.result));
5486                         ret = false;
5487                 } else {
5488                         if ((info->info16.acct_flags & acct_flags) != acct_flags) {
5489                                 torture_warning(tctx, "QueryUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5490                                        info->info16.acct_flags,
5491                                        acct_flags);
5492                                 ret = false;
5493                         }
5494                 }
5495
5496                 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
5497                                    domain_sid, acct_flags, name.string, which_ops,
5498                                    machine_credentials)) {
5499                         ret = false;
5500                 }
5501
5502                 if (user_handle_out) {
5503                         *user_handle_out = user_handle;
5504                 } else {
5505                         torture_comment(tctx, "Testing DeleteUser (createuser test)\n");
5506
5507                         d.in.user_handle = &user_handle;
5508                         d.out.user_handle = &user_handle;
5509
5510                         torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, user_ctx, &d),
5511                                 "DeleteUser failed");
5512                         if (!NT_STATUS_IS_OK(d.out.result)) {
5513                                 torture_warning(tctx, "DeleteUser failed - %s\n", nt_errstr(d.out.result));
5514                                 ret = false;
5515                         }
5516                 }
5517
5518         }
5519
5520         talloc_free(user_ctx);
5521
5522         return ret;
5523 }
5524
5525
5526 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
5527                              struct policy_handle *domain_handle,
5528                              struct dom_sid *domain_sid,
5529                              enum torture_samr_choice which_ops,
5530                              struct cli_credentials *machine_credentials)
5531 {
5532         struct samr_CreateUser2 r;
5533         struct samr_QueryUserInfo q;
5534         union samr_UserInfo *info;
5535         struct samr_DeleteUser d;
5536         struct policy_handle user_handle;
5537         uint32_t rid;
5538         struct lsa_String name;
5539         bool ret = true;
5540         int i;
5541         struct dcerpc_binding_handle *b = p->binding_handle;
5542
5543         struct {
5544                 uint32_t acct_flags;
5545                 const char *account_name;
5546                 NTSTATUS nt_status;
5547         } account_types[] = {
5548                 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
5549                 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5550                 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5551                 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
5552                 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5553                 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5554                 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
5555                 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5556                 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5557                 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_ACCESS_DENIED },
5558                 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
5559                 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
5560                 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5561                 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5562                 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
5563         };
5564
5565         for (i = 0; account_types[i].account_name; i++) {
5566                 TALLOC_CTX *user_ctx;
5567                 uint32_t acct_flags = account_types[i].acct_flags;
5568                 uint32_t access_granted;
5569                 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
5570                 init_lsa_String(&name, account_types[i].account_name);
5571
5572                 r.in.domain_handle = domain_handle;
5573                 r.in.account_name = &name;
5574                 r.in.acct_flags = acct_flags;
5575                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5576                 r.out.user_handle = &user_handle;
5577                 r.out.access_granted = &access_granted;
5578                 r.out.rid = &rid;
5579
5580                 torture_comment(tctx, "Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
5581
5582                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser2_r(b, user_ctx, &r),
5583                         "CreateUser2 failed");
5584
5585                 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5586                         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
5587                                 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
5588                                 continue;
5589                         } else {
5590                                 torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
5591                                        nt_errstr(r.out.result));
5592                                 ret = false;
5593                                 continue;
5594                         }
5595                 }
5596
5597                 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
5598                         if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.account_name->string)) {
5599                                 talloc_free(user_ctx);
5600                                 ret = false;
5601                                 continue;
5602                         }
5603                         torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser2_r(b, user_ctx, &r),
5604                                 "CreateUser2 failed");
5605
5606                 }
5607                 if (!NT_STATUS_EQUAL(r.out.result, account_types[i].nt_status)) {
5608                         torture_warning(tctx, "CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
5609                                nt_errstr(r.out.result), nt_errstr(account_types[i].nt_status));
5610                         ret = false;
5611                 }
5612
5613                 if (NT_STATUS_IS_OK(r.out.result)) {
5614                         q.in.user_handle = &user_handle;
5615                         q.in.level = 5;
5616                         q.out.info = &info;
5617
5618                         torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, user_ctx, &q),
5619                                 "QueryUserInfo failed");
5620                         if (!NT_STATUS_IS_OK(q.out.result)) {
5621                                 torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
5622                                        q.in.level, nt_errstr(q.out.result));
5623                                 ret = false;
5624                         } else {
5625                                 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
5626                                 if (acct_flags == ACB_NORMAL) {
5627                                         expected_flags |= ACB_PW_EXPIRED;
5628                                 }
5629                                 if ((info->info5.acct_flags) != expected_flags) {
5630                                         torture_warning(tctx, "QueryUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5631                                                info->info5.acct_flags,
5632                                                expected_flags);
5633                                         ret = false;
5634                                 }
5635                                 switch (acct_flags) {
5636                                 case ACB_SVRTRUST:
5637                                         if (info->info5.primary_gid != DOMAIN_RID_DCS) {
5638                                                 torture_warning(tctx, "QueryUserInfo level 5: DC should have had Primary Group %d, got %d\n",
5639                                                        DOMAIN_RID_DCS, info->info5.primary_gid);
5640                                                 ret = false;
5641                                         }
5642                                         break;
5643                                 case ACB_WSTRUST:
5644                                         if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
5645                                                 torture_warning(tctx, "QueryUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
5646                                                        DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
5647                                                 ret = false;
5648                                         }
5649                                         break;
5650                                 case ACB_NORMAL:
5651                                         if (info->info5.primary_gid != DOMAIN_RID_USERS) {
5652                                                 torture_warning(tctx, "QueryUserInfo level 5: Users should have had Primary Group %d, got %d\n",
5653                                                        DOMAIN_RID_USERS, info->info5.primary_gid);
5654                                                 ret = false;
5655                                         }
5656                                         break;
5657                                 }
5658                         }
5659
5660                         if (!test_user_ops(p, tctx, &user_handle, domain_handle,
5661                                            domain_sid, acct_flags, name.string, which_ops,
5662                                            machine_credentials)) {
5663                                 ret = false;
5664                         }
5665
5666                         if (!ndr_policy_handle_empty(&user_handle)) {
5667                                 torture_comment(tctx, "Testing DeleteUser (createuser2 test)\n");
5668
5669                                 d.in.user_handle = &user_handle;
5670                                 d.out.user_handle = &user_handle;
5671
5672                                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, user_ctx, &d),
5673                                         "DeleteUser failed");
5674                                 if (!NT_STATUS_IS_OK(d.out.result)) {
5675                                         torture_warning(tctx, "DeleteUser failed - %s\n", nt_errstr(d.out.result));
5676                                         ret = false;
5677                                 }
5678                         }
5679                 }
5680                 talloc_free(user_ctx);
5681         }
5682
5683         return ret;
5684 }
5685
5686 static bool test_QueryAliasInfo(struct dcerpc_binding_handle *b,
5687                                 struct torture_context *tctx,
5688                                 struct policy_handle *handle)
5689 {
5690         struct samr_QueryAliasInfo r;
5691         union samr_AliasInfo *info;
5692         uint16_t levels[] = {1, 2, 3};
5693         int i;
5694         bool ret = true;
5695
5696         for (i=0;i<ARRAY_SIZE(levels);i++) {
5697                 torture_comment(tctx, "Testing QueryAliasInfo level %u\n", levels[i]);
5698
5699                 r.in.alias_handle = handle;
5700                 r.in.level = levels[i];
5701                 r.out.info = &info;
5702
5703                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryAliasInfo_r(b, tctx, &r),
5704                         "QueryAliasInfo failed");
5705                 if (!NT_STATUS_IS_OK(r.out.result)) {
5706                         torture_warning(tctx, "QueryAliasInfo level %u failed - %s\n",
5707                                levels[i], nt_errstr(r.out.result));
5708                         ret = false;
5709                 }
5710         }
5711
5712         return ret;
5713 }
5714
5715 static bool test_QueryGroupInfo(struct dcerpc_binding_handle *b,
5716                                 struct torture_context *tctx,
5717                                 struct policy_handle *handle)
5718 {
5719         struct samr_QueryGroupInfo r;
5720         union samr_GroupInfo *info;
5721         uint16_t levels[] = {1, 2, 3, 4, 5};
5722         int i;
5723         bool ret = true;
5724
5725         for (i=0;i<ARRAY_SIZE(levels);i++) {
5726                 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
5727
5728                 r.in.group_handle = handle;
5729                 r.in.level = levels[i];
5730                 r.out.info = &info;
5731
5732                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupInfo_r(b, tctx, &r),
5733                         "QueryGroupInfo failed");
5734                 if (!NT_STATUS_IS_OK(r.out.result)) {
5735                         torture_warning(tctx, "QueryGroupInfo level %u failed - %s\n",
5736                                levels[i], nt_errstr(r.out.result));
5737                         ret = false;
5738                 }
5739         }
5740
5741         return ret;
5742 }
5743
5744 static bool test_QueryGroupMember(struct dcerpc_binding_handle *b,
5745                                   struct torture_context *tctx,
5746                                   struct policy_handle *handle)
5747 {
5748         struct samr_QueryGroupMember r;
5749         struct samr_RidAttrArray *rids = NULL;
5750         bool ret = true;
5751
5752         torture_comment(tctx, "Testing QueryGroupMember\n");
5753
5754         r.in.group_handle = handle;
5755         r.out.rids = &rids;
5756
5757         torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &r),
5758                 "QueryGroupMember failed");
5759         if (!NT_STATUS_IS_OK(r.out.result)) {
5760                 torture_warning(tctx, "QueryGroupMember failed - %s\n", nt_errstr(r.out.result));
5761                 ret = false;
5762         }
5763
5764         return ret;
5765 }
5766
5767
5768 static bool test_SetGroupInfo(struct dcerpc_binding_handle *b,
5769                               struct torture_context *tctx,
5770                               struct policy_handle *handle)
5771 {
5772         struct samr_QueryGroupInfo r;
5773         union samr_GroupInfo *info;
5774         struct samr_SetGroupInfo s;
5775         uint16_t levels[] = {1, 2, 3, 4};
5776         uint16_t set_ok[] = {0, 1, 1, 1};
5777         int i;
5778         bool ret = true;
5779
5780         for (i=0;i<ARRAY_SIZE(levels);i++) {
5781                 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
5782
5783                 r.in.group_handle = handle;
5784                 r.in.level = levels[i];
5785                 r.out.info = &info;
5786
5787                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupInfo_r(b, tctx, &r),
5788                         "QueryGroupInfo failed");
5789                 if (!NT_STATUS_IS_OK(r.out.result)) {
5790                         torture_warning(tctx, "QueryGroupInfo level %u failed - %s\n",
5791                                levels[i], nt_errstr(r.out.result));
5792                         ret = false;
5793                 }
5794
5795                 torture_comment(tctx, "Testing SetGroupInfo level %u\n", levels[i]);
5796
5797                 s.in.group_handle = handle;
5798                 s.in.level = levels[i];
5799                 s.in.info = *r.out.info;
5800
5801 #if 0
5802                 /* disabled this, as it changes the name only from the point of view of samr,
5803                    but leaves the name from the point of view of w2k3 internals (and ldap). This means
5804                    the name is still reserved, so creating the old name fails, but deleting by the old name
5805                    also fails */
5806                 if (s.in.level == 2) {
5807                         init_lsa_String(&s.in.info->string, "NewName");
5808                 }
5809 #endif
5810
5811                 if (s.in.level == 4) {
5812                         init_lsa_String(&s.in.info->description, "test description");
5813                 }
5814
5815                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetGroupInfo_r(b, tctx, &s),
5816                         "SetGroupInfo failed");
5817                 if (set_ok[i]) {
5818                         if (!NT_STATUS_IS_OK(s.out.result)) {
5819                                 torture_warning(tctx, "SetGroupInfo level %u failed - %s\n",
5820                                        r.in.level, nt_errstr(s.out.result));
5821                                 ret = false;
5822                                 continue;
5823                         }
5824                 } else {
5825                         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, s.out.result)) {
5826                                 torture_warning(tctx, "SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
5827                                        r.in.level, nt_errstr(s.out.result));
5828                                 ret = false;
5829                                 continue;
5830                         }
5831                 }
5832         }
5833
5834         return ret;
5835 }
5836
5837 static bool test_QueryUserInfo(struct dcerpc_binding_handle *b,
5838                                struct torture_context *tctx,
5839                                struct policy_handle *handle)
5840 {
5841         struct samr_QueryUserInfo r;
5842         union samr_UserInfo *info;
5843         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
5844                            11, 12, 13, 14, 16, 17, 20, 21};
5845         int i;
5846         bool ret = true;
5847
5848         for (i=0;i<ARRAY_SIZE(levels);i++) {
5849                 torture_comment(tctx, "Testing QueryUserInfo level %u\n", levels[i]);
5850
5851                 r.in.user_handle = handle;
5852                 r.in.level = levels[i];
5853                 r.out.info = &info;
5854
5855                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
5856                         "QueryUserInfo failed");
5857                 if (!NT_STATUS_IS_OK(r.out.result)) {
5858                         torture_warning(tctx, "QueryUserInfo level %u failed - %s\n",
5859                                levels[i], nt_errstr(r.out.result));
5860                         ret = false;
5861                 }
5862         }
5863
5864         return ret;
5865 }
5866
5867 static bool test_QueryUserInfo2(struct dcerpc_binding_handle *b,
5868                                 struct torture_context *tctx,
5869                                 struct policy_handle *handle)
5870 {
5871         struct samr_QueryUserInfo2 r;
5872         union samr_UserInfo *info;
5873         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
5874                            11, 12, 13, 14, 16, 17, 20, 21};
5875         int i;
5876         bool ret = true;
5877
5878         for (i=0;i<ARRAY_SIZE(levels);i++) {
5879                 torture_comment(tctx, "Testing QueryUserInfo2 level %u\n", levels[i]);
5880
5881                 r.in.user_handle = handle;
5882                 r.in.level = levels[i];
5883                 r.out.info = &info;
5884
5885                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo2_r(b, tctx, &r),
5886                         "QueryUserInfo2 failed");
5887                 if (!NT_STATUS_IS_OK(r.out.result)) {
5888                         torture_warning(tctx, "QueryUserInfo2 level %u failed - %s\n",
5889                                levels[i], nt_errstr(r.out.result));
5890                         ret = false;
5891                 }
5892         }
5893
5894         return ret;
5895 }
5896
5897 static bool test_OpenUser(struct dcerpc_binding_handle *b,
5898                           struct torture_context *tctx,
5899                           struct policy_handle *handle, uint32_t rid)
5900 {
5901         struct samr_OpenUser r;
5902         struct policy_handle user_handle;
5903         bool ret = true;
5904
5905         torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
5906
5907         r.in.domain_handle = handle;
5908         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5909         r.in.rid = rid;
5910         r.out.user_handle = &user_handle;
5911
5912         torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
5913                 "OpenUser failed");
5914         if (!NT_STATUS_IS_OK(r.out.result)) {
5915                 torture_warning(tctx, "OpenUser(%u) failed - %s\n", rid, nt_errstr(r.out.result));
5916                 return false;
5917         }
5918
5919         if (!test_QuerySecurity(b, tctx, &user_handle)) {
5920                 ret = false;
5921         }
5922
5923         if (!test_QueryUserInfo(b, tctx, &user_handle)) {
5924                 ret = false;
5925         }
5926
5927         if (!test_QueryUserInfo2(b, tctx, &user_handle)) {
5928                 ret = false;
5929         }
5930
5931         if (!test_GetUserPwInfo(b, tctx, &user_handle)) {
5932                 ret = false;
5933         }
5934
5935         if (!test_GetGroupsForUser(b, tctx, &user_handle)) {
5936                 ret = false;
5937         }
5938
5939         if (!test_samr_handle_Close(b, tctx, &user_handle)) {
5940                 ret = false;
5941         }
5942
5943         return ret;
5944 }
5945
5946 static bool test_OpenGroup(struct dcerpc_binding_handle *b,
5947                            struct torture_context *tctx,
5948                            struct policy_handle *handle, uint32_t rid)
5949 {
5950         struct samr_OpenGroup r;
5951         struct policy_handle group_handle;
5952         bool ret = true;
5953
5954         torture_comment(tctx, "Testing OpenGroup(%u)\n", rid);
5955
5956         r.in.domain_handle = handle;
5957         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5958         r.in.rid = rid;
5959         r.out.group_handle = &group_handle;
5960
5961         torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenGroup_r(b, tctx, &r),
5962                 "OpenGroup failed");
5963         if (!NT_STATUS_IS_OK(r.out.result)) {
5964                 torture_warning(tctx, "OpenGroup(%u) failed - %s\n", rid, nt_errstr(r.out.result));
5965                 return false;
5966         }
5967
5968         if (!torture_setting_bool(tctx, "samba3", false)) {
5969                 if (!test_QuerySecurity(b, tctx, &group_handle)) {
5970                         ret = false;
5971                 }
5972         }
5973
5974         if (!test_QueryGroupInfo(b, tctx, &group_handle)) {
5975                 ret = false;
5976         }
5977
5978         if (!test_QueryGroupMember(b, tctx, &group_handle)) {
5979                 ret = false;
5980         }
5981
5982         if (!test_samr_handle_Close(b, tctx, &group_handle)) {
5983                 ret = false;
5984         }
5985
5986         return ret;
5987 }
5988
5989 static bool test_OpenAlias(struct dcerpc_binding_handle *b,
5990                            struct torture_context *tctx,
5991                            struct policy_handle *handle, uint32_t rid)
5992 {
5993         struct samr_OpenAlias r;
5994         struct policy_handle alias_handle;
5995         bool ret = true;
5996
5997         torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
5998
5999         r.in.domain_handle = handle;
6000         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6001         r.in.rid = rid;
6002         r.out.alias_handle = &alias_handle;
6003
6004         torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenAlias_r(b, tctx, &r),
6005                 "OpenAlias failed");
6006         if (!NT_STATUS_IS_OK(r.out.result)) {
6007                 torture_warning(tctx, "OpenAlias(%u) failed - %s\n", rid, nt_errstr(r.out.result));
6008                 return false;
6009         }
6010
6011         if (!torture_setting_bool(tctx, "samba3", false)) {
6012                 if (!test_QuerySecurity(b, tctx, &alias_handle)) {
6013                         ret = false;
6014                 }
6015         }
6016
6017         if (!test_QueryAliasInfo(b, tctx, &alias_handle)) {
6018                 ret = false;
6019         }
6020
6021         if (!test_GetMembersInAlias(b, tctx, &alias_handle)) {
6022                 ret = false;
6023         }
6024
6025         if (!test_samr_handle_Close(b, tctx, &alias_handle)) {
6026                 ret = false;
6027         }
6028
6029         return ret;
6030 }
6031
6032 static bool check_mask(struct dcerpc_binding_handle *b,
6033                        struct torture_context *tctx,
6034                        struct policy_handle *handle, uint32_t rid,
6035                        uint32_t acct_flag_mask)
6036 {
6037         struct samr_OpenUser r;
6038         struct samr_QueryUserInfo q;
6039         union samr_UserInfo *info;
6040         struct policy_handle user_handle;
6041         bool ret = true;
6042
6043         torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
6044
6045         r.in.domain_handle = handle;
6046         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6047         r.in.rid = rid;
6048         r.out.user_handle = &user_handle;
6049
6050         torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
6051                 "OpenUser failed");
6052         if (!NT_STATUS_IS_OK(r.out.result)) {
6053                 torture_warning(tctx, "OpenUser(%u) failed - %s\n", rid, nt_errstr(r.out.result));
6054                 return false;
6055         }
6056
6057         q.in.user_handle = &user_handle;
6058         q.in.level = 16;
6059         q.out.info = &info;
6060
6061         torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
6062                 "QueryUserInfo failed");
6063         if (!NT_STATUS_IS_OK(q.out.result)) {
6064                 torture_warning(tctx, "QueryUserInfo level 16 failed - %s\n",
6065                        nt_errstr(q.out.result));
6066                 ret = false;
6067         } else {
6068                 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
6069                         torture_warning(tctx, "Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
6070                                acct_flag_mask, info->info16.acct_flags, rid);
6071                         ret = false;
6072                 }
6073         }
6074
6075         if (!test_samr_handle_Close(b, tctx, &user_handle)) {
6076                 ret = false;
6077         }
6078
6079         return ret;
6080 }
6081
6082 static bool test_EnumDomainUsers_all(struct dcerpc_binding_handle *b,
6083                                      struct torture_context *tctx,
6084                                      struct policy_handle *handle)
6085 {
6086         struct samr_EnumDomainUsers r;
6087         uint32_t mask, resume_handle=0;
6088         int i, mask_idx;
6089         bool ret = true;
6090         struct samr_LookupNames n;
6091         struct samr_LookupRids  lr ;
6092         struct lsa_Strings names;
6093         struct samr_Ids rids, types;
6094         struct samr_SamArray *sam = NULL;
6095         uint32_t num_entries = 0;
6096
6097         uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
6098                             ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
6099                             ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
6100                             ACB_PWNOEXP, 0};
6101
6102         torture_comment(tctx, "Testing EnumDomainUsers\n");
6103
6104         for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
6105                 r.in.domain_handle = handle;
6106                 r.in.resume_handle = &resume_handle;
6107                 r.in.acct_flags = mask = masks[mask_idx];
6108                 r.in.max_size = (uint32_t)-1;
6109                 r.out.resume_handle = &resume_handle;
6110                 r.out.num_entries = &num_entries;
6111                 r.out.sam = &sam;
6112
6113                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r(b, tctx, &r),
6114                         "EnumDomainUsers failed");
6115                 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) &&
6116                     !NT_STATUS_IS_OK(r.out.result)) {
6117                         torture_warning(tctx, "EnumDomainUsers failed - %s\n", nt_errstr(r.out.result));
6118                         return false;
6119                 }
6120
6121                 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
6122
6123                 if (sam->count == 0) {
6124                         continue;
6125                 }
6126
6127                 for (i=0;i<sam->count;i++) {
6128                         if (mask) {
6129                                 if (!check_mask(b, tctx, handle, sam->entries[i].idx, mask)) {
6130                                         ret = false;
6131                                 }
6132                         } else if (!test_OpenUser(b, tctx, handle, sam->entries[i].idx)) {
6133                                 ret = false;
6134                         }
6135                 }
6136         }
6137
6138         torture_comment(tctx, "Testing LookupNames\n");
6139         n.in.domain_handle = handle;
6140         n.in.num_names = sam->count;
6141         n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
6142         n.out.rids = &rids;
6143         n.out.types = &types;
6144         for (i=0;i<sam->count;i++) {
6145                 n.in.names[i].string = sam->entries[i].name.string;
6146         }
6147         torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupNames_r(b, tctx, &n),
6148                 "LookupNames failed");
6149         if (!NT_STATUS_IS_OK(n.out.result)) {
6150                 torture_warning(tctx, "LookupNames failed - %s\n", nt_errstr(n.out.result));
6151                 ret = false;
6152         }
6153
6154
6155         torture_comment(tctx, "Testing LookupRids\n");
6156         lr.in.domain_handle = handle;
6157         lr.in.num_rids = sam->count;
6158         lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
6159         lr.out.names = &names;
6160         lr.out.types = &types;
6161         for (i=0;i<sam->count;i++) {
6162                 lr.in.rids[i] = sam->entries[i].idx;
6163         }
6164         torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupRids_r(b, tctx, &lr),
6165                 "LookupRids failed");
6166         torture_assert_ntstatus_ok(tctx, lr.out.result, "LookupRids");
6167
6168         return ret;
6169 }
6170
6171 /*
6172   try blasting the server with a bunch of sync requests
6173 */
6174 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
6175                                        struct policy_handle *handle)
6176 {
6177         struct samr_EnumDomainUsers r;
6178         uint32_t resume_handle=0;
6179         int i;
6180 #define ASYNC_COUNT 100
6181         struct tevent_req *req[ASYNC_COUNT];
6182
6183         if (!torture_setting_bool(tctx, "dangerous", false)) {
6184                 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
6185         }
6186
6187         torture_comment(tctx, "Testing EnumDomainUsers_async\n");
6188
6189         r.in.domain_handle = handle;
6190         r.in.resume_handle = &resume_handle;
6191         r.in.acct_flags = 0;
6192         r.in.max_size = (uint32_t)-1;
6193         r.out.resume_handle = &resume_handle;
6194
6195         for (i=0;i<ASYNC_COUNT;i++) {
6196                 req[i] = dcerpc_samr_EnumDomainUsers_r_send(tctx, tctx->ev, p->binding_handle, &r);
6197         }
6198
6199         for (i=0;i<ASYNC_COUNT;i++) {
6200                 tevent_req_poll(req[i], tctx->ev);
6201                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r_recv(req[i], tctx),
6202                         talloc_asprintf(tctx, "EnumDomainUsers[%d] failed - %s\n",
6203                                i, nt_errstr(r.out.result)));
6204         }
6205
6206         torture_comment(tctx, "%d async requests OK\n", i);
6207
6208         return true;
6209 }
6210
6211 static bool test_EnumDomainGroups_all(struct dcerpc_binding_handle *b,
6212                                       struct torture_context *tctx,
6213                                       struct policy_handle *handle)
6214 {
6215         struct samr_EnumDomainGroups r;
6216         uint32_t resume_handle=0;
6217         struct samr_SamArray *sam = NULL;
6218         uint32_t num_entries = 0;
6219         int i;
6220         bool ret = true;
6221         bool universal_group_found = false;
6222
6223         torture_comment(tctx, "Testing EnumDomainGroups\n");
6224
6225         r.in.domain_handle = handle;
6226         r.in.resume_handle = &resume_handle;
6227         r.in.max_size = (uint32_t)-1;
6228         r.out.resume_handle = &resume_handle;
6229         r.out.num_entries = &num_entries;
6230         r.out.sam = &sam;
6231
6232         torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &r),
6233                 "EnumDomainGroups failed");
6234         if (!NT_STATUS_IS_OK(r.out.result)) {
6235                 torture_warning(tctx, "EnumDomainGroups failed - %s\n", nt_errstr(r.out.result));
6236                 return false;
6237         }
6238
6239         if (!sam) {
6240                 return false;
6241         }
6242
6243         for (i=0;i<sam->count;i++) {
6244                 if (!test_OpenGroup(b, tctx, handle, sam->entries[i].idx)) {
6245                         ret = false;
6246                 }
6247                 if ((ret == true) && (strcasecmp(sam->entries[i].name.string,
6248                                                  "Enterprise Admins") == 0)) {
6249                         universal_group_found = true;
6250                 }
6251         }
6252
6253         /* when we are running this on s4 we should get back at least the
6254          * "Enterprise Admins" universal group. If we don't get a group entry
6255          * at all we probably are performing the test on the builtin domain.
6256          * So ignore this case. */
6257         if (torture_setting_bool(tctx, "samba4", false)) {
6258                 if ((sam->count > 0) && (!universal_group_found)) {
6259                         ret = false;
6260                 }
6261         }
6262
6263         return ret;
6264 }
6265
6266 static bool test_EnumDomainAliases_all(struct dcerpc_binding_handle *b,
6267                                        struct torture_context *tctx,
6268                                        struct policy_handle *handle)
6269 {
6270         struct samr_EnumDomainAliases r;
6271         uint32_t resume_handle=0;
6272         struct samr_SamArray *sam = NULL;
6273         uint32_t num_entries = 0;
6274         int i;
6275         bool ret = true;
6276
6277         torture_comment(tctx, "Testing EnumDomainAliases\n");
6278
6279         r.in.domain_handle = handle;
6280         r.in.resume_handle = &resume_handle;
6281         r.in.max_size = (uint32_t)-1;
6282         r.out.sam = &sam;
6283         r.out.num_entries = &num_entries;
6284         r.out.resume_handle = &resume_handle;
6285
6286         torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainAliases_r(b, tctx, &r),
6287                 "EnumDomainAliases failed");
6288         if (!NT_STATUS_IS_OK(r.out.result)) {
6289                 torture_warning(tctx, "EnumDomainAliases failed - %s\n", nt_errstr(r.out.result));
6290                 return false;
6291         }
6292
6293         if (!sam) {
6294                 return false;
6295         }
6296
6297         for (i=0;i<sam->count;i++) {
6298                 if (!test_OpenAlias(b, tctx, handle, sam->entries[i].idx)) {
6299                         ret = false;
6300                 }
6301         }
6302
6303         return ret;
6304 }
6305
6306 static bool test_GetDisplayEnumerationIndex(struct dcerpc_binding_handle *b,
6307                                             struct torture_context *tctx,
6308                                             struct policy_handle *handle)
6309 {
6310         struct samr_GetDisplayEnumerationIndex r;
6311         bool ret = true;
6312         uint16_t levels[] = {1, 2, 3, 4, 5};
6313         uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
6314         struct lsa_String name;
6315         uint32_t idx = 0;
6316         int i;
6317
6318         for (i=0;i<ARRAY_SIZE(levels);i++) {
6319                 torture_comment(tctx, "Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
6320
6321                 init_lsa_String(&name, TEST_ACCOUNT_NAME);
6322
6323                 r.in.domain_handle = handle;
6324                 r.in.level = levels[i];
6325                 r.in.name = &name;
6326                 r.out.idx = &idx;
6327
6328                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex_r(b, tctx, &r),
6329                         "GetDisplayEnumerationIndex failed");
6330
6331                 if (ok_lvl[i] &&
6332                     !NT_STATUS_IS_OK(r.out.result) &&
6333                     !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6334                         torture_warning(tctx, "GetDisplayEnumerationIndex level %u failed - %s\n",
6335                                levels[i], nt_errstr(r.out.result));
6336                         ret = false;
6337                 }
6338
6339                 init_lsa_String(&name, "zzzzzzzz");
6340
6341                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex_r(b, tctx, &r),
6342                         "GetDisplayEnumerationIndex failed");
6343
6344                 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6345                         torture_warning(tctx, "GetDisplayEnumerationIndex level %u failed - %s\n",
6346                                levels[i], nt_errstr(r.out.result));
6347                         ret = false;
6348                 }
6349         }
6350
6351         return ret;
6352 }
6353
6354 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_binding_handle *b,
6355                                              struct torture_context *tctx,
6356                                              struct policy_handle *handle)
6357 {
6358         struct samr_GetDisplayEnumerationIndex2 r;
6359         bool ret = true;
6360         uint16_t levels[] = {1, 2, 3, 4, 5};
6361         uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
6362         struct lsa_String name;
6363         uint32_t idx = 0;
6364         int i;
6365
6366         for (i=0;i<ARRAY_SIZE(levels);i++) {
6367                 torture_comment(tctx, "Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
6368
6369                 init_lsa_String(&name, TEST_ACCOUNT_NAME);
6370
6371                 r.in.domain_handle = handle;
6372                 r.in.level = levels[i];
6373                 r.in.name = &name;
6374                 r.out.idx = &idx;
6375
6376                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex2_r(b, tctx, &r),
6377                         "GetDisplayEnumerationIndex2 failed");
6378                 if (ok_lvl[i] &&
6379                     !NT_STATUS_IS_OK(r.out.result) &&
6380                     !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6381                         torture_warning(tctx, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6382                                levels[i], nt_errstr(r.out.result));
6383                         ret = false;
6384                 }
6385
6386                 init_lsa_String(&name, "zzzzzzzz");
6387
6388                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex2_r(b, tctx, &r),
6389                         "GetDisplayEnumerationIndex2 failed");
6390                 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6391                         torture_warning(tctx, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6392                                levels[i], nt_errstr(r.out.result));
6393                         ret = false;
6394                 }
6395         }
6396
6397         return ret;
6398 }
6399
6400 #define STRING_EQUAL_QUERY(s1, s2, user)                                        \
6401         if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
6402                 /* odd, but valid */                                            \
6403         } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
6404                         torture_warning(tctx, "%s mismatch for %s: %s != %s (%s)\n", \
6405                                #s1, user.string,  s1.string, s2.string, __location__);   \
6406                         ret = false; \
6407         }
6408 #define INT_EQUAL_QUERY(s1, s2, user)           \
6409                 if (s1 != s2) { \
6410                         torture_warning(tctx, "%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
6411                                #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
6412                         ret = false; \
6413                 }
6414
6415 static bool test_each_DisplayInfo_user(struct dcerpc_binding_handle *b,
6416                                        struct torture_context *tctx,
6417                                        struct samr_QueryDisplayInfo *querydisplayinfo,
6418                                        bool *seen_testuser)
6419 {
6420         struct samr_OpenUser r;
6421         struct samr_QueryUserInfo q;
6422         union samr_UserInfo *info;
6423         struct policy_handle user_handle;
6424         int i, ret = true;
6425         r.in.domain_handle = querydisplayinfo->in.domain_handle;
6426         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6427         for (i = 0; ; i++) {
6428                 switch (querydisplayinfo->in.level) {
6429                 case 1:
6430                         if (i >= querydisplayinfo->out.info->info1.count) {
6431                                 return ret;
6432                         }
6433                         r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
6434                         break;
6435                 case 2:
6436                         if (i >= querydisplayinfo->out.info->info2.count) {
6437                                 return ret;
6438                         }
6439                         r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
6440                         break;
6441                 case 3:
6442                         /* Groups */
6443                 case 4:
6444                 case 5:
6445                         /* Not interested in validating just the account name */
6446                         return true;
6447                 }
6448
6449                 r.out.user_handle = &user_handle;
6450
6451                 switch (querydisplayinfo->in.level) {
6452                 case 1:
6453                 case 2:
6454                         torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
6455                                 "OpenUser failed");
6456                         if (!NT_STATUS_IS_OK(r.out.result)) {
6457                                 torture_warning(tctx, "OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(r.out.result));
6458                                 return false;
6459                         }
6460                 }
6461
6462                 q.in.user_handle = &user_handle;
6463                 q.in.level = 21;
6464                 q.out.info = &info;
6465                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
6466                         "QueryUserInfo failed");
6467                 if (!NT_STATUS_IS_OK(r.out.result)) {
6468                         torture_warning(tctx, "QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(r.out.result));
6469                         return false;
6470                 }
6471
6472                 switch (querydisplayinfo->in.level) {
6473                 case 1:
6474                         if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
6475                                 *seen_testuser = true;
6476                         }
6477                         STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
6478                                            info->info21.full_name, info->info21.account_name);
6479                         STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
6480                                            info->info21.account_name, info->info21.account_name);
6481                         STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
6482                                            info->info21.description, info->info21.account_name);
6483                         INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
6484                                         info->info21.rid, info->info21.account_name);
6485                         INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
6486                                         info->info21.acct_flags, info->info21.account_name);
6487
6488                         break;
6489                 case 2:
6490                         STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
6491                                            info->info21.account_name, info->info21.account_name);
6492                         STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
6493                                            info->info21.description, info->info21.account_name);
6494                         INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
6495                                         info->info21.rid, info->info21.account_name);
6496                         INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
6497                                         info->info21.acct_flags, info->info21.account_name);
6498
6499                         if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
6500                                 torture_warning(tctx, "Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
6501                                        info->info21.account_name.string);
6502                         }
6503
6504                         if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
6505                                 torture_warning(tctx, "Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
6506                                        info->info21.account_name.string,
6507                                        querydisplayinfo->out.info->info2.entries[i].acct_flags,
6508                                        info->info21.acct_flags);
6509                                 return false;
6510                         }
6511
6512                         break;
6513                 }
6514
6515                 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
6516                         return false;
6517                 }
6518         }
6519         return ret;
6520 }
6521
6522 static bool test_QueryDisplayInfo(struct dcerpc_binding_handle *b,
6523                                   struct torture_context *tctx,
6524                                   struct policy_handle *handle)
6525 {
6526         struct samr_QueryDisplayInfo r;
6527         struct samr_QueryDomainInfo dom_info;
6528         union samr_DomainInfo *info = NULL;
6529         bool ret = true;
6530         uint16_t levels[] = {1, 2, 3, 4, 5};
6531         int i;
6532         bool seen_testuser = false;
6533         uint32_t total_size;
6534         uint32_t returned_size;
6535         union samr_DispInfo disp_info;
6536
6537
6538         for (i=0;i<ARRAY_SIZE(levels);i++) {
6539                 torture_comment(tctx, "Testing QueryDisplayInfo level %u\n", levels[i]);
6540
6541                 r.in.start_idx = 0;
6542                 r.out.result = STATUS_MORE_ENTRIES;
6543                 while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES)) {
6544                         r.in.domain_handle = handle;
6545                         r.in.level = levels[i];
6546                         r.in.max_entries = 2;
6547                         r.in.buf_size = (uint32_t)-1;
6548                         r.out.total_size = &total_size;
6549                         r.out.returned_size = &returned_size;
6550                         r.out.info = &disp_info;
6551
6552                         torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
6553                                 "QueryDisplayInfo failed");
6554                         if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(r.out.result)) {
6555                                 torture_warning(tctx, "QueryDisplayInfo level %u failed - %s\n",
6556                                        levels[i], nt_errstr(r.out.result));
6557                                 ret = false;
6558                         }
6559                         switch (r.in.level) {
6560                         case 1:
6561                                 if (!test_each_DisplayInfo_user(b, tctx, &r, &seen_testuser)) {
6562                                         ret = false;
6563                                 }
6564                                 r.in.start_idx += r.out.info->info1.count;
6565                                 break;
6566                         case 2:
6567                                 if (!test_each_DisplayInfo_user(b, tctx, &r, NULL)) {
6568                                         ret = false;
6569                                 }
6570                                 r.in.start_idx += r.out.info->info2.count;
6571                                 break;
6572                         case 3:
6573                                 r.in.start_idx += r.out.info->info3.count;
6574                                 break;
6575                         case 4:
6576                                 r.in.start_idx += r.out.info->info4.count;
6577                                 break;
6578                         case 5:
6579                                 r.in.start_idx += r.out.info->info5.count;
6580                                 break;
6581                         }
6582                 }
6583                 dom_info.in.domain_handle = handle;
6584                 dom_info.in.level = 2;
6585                 dom_info.out.info = &info;
6586
6587                 /* Check number of users returned is correct */
6588                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &dom_info),
6589                         "QueryDomainInfo failed");
6590                 if (!NT_STATUS_IS_OK(dom_info.out.result)) {
6591                         torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
6592                                r.in.level, nt_errstr(dom_info.out.result));
6593                         ret = false;
6594                         break;
6595                 }
6596                 switch (r.in.level) {
6597                 case 1:
6598                 case 4:
6599                         if (info->general.num_users < r.in.start_idx) {
6600                                 /* On AD deployments this numbers don't match
6601                                  * since QueryDisplayInfo returns universal and
6602                                  * global groups, QueryDomainInfo only global
6603                                  * ones. */
6604                                 if (torture_setting_bool(tctx, "samba3", false)) {
6605                                         torture_warning(tctx, "QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
6606                                                r.in.start_idx, info->general.num_groups,
6607                                                info->general.domain_name.string);
6608                                         ret = false;
6609                                 }
6610                         }
6611                         if (!seen_testuser) {
6612                                 struct policy_handle user_handle;
6613                                 if (NT_STATUS_IS_OK(test_OpenUser_byname(b, tctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
6614                                         torture_warning(tctx, "Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
6615                                                info->general.domain_name.string);
6616                                         ret = false;
6617                                         test_samr_handle_Close(b, tctx, &user_handle);
6618                                 }
6619                         }
6620                         break;
6621                 case 3:
6622                 case 5:
6623                         if (info->general.num_groups != r.in.start_idx) {
6624                                 /* On AD deployments this numbers don't match
6625                                  * since QueryDisplayInfo returns universal and
6626                                  * global groups, QueryDomainInfo only global
6627                                  * ones. */
6628                                 if (torture_setting_bool(tctx, "samba3", false)) {
6629                                         torture_warning(tctx, "QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
6630                                                r.in.start_idx, info->general.num_groups,
6631                                                info->general.domain_name.string);
6632                                         ret = false;
6633                                 }
6634                         }
6635
6636                         break;
6637                 }
6638
6639         }
6640
6641         return ret;
6642 }
6643
6644 static bool test_QueryDisplayInfo2(struct dcerpc_binding_handle *b,
6645                                    struct torture_context *tctx,
6646                                    struct policy_handle *handle)
6647 {
6648         struct samr_QueryDisplayInfo2 r;
6649         bool ret = true;
6650         uint16_t levels[] = {1, 2, 3, 4, 5};
6651         int i;
6652         uint32_t total_size;
6653         uint32_t returned_size;
6654         union samr_DispInfo info;
6655
6656         for (i=0;i<ARRAY_SIZE(levels);i++) {
6657                 torture_comment(tctx, "Testing QueryDisplayInfo2 level %u\n", levels[i]);
6658
6659                 r.in.domain_handle = handle;
6660                 r.in.level = levels[i];
6661                 r.in.start_idx = 0;
6662                 r.in.max_entries = 1000;
6663                 r.in.buf_size = (uint32_t)-1;
6664                 r.out.total_size = &total_size;
6665                 r.out.returned_size = &returned_size;
6666                 r.out.info = &info;
6667
6668                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo2_r(b, tctx, &r),
6669                         "QueryDisplayInfo2 failed");
6670                 if (!NT_STATUS_IS_OK(r.out.result)) {
6671                         torture_warning(tctx, "QueryDisplayInfo2 level %u failed - %s\n",
6672                                levels[i], nt_errstr(r.out.result));
6673                         ret = false;
6674                 }
6675         }
6676
6677         return ret;
6678 }
6679
6680 static bool test_QueryDisplayInfo3(struct dcerpc_binding_handle *b,
6681                                    struct torture_context *tctx,
6682                                    struct policy_handle *handle)
6683 {
6684         struct samr_QueryDisplayInfo3 r;
6685         bool ret = true;
6686         uint16_t levels[] = {1, 2, 3, 4, 5};
6687         int i;
6688         uint32_t total_size;
6689         uint32_t returned_size;
6690         union samr_DispInfo info;
6691
6692         for (i=0;i<ARRAY_SIZE(levels);i++) {
6693                 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
6694
6695                 r.in.domain_handle = handle;
6696                 r.in.level = levels[i];
6697                 r.in.start_idx = 0;
6698                 r.in.max_entries = 1000;
6699                 r.in.buf_size = (uint32_t)-1;
6700                 r.out.total_size = &total_size;
6701                 r.out.returned_size = &returned_size;
6702                 r.out.info = &info;
6703
6704                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo3_r(b, tctx, &r),
6705                         "QueryDisplayInfo3 failed");
6706                 if (!NT_STATUS_IS_OK(r.out.result)) {
6707                         torture_warning(tctx, "QueryDisplayInfo3 level %u failed - %s\n",
6708                                levels[i], nt_errstr(r.out.result));
6709                         ret = false;
6710                 }
6711         }
6712
6713         return ret;
6714 }
6715
6716
6717 static bool test_QueryDisplayInfo_continue(struct dcerpc_binding_handle *b,
6718                                            struct torture_context *tctx,
6719                                            struct policy_handle *handle)
6720 {
6721         struct samr_QueryDisplayInfo r;
6722         bool ret = true;
6723         uint32_t total_size;
6724         uint32_t returned_size;
6725         union samr_DispInfo info;
6726
6727         torture_comment(tctx, "Testing QueryDisplayInfo continuation\n");
6728
6729         r.in.domain_handle = handle;
6730         r.in.level = 1;
6731         r.in.start_idx = 0;
6732         r.in.max_entries = 1;
6733         r.in.buf_size = (uint32_t)-1;
6734         r.out.total_size = &total_size;
6735         r.out.returned_size = &returned_size;
6736         r.out.info = &info;
6737
6738         do {
6739                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
6740                         "QueryDisplayInfo failed");
6741                 if (NT_STATUS_IS_OK(r.out.result) && *r.out.returned_size != 0) {
6742                         if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
6743                                 torture_warning(tctx, "expected idx %d but got %d\n",
6744                                        r.in.start_idx + 1,
6745                                        r.out.info->info1.entries[0].idx);
6746                                 break;
6747                         }
6748                 }
6749                 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) &&
6750                     !NT_STATUS_IS_OK(r.out.result)) {
6751                         torture_warning(tctx, "QueryDisplayInfo level %u failed - %s\n",
6752                                r.in.level, nt_errstr(r.out.result));
6753                         ret = false;
6754                         break;
6755                 }
6756                 r.in.start_idx++;
6757         } while ((NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) ||
6758                   NT_STATUS_IS_OK(r.out.result)) &&
6759                  *r.out.returned_size != 0);
6760
6761         return ret;
6762 }
6763
6764 static bool test_QueryDomainInfo(struct dcerpc_pipe *p,
6765                                  struct torture_context *tctx,
6766                                  struct policy_handle *handle)
6767 {
6768         struct samr_QueryDomainInfo r;
6769         union samr_DomainInfo *info = NULL;
6770         struct samr_SetDomainInfo s;
6771         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
6772         uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1,  0,  1,  0};
6773         int i;
6774         bool ret = true;
6775         struct dcerpc_binding_handle *b = p->binding_handle;
6776         const char *domain_comment = talloc_asprintf(tctx,
6777                                   "Tortured by Samba4 RPC-SAMR: %s",
6778                                   timestring(tctx, time(NULL)));
6779
6780         s.in.domain_handle = handle;
6781         s.in.level = 4;
6782         s.in.info = talloc(tctx, union samr_DomainInfo);
6783
6784         s.in.info->oem.oem_information.string = domain_comment;
6785         torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
6786                 "SetDomainInfo failed");
6787         if (!NT_STATUS_IS_OK(s.out.result)) {
6788                 torture_warning(tctx, "SetDomainInfo level %u (set comment) failed - %s\n",
6789                        s.in.level, nt_errstr(s.out.result));
6790                 return false;
6791         }
6792
6793         for (i=0;i<ARRAY_SIZE(levels);i++) {
6794                 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
6795
6796                 r.in.domain_handle = handle;
6797                 r.in.level = levels[i];
6798                 r.out.info = &info;
6799
6800                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
6801                         "QueryDomainInfo failed");
6802                 if (!NT_STATUS_IS_OK(r.out.result)) {
6803                         torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
6804                                r.in.level, nt_errstr(r.out.result));
6805                         ret = false;
6806                         continue;
6807                 }
6808
6809                 switch (levels[i]) {
6810                 case 2:
6811                         if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
6812                                 torture_warning(tctx, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
6813                                        levels[i], info->general.oem_information.string, domain_comment);
6814                                 if (!torture_setting_bool(tctx, "samba3", false)) {
6815                                         ret = false;
6816                                 }
6817                         }
6818                         if (!info->general.primary.string) {
6819                                 torture_warning(tctx, "QueryDomainInfo level %u returned no PDC name\n",
6820                                        levels[i]);
6821                                 ret = false;
6822                         } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
6823                                 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
6824                                         if (torture_setting_bool(tctx, "samba3", false)) {
6825                                                 torture_warning(tctx, "QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
6826                                                        levels[i], info->general.primary.string, dcerpc_server_name(p));
6827                                         }
6828                                 }
6829                         }
6830                         break;
6831                 case 4:
6832                         if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
6833                                 torture_warning(tctx, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
6834                                        levels[i], info->oem.oem_information.string, domain_comment);
6835                                 if (!torture_setting_bool(tctx, "samba3", false)) {
6836                                         ret = false;
6837                                 }
6838                         }
6839                         break;
6840                 case 6:
6841                         if (!info->info6.primary.string) {
6842                                 torture_warning(tctx, "QueryDomainInfo level %u returned no PDC name\n",
6843                                        levels[i]);
6844                                 ret = false;
6845                         }
6846                         break;
6847                 case 11:
6848                         if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
6849                                 torture_warning(tctx, "QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
6850                                        levels[i], info->general2.general.oem_information.string, domain_comment);
6851                                 if (!torture_setting_bool(tctx, "samba3", false)) {
6852                                         ret = false;
6853                                 }
6854                         }
6855                         break;
6856                 }
6857
6858                 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
6859
6860                 s.in.domain_handle = handle;
6861                 s.in.level = levels[i];
6862                 s.in.info = info;
6863
6864                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
6865                         "SetDomainInfo failed");
6866                 if (set_ok[i]) {
6867                         if (!NT_STATUS_IS_OK(s.out.result)) {
6868                                 torture_warning(tctx, "SetDomainInfo level %u failed - %s\n",
6869                                        r.in.level, nt_errstr(s.out.result));
6870                                 ret = false;
6871                                 continue;
6872                         }
6873                 } else {
6874                         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, s.out.result)) {
6875                                 torture_warning(tctx, "SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
6876                                        r.in.level, nt_errstr(s.out.result));
6877                                 ret = false;
6878                                 continue;
6879                         }
6880                 }
6881
6882                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
6883                         "QueryDomainInfo failed");
6884                 if (!NT_STATUS_IS_OK(r.out.result)) {
6885                         torture_warning(tctx, "QueryDomainInfo level %u failed - %s\n",
6886                                r.in.level, nt_errstr(r.out.result));
6887                         ret = false;
6888                         continue;
6889                 }
6890         }
6891
6892         return ret;
6893 }
6894
6895
6896 static bool test_QueryDomainInfo2(struct dcerpc_binding_handle *b,
6897                                   struct torture_context *tctx,
6898                                   struct policy_handle *handle)
6899 {
6900         struct samr_QueryDomainInfo2 r;
6901         union samr_DomainInfo *info = NULL;
6902         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
6903         int i;
6904         bool ret = true;
6905
6906         for (i=0;i<ARRAY_SIZE(levels);i++) {
6907                 torture_comment(tctx, "Testing QueryDomainInfo2 level %u\n", levels[i]);
6908
6909                 r.in.domain_handle = handle;
6910                 r.in.level = levels[i];
6911                 r.out.info = &info;
6912
6913                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
6914                         "QueryDomainInfo2 failed");
6915                 if (!NT_STATUS_IS_OK(r.out.result)) {
6916                         torture_warning(tctx, "QueryDomainInfo2 level %u failed - %s\n",
6917                                r.in.level, nt_errstr(r.out.result));
6918                         ret = false;
6919                         continue;
6920                 }
6921         }
6922
6923         return true;
6924 }
6925
6926 /* Test whether querydispinfo level 5 and enumdomgroups return the same
6927    set of group names. */
6928 static bool test_GroupList(struct dcerpc_binding_handle *b,
6929                            struct torture_context *tctx,
6930                            struct dom_sid *domain_sid,
6931                            struct policy_handle *handle)
6932 {
6933         struct samr_EnumDomainGroups q1;
6934         struct samr_QueryDisplayInfo q2;
6935         NTSTATUS status;
6936         uint32_t resume_handle=0;
6937         struct samr_SamArray *sam = NULL;
6938         uint32_t num_entries = 0;
6939         int i;
6940         bool ret = true;
6941         uint32_t total_size;
6942         uint32_t returned_size;
6943         union samr_DispInfo info;
6944
6945         int num_names = 0;
6946         const char **names = NULL;
6947
6948         bool builtin_domain = dom_sid_compare(domain_sid,
6949                                               &global_sid_Builtin) == 0;
6950
6951         torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
6952
6953         q1.in.domain_handle = handle;
6954         q1.in.resume_handle = &resume_handle;
6955         q1.in.max_size = 5;
6956         q1.out.resume_handle = &resume_handle;
6957         q1.out.num_entries = &num_entries;
6958         q1.out.sam = &sam;
6959
6960         status = STATUS_MORE_ENTRIES;
6961         while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
6962                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &q1),
6963                         "EnumDomainGroups failed");
6964                 status = q1.out.result;
6965
6966                 if (!NT_STATUS_IS_OK(status) &&
6967                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
6968                         break;
6969
6970                 for (i=0; i<*q1.out.num_entries; i++) {
6971                         add_string_to_array(tctx,
6972                                             sam->entries[i].name.string,
6973                                             &names, &num_names);
6974                 }
6975         }
6976
6977         torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
6978
6979         torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
6980
6981         if (builtin_domain) {
6982                 torture_assert(tctx, num_names == 0,
6983                                "EnumDomainGroups shouldn't return any group in the builtin domain!");
6984         }
6985
6986         q2.in.domain_handle = handle;
6987         q2.in.level = 5;
6988         q2.in.start_idx = 0;
6989         q2.in.max_entries = 5;
6990         q2.in.buf_size = (uint32_t)-1;
6991         q2.out.total_size = &total_size;
6992         q2.out.returned_size = &returned_size;
6993         q2.out.info = &info;
6994
6995         status = STATUS_MORE_ENTRIES;
6996         while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
6997                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &q2),
6998                         "QueryDisplayInfo failed");
6999                 status = q2.out.result;
7000                 if (!NT_STATUS_IS_OK(status) &&
7001                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
7002                         break;
7003
7004                 for (i=0; i<q2.out.info->info5.count; i++) {
7005                         int j;
7006                         const char *name = q2.out.info->info5.entries[i].account_name.string;
7007                         bool found = false;
7008                         for (j=0; j<num_names; j++) {
7009                                 if (names[j] == NULL)
7010                                         continue;
7011                                 if (strequal(names[j], name)) {
7012                                         names[j] = NULL;
7013                                         found = true;
7014                                         break;
7015                                 }
7016                         }
7017
7018                         if ((!found) && (!builtin_domain)) {
7019                                 torture_warning(tctx, "QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
7020                                        name);
7021                                 ret = false;
7022                         }
7023                 }
7024                 q2.in.start_idx += q2.out.info->info5.count;
7025         }
7026
7027         if (!NT_STATUS_IS_OK(status)) {
7028                 torture_warning(tctx, "QueryDisplayInfo level 5 failed - %s\n",
7029                        nt_errstr(status));
7030                 ret = false;
7031         }
7032
7033         if (builtin_domain) {
7034                 torture_assert(tctx, q2.in.start_idx != 0,
7035                                "QueryDisplayInfo should return all domain groups also on the builtin domain handle!");
7036         }
7037
7038         for (i=0; i<num_names; i++) {
7039                 if (names[i] != NULL) {
7040                         torture_warning(tctx, "EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
7041                                names[i]);
7042                         ret = false;
7043                 }
7044         }
7045
7046         return ret;
7047 }
7048
7049 static bool test_DeleteDomainGroup(struct dcerpc_binding_handle *b,
7050                                    struct torture_context *tctx,
7051                                    struct policy_handle *group_handle)
7052 {
7053         struct samr_DeleteDomainGroup d;
7054
7055         torture_comment(tctx, "Testing DeleteDomainGroup\n");
7056
7057         d.in.group_handle = group_handle;
7058         d.out.group_handle = group_handle;
7059
7060         torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomainGroup_r(b, tctx, &d),
7061                 "DeleteDomainGroup failed");
7062         torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteDomainGroup");
7063
7064         return true;
7065 }
7066
7067 static bool test_TestPrivateFunctionsDomain(struct dcerpc_binding_handle *b,
7068                                             struct torture_context *tctx,
7069                                             struct policy_handle *domain_handle)
7070 {
7071         struct samr_TestPrivateFunctionsDomain r;
7072         bool ret = true;
7073
7074         torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
7075
7076         r.in.domain_handle = domain_handle;
7077
7078         torture_assert_ntstatus_ok(tctx, dcerpc_samr_TestPrivateFunctionsDomain_r(b, tctx, &r),
7079                 "TestPrivateFunctionsDomain failed");
7080         torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsDomain");
7081
7082         return ret;
7083 }
7084
7085 static bool test_RidToSid(struct dcerpc_binding_handle *b,
7086                           struct torture_context *tctx,
7087                           struct dom_sid *domain_sid,
7088                           struct policy_handle *domain_handle)
7089 {
7090         struct samr_RidToSid r;
7091         bool ret = true;
7092         struct dom_sid *calc_sid, *out_sid;
7093         int rids[] = { 0, 42, 512, 10200 };
7094         int i;
7095
7096         for (i=0;i<ARRAY_SIZE(rids);i++) {
7097                 torture_comment(tctx, "Testing RidToSid\n");
7098
7099                 calc_sid = dom_sid_dup(tctx, domain_sid);
7100                 r.in.domain_handle = domain_handle;
7101                 r.in.rid = rids[i];
7102                 r.out.sid = &out_sid;
7103
7104                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RidToSid_r(b, tctx, &r),
7105                         "RidToSid failed");
7106                 if (!NT_STATUS_IS_OK(r.out.result)) {
7107                         torture_warning(tctx, "RidToSid for %d failed - %s\n", rids[i], nt_errstr(r.out.result));
7108                         ret = false;
7109                 } else {
7110                         calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
7111
7112                         if (!dom_sid_equal(calc_sid, out_sid)) {
7113                                 torture_warning(tctx, "RidToSid for %d failed - got %s, expected %s\n", rids[i],
7114                                        dom_sid_string(tctx, out_sid),
7115                                        dom_sid_string(tctx, calc_sid));
7116                                 ret = false;
7117                         }
7118                 }
7119         }
7120
7121         return ret;
7122 }
7123
7124 static bool test_GetBootKeyInformation(struct dcerpc_binding_handle *b,
7125                                        struct torture_context *tctx,
7126                                        struct policy_handle *domain_handle)
7127 {
7128         struct samr_GetBootKeyInformation r;
7129         bool ret = true;
7130         uint32_t unknown = 0;
7131         NTSTATUS status;
7132
7133         torture_comment(tctx, "Testing GetBootKeyInformation\n");
7134
7135         r.in.domain_handle = domain_handle;
7136         r.out.unknown = &unknown;
7137
7138         status = dcerpc_samr_GetBootKeyInformation_r(b, tctx, &r);
7139         if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(r.out.result)) {
7140                 status = r.out.result;
7141         }
7142         if (!NT_STATUS_IS_OK(status)) {
7143                 /* w2k3 seems to fail this sometimes and pass it sometimes */
7144                 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
7145         }
7146
7147         return ret;
7148 }
7149
7150 static bool test_AddGroupMember(struct dcerpc_binding_handle *b,
7151                                 struct torture_context *tctx,
7152                                 struct policy_handle *domain_handle,
7153                                 struct policy_handle *group_handle)
7154 {
7155         NTSTATUS status;
7156         struct samr_AddGroupMember r;
7157         struct samr_DeleteGroupMember d;
7158         struct samr_QueryGroupMember q;
7159         struct samr_RidAttrArray *rids = NULL;
7160         struct samr_SetMemberAttributesOfGroup s;
7161         uint32_t rid;
7162         bool found_member = false;
7163         int i;
7164
7165         status = test_LookupName(b, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
7166         torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
7167
7168         r.in.group_handle = group_handle;
7169         r.in.rid = rid;
7170         r.in.flags = 0; /* ??? */
7171
7172         torture_comment(tctx, "Testing AddGroupMember, QueryGroupMember and DeleteGroupMember\n");
7173
7174         d.in.group_handle = group_handle;
7175         d.in.rid = rid;
7176
7177         torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteGroupMember_r(b, tctx, &d),
7178                 "DeleteGroupMember failed");
7179         torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, d.out.result, "DeleteGroupMember");
7180
7181         torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7182                 "AddGroupMember failed");
7183         torture_assert_ntstatus_ok(tctx, r.out.result, "AddGroupMember");
7184
7185         torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7186                 "AddGroupMember failed");
7187         torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, r.out.result, "AddGroupMember");
7188
7189         if (torture_setting_bool(tctx, "samba4", false) ||
7190             torture_setting_bool(tctx, "samba3", false)) {
7191                 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba\n");
7192         } else {
7193                 /* this one is quite strange. I am using random inputs in the
7194                    hope of triggering an error that might give us a clue */
7195
7196                 s.in.group_handle = group_handle;
7197                 s.in.unknown1 = random();
7198                 s.in.unknown2 = random();
7199
7200                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetMemberAttributesOfGroup_r(b, tctx, &s),
7201                         "SetMemberAttributesOfGroup failed");
7202                 torture_assert_ntstatus_ok(tctx, s.out.result, "SetMemberAttributesOfGroup");
7203         }
7204
7205         q.in.group_handle = group_handle;
7206         q.out.rids = &rids;
7207
7208         torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &q),
7209                 "QueryGroupMember failed");
7210         torture_assert_ntstatus_ok(tctx, q.out.result, "QueryGroupMember");
7211         torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
7212
7213         for (i=0; i < rids->count; i++) {
7214                 if (rids->rids[i] == rid) {
7215                         found_member = true;
7216                 }
7217         }
7218
7219         torture_assert(tctx, found_member, "QueryGroupMember did not list newly added member");
7220
7221         torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteGroupMember_r(b, tctx, &d),
7222                 "DeleteGroupMember failed");
7223         torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteGroupMember");
7224
7225         rids = NULL;
7226         found_member = false;
7227
7228         torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &q),
7229                 "QueryGroupMember failed");
7230         torture_assert_ntstatus_ok(tctx, q.out.result, "QueryGroupMember");
7231         torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
7232
7233         for (i=0; i < rids->count; i++) {
7234                 if (rids->rids[i] == rid) {
7235                         found_member = true;
7236                 }
7237         }
7238
7239         torture_assert(tctx, !found_member, "QueryGroupMember does still list removed member");
7240
7241         torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7242                 "AddGroupMember failed");
7243         torture_assert_ntstatus_ok(tctx, r.out.result, "AddGroupMember");
7244
7245         return true;
7246 }
7247
7248
7249 static bool test_CreateDomainGroup(struct dcerpc_binding_handle *b,
7250                                    struct torture_context *tctx,
7251                                    struct policy_handle *domain_handle,
7252                                    const char *group_name,
7253                                    struct policy_handle *group_handle,
7254                                    struct dom_sid *domain_sid,
7255                                    bool test_group)
7256 {
7257         struct samr_CreateDomainGroup r;
7258         uint32_t rid;
7259         struct lsa_String name;
7260         bool ret = true;
7261
7262         init_lsa_String(&name, group_name);
7263
7264         r.in.domain_handle = domain_handle;
7265         r.in.name = &name;
7266         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7267         r.out.group_handle = group_handle;
7268         r.out.rid = &rid;
7269
7270         torture_comment(tctx, "Testing CreateDomainGroup(%s)\n", r.in.name->string);
7271
7272         torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7273                 "CreateDomainGroup failed");
7274
7275         if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
7276                 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED)) {
7277                         torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
7278                         return true;
7279                 } else {
7280                         torture_warning(tctx, "Server should have refused create of '%s', got %s instead\n", r.in.name->string,
7281                                nt_errstr(r.out.result));
7282                         return false;
7283                 }
7284         }
7285
7286         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_GROUP_EXISTS)) {
7287                 if (!test_DeleteGroup_byname(b, tctx, domain_handle, r.in.name->string)) {
7288                         torture_warning(tctx, "CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
7289                                nt_errstr(r.out.result));
7290                         return false;
7291                 }
7292                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7293                         "CreateDomainGroup failed");
7294         }
7295         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
7296                 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.name->string)) {
7297
7298                         torture_warning(tctx, "CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
7299                                nt_errstr(r.out.result));
7300                         return false;
7301                 }
7302                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7303                         "CreateDomainGroup failed");
7304         }
7305         torture_assert_ntstatus_ok(tctx, r.out.result, "CreateDomainGroup");
7306
7307         if (!test_group) {
7308                 return ret;
7309         }
7310
7311         if (!test_AddGroupMember(b, tctx, domain_handle, group_handle)) {
7312                 torture_warning(tctx, "CreateDomainGroup failed - %s\n", nt_errstr(r.out.result));
7313                 ret = false;
7314         }
7315
7316         if (!test_SetGroupInfo(b, tctx, group_handle)) {
7317                 ret = false;
7318         }
7319
7320         return ret;
7321 }
7322
7323
7324 /*
7325   its not totally clear what this does. It seems to accept any sid you like.
7326 */
7327 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_binding_handle *b,
7328                                                struct torture_context *tctx,
7329                                                struct policy_handle *domain_handle)
7330 {
7331         struct samr_RemoveMemberFromForeignDomain r;
7332
7333         r.in.domain_handle = domain_handle;
7334         r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
7335
7336         torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMemberFromForeignDomain_r(b, tctx, &r),
7337                 "RemoveMemberFromForeignDomain failed");
7338         torture_assert_ntstatus_ok(tctx, r.out.result, "RemoveMemberFromForeignDomain");
7339
7340         return true;
7341 }
7342
7343 static bool test_EnumDomainUsers(struct dcerpc_binding_handle *b,
7344                                  struct torture_context *tctx,
7345                                  struct policy_handle *domain_handle,
7346                                  uint32_t *total_num_entries_p)
7347 {
7348         NTSTATUS status;
7349         struct samr_EnumDomainUsers r;
7350         uint32_t resume_handle = 0;
7351         uint32_t num_entries = 0;
7352         uint32_t total_num_entries = 0;
7353         struct samr_SamArray *sam;
7354
7355         r.in.domain_handle = domain_handle;
7356         r.in.acct_flags = 0;
7357         r.in.max_size = (uint32_t)-1;
7358         r.in.resume_handle = &resume_handle;
7359
7360         r.out.sam = &sam;
7361         r.out.num_entries = &num_entries;
7362         r.out.resume_handle = &resume_handle;
7363
7364         torture_comment(tctx, "Testing EnumDomainUsers\n");
7365
7366         do {
7367                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r(b, tctx, &r),
7368                         "EnumDomainUsers failed");
7369                 if (NT_STATUS_IS_ERR(r.out.result)) {
7370                         torture_assert_ntstatus_ok(tctx, r.out.result,
7371                                 "failed to enumerate users");
7372                 }
7373                 status = r.out.result;
7374
7375                 total_num_entries += num_entries;
7376         } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7377
7378         if (total_num_entries_p) {
7379                 *total_num_entries_p = total_num_entries;
7380         }
7381
7382         return true;
7383 }
7384
7385 static bool test_EnumDomainGroups(struct dcerpc_binding_handle *b,
7386                                   struct torture_context *tctx,
7387                                   struct policy_handle *domain_handle,
7388                                   uint32_t *total_num_entries_p)
7389 {
7390         NTSTATUS status;
7391         struct samr_EnumDomainGroups r;
7392         uint32_t resume_handle = 0;
7393         uint32_t num_entries = 0;
7394         uint32_t total_num_entries = 0;
7395         struct samr_SamArray *sam;
7396
7397         r.in.domain_handle = domain_handle;
7398         r.in.max_size = (uint32_t)-1;
7399         r.in.resume_handle = &resume_handle;
7400
7401         r.out.sam = &sam;
7402         r.out.num_entries = &num_entries;
7403         r.out.resume_handle = &resume_handle;
7404
7405         torture_comment(tctx, "Testing EnumDomainGroups\n");
7406
7407         do {
7408                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &r),
7409                         "EnumDomainGroups failed");
7410                 if (NT_STATUS_IS_ERR(r.out.result)) {
7411                         torture_assert_ntstatus_ok(tctx, r.out.result,
7412                                 "failed to enumerate groups");
7413                 }
7414                 status = r.out.result;
7415
7416                 total_num_entries += num_entries;
7417         } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7418
7419         if (total_num_entries_p) {
7420                 *total_num_entries_p = total_num_entries;
7421         }
7422
7423         return true;
7424 }
7425
7426 static bool test_EnumDomainAliases(struct dcerpc_binding_handle *b,
7427                                    struct torture_context *tctx,
7428                                    struct policy_handle *domain_handle,
7429                                    uint32_t *total_num_entries_p)
7430 {
7431         NTSTATUS status;
7432         struct samr_EnumDomainAliases r;
7433         uint32_t resume_handle = 0;
7434         uint32_t num_entries = 0;
7435         uint32_t total_num_entries = 0;
7436         struct samr_SamArray *sam;
7437
7438         r.in.domain_handle = domain_handle;
7439         r.in.max_size = (uint32_t)-1;
7440         r.in.resume_handle = &resume_handle;
7441
7442         r.out.sam = &sam;
7443         r.out.num_entries = &num_entries;
7444         r.out.resume_handle = &resume_handle;
7445
7446         torture_comment(tctx, "Testing EnumDomainAliases\n");
7447
7448         do {
7449                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainAliases_r(b, tctx, &r),
7450                         "EnumDomainAliases failed");
7451                 if (NT_STATUS_IS_ERR(r.out.result)) {
7452                         torture_assert_ntstatus_ok(tctx, r.out.result,
7453                                 "failed to enumerate aliases");
7454                 }
7455                 status = r.out.result;
7456
7457                 total_num_entries += num_entries;
7458         } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7459
7460         if (total_num_entries_p) {
7461                 *total_num_entries_p = total_num_entries;
7462         }
7463
7464         return true;
7465 }
7466
7467 static bool test_QueryDisplayInfo_level(struct dcerpc_binding_handle *b,
7468                                         struct torture_context *tctx,
7469                                         struct policy_handle *handle,
7470                                         uint16_t level,
7471                                         uint32_t *total_num_entries_p)
7472 {
7473         NTSTATUS status;
7474         struct samr_QueryDisplayInfo r;
7475         uint32_t total_num_entries = 0;
7476
7477         r.in.domain_handle = handle;
7478         r.in.level = level;
7479         r.in.start_idx = 0;
7480         r.in.max_entries = (uint32_t)-1;
7481         r.in.buf_size = (uint32_t)-1;
7482
7483         torture_comment(tctx, "Testing QueryDisplayInfo\n");
7484
7485         do {
7486                 uint32_t total_size;
7487                 uint32_t returned_size;
7488                 union samr_DispInfo info;
7489
7490                 r.out.total_size = &total_size;
7491                 r.out.returned_size = &returned_size;
7492                 r.out.info = &info;
7493
7494                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
7495                         "failed to query displayinfo");
7496                 if (NT_STATUS_IS_ERR(r.out.result)) {
7497                         torture_assert_ntstatus_ok(tctx, r.out.result,
7498                                 "failed to query displayinfo");
7499                 }
7500                 status = r.out.result;
7501
7502                 if (*r.out.returned_size == 0) {
7503                         break;
7504                 }
7505
7506                 switch (r.in.level) {
7507                 case 1:
7508                         total_num_entries += info.info1.count;
7509                         r.in.start_idx += info.info1.entries[info.info1.count - 1].idx + 1;
7510                         break;
7511                 case 2:
7512                         total_num_entries += info.info2.count;
7513                         r.in.start_idx += info.info2.entries[info.info2.count - 1].idx + 1;
7514                         break;
7515                 case 3:
7516                         total_num_entries += info.info3.count;
7517                         r.in.start_idx += info.info3.entries[info.info3.count - 1].idx + 1;
7518                         break;
7519                 case 4:
7520                         total_num_entries += info.info4.count;
7521                         r.in.start_idx += info.info4.entries[info.info4.count - 1].idx + 1;
7522                         break;
7523                 case 5:
7524                         total_num_entries += info.info5.count;
7525                         r.in.start_idx += info.info5.entries[info.info5.count - 1].idx + 1;
7526                         break;
7527                 default:
7528                         return false;
7529                 }
7530
7531         } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7532
7533         if (total_num_entries_p) {
7534                 *total_num_entries_p = total_num_entries;
7535         }
7536
7537         return true;
7538 }
7539
7540 static bool test_ManyObjects(struct dcerpc_pipe *p,
7541                              struct torture_context *tctx,
7542                              struct policy_handle *domain_handle,
7543                              struct dom_sid *domain_sid,
7544                              struct torture_samr_context *ctx)
7545 {
7546         uint32_t num_total = ctx->num_objects_large_dc;
7547         uint32_t num_enum = 0;
7548         uint32_t num_disp = 0;
7549         uint32_t num_created = 0;
7550         uint32_t num_anounced = 0;
7551         uint32_t i;
7552         struct dcerpc_binding_handle *b = p->binding_handle;
7553
7554         struct policy_handle *handles = talloc_zero_array(tctx, struct policy_handle, num_total);
7555
7556         /* query */
7557
7558         {
7559                 struct samr_QueryDomainInfo2 r;
7560                 union samr_DomainInfo *info;
7561                 r.in.domain_handle = domain_handle;
7562                 r.in.level = 2;
7563                 r.out.info = &info;
7564
7565                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
7566                         "QueryDomainInfo2 failed");
7567                 torture_assert_ntstatus_ok(tctx, r.out.result,
7568                         "failed to query domain info");
7569
7570                 switch (ctx->choice) {
7571                 case TORTURE_SAMR_MANY_ACCOUNTS:
7572                         num_anounced = info->general.num_users;
7573                         break;
7574                 case TORTURE_SAMR_MANY_GROUPS:
7575                         num_anounced = info->general.num_groups;
7576                         break;
7577                 case TORTURE_SAMR_MANY_ALIASES:
7578                         num_anounced = info->general.num_aliases;
7579                         break;
7580                 default:
7581                         return false;
7582                 }
7583         }
7584
7585         /* create */
7586
7587         for (i=0; i < num_total; i++) {
7588
7589                 const char *name = NULL;
7590
7591                 switch (ctx->choice) {
7592                 case TORTURE_SAMR_MANY_ACCOUNTS:
7593                         name = talloc_asprintf(tctx, "%s%04d", TEST_ACCOUNT_NAME, i);
7594                         torture_assert(tctx,
7595                                 test_CreateUser(p, tctx, domain_handle, name, &handles[i], domain_sid, 0, NULL, false),
7596                                 "failed to create user");
7597                         break;
7598                 case TORTURE_SAMR_MANY_GROUPS:
7599                         name = talloc_asprintf(tctx, "%s%04d", TEST_GROUPNAME, i);
7600                         torture_assert(tctx,
7601                                 test_CreateDomainGroup(b, tctx, domain_handle, name, &handles[i], domain_sid, false),
7602                                 "failed to create group");
7603                         break;
7604                 case TORTURE_SAMR_MANY_ALIASES:
7605                         name = talloc_asprintf(tctx, "%s%04d", TEST_ALIASNAME, i);
7606                         torture_assert(tctx,
7607                                 test_CreateAlias(b, tctx, domain_handle, name, &handles[i], domain_sid, false),
7608                                 "failed to create alias");
7609                         break;
7610                 default:
7611                         return false;
7612                 }
7613                 if (!ndr_policy_handle_empty(&handles[i])) {
7614                         num_created++;
7615                 }
7616         }
7617
7618         /* enum */
7619
7620         switch (ctx->choice) {
7621         case TORTURE_SAMR_MANY_ACCOUNTS:
7622                 torture_assert(tctx,
7623                         test_EnumDomainUsers(b, tctx, domain_handle, &num_enum),
7624                         "failed to enum users");
7625                 break;
7626         case TORTURE_SAMR_MANY_GROUPS:
7627                 torture_assert(tctx,
7628                         test_EnumDomainGroups(b, tctx, domain_handle, &num_enum),
7629                         "failed to enum groups");
7630                 break;
7631         case TORTURE_SAMR_MANY_ALIASES:
7632                 torture_assert(tctx,
7633                         test_EnumDomainAliases(b, tctx, domain_handle, &num_enum),
7634                         "failed to enum aliases");
7635                 break;
7636         default:
7637                 return false;
7638         }
7639
7640         /* dispinfo */
7641
7642         switch (ctx->choice) {
7643         case TORTURE_SAMR_MANY_ACCOUNTS:
7644                 torture_assert(tctx,
7645                         test_QueryDisplayInfo_level(b, tctx, domain_handle, 1, &num_disp),
7646                         "failed to query display info");
7647                 break;
7648         case TORTURE_SAMR_MANY_GROUPS:
7649                 torture_assert(tctx,
7650                         test_QueryDisplayInfo_level(b, tctx, domain_handle, 3, &num_disp),
7651                         "failed to query display info");
7652                 break;
7653         case TORTURE_SAMR_MANY_ALIASES:
7654                 /* no aliases in dispinfo */
7655                 break;
7656         default:
7657                 return false;
7658         }
7659
7660         /* close or delete */
7661
7662         for (i=0; i < num_total; i++) {
7663
7664                 if (ndr_policy_handle_empty(&handles[i])) {
7665                         continue;
7666                 }
7667
7668                 if (torture_setting_bool(tctx, "samba3", false)) {
7669                         torture_assert(tctx,
7670                                 test_samr_handle_Close(b, tctx, &handles[i]),
7671                                 "failed to close handle");
7672                 } else {
7673                         switch (ctx->choice) {
7674                         case TORTURE_SAMR_MANY_ACCOUNTS:
7675                                 torture_assert(tctx,
7676                                         test_DeleteUser(b, tctx, &handles[i]),
7677                                         "failed to delete user");
7678                                 break;
7679                         case TORTURE_SAMR_MANY_GROUPS:
7680                                 torture_assert(tctx,
7681                                         test_DeleteDomainGroup(b, tctx, &handles[i]),
7682                                         "failed to delete group");
7683                                 break;
7684                         case TORTURE_SAMR_MANY_ALIASES:
7685                                 torture_assert(tctx,
7686                                         test_DeleteAlias(b, tctx, &handles[i]),
7687                                         "failed to delete alias");
7688                                 break;
7689                         default:
7690                                 return false;
7691                         }
7692                 }
7693         }
7694
7695         talloc_free(handles);
7696
7697         if (ctx->choice == TORTURE_SAMR_MANY_ACCOUNTS && num_enum != num_anounced + num_created) {
7698                 torture_comment(tctx,
7699                                 "unexpected number of results (%u) returned in enum call, expected %u\n",
7700                                 num_enum, num_anounced + num_created);
7701
7702                 torture_comment(tctx,
7703                                 "unexpected number of results (%u) returned in dispinfo, call, expected %u\n",
7704                                 num_disp, num_anounced + num_created);
7705         }
7706
7707         return true;
7708 }
7709
7710 static bool test_Connect(struct dcerpc_binding_handle *b,
7711                          struct torture_context *tctx,
7712                          struct policy_handle *handle);
7713
7714 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
7715                             struct torture_samr_context *ctx, struct dom_sid *sid)
7716 {
7717         struct samr_OpenDomain r;
7718         struct policy_handle domain_handle;
7719         struct policy_handle alias_handle;
7720         struct policy_handle user_handle;
7721         struct policy_handle group_handle;
7722         bool ret = true;
7723         struct dcerpc_binding_handle *b = p->binding_handle;
7724
7725         ZERO_STRUCT(alias_handle);
7726         ZERO_STRUCT(user_handle);
7727         ZERO_STRUCT(group_handle);
7728         ZERO_STRUCT(domain_handle);
7729
7730         torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
7731
7732         r.in.connect_handle = &ctx->handle;
7733         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7734         r.in.sid = sid;
7735         r.out.domain_handle = &domain_handle;
7736
7737         torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenDomain_r(b, tctx, &r),
7738                 "OpenDomain failed");
7739         torture_assert_ntstatus_ok(tctx, r.out.result, "OpenDomain failed");
7740
7741         /* run the domain tests with the main handle closed - this tests
7742            the servers reference counting */
7743         torture_assert(tctx, test_samr_handle_Close(b, tctx, &ctx->handle), "Failed to close SAMR handle");
7744
7745         switch (ctx->choice) {
7746         case TORTURE_SAMR_PASSWORDS:
7747         case TORTURE_SAMR_USER_PRIVILEGES:
7748                 if (!torture_setting_bool(tctx, "samba3", false)) {
7749                         ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, NULL);
7750                 }
7751                 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
7752                 if (!ret) {
7753                         torture_warning(tctx, "Testing PASSWORDS or PRIVILEGES on domain %s failed!\n", dom_sid_string(tctx, sid));
7754                 }
7755                 break;
7756         case TORTURE_SAMR_USER_ATTRIBUTES:
7757                 if (!torture_setting_bool(tctx, "samba3", false)) {
7758                         ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, NULL);
7759                 }
7760                 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
7761                 /* This test needs 'complex' users to validate */
7762                 ret &= test_QueryDisplayInfo(b, tctx, &domain_handle);
7763                 if (!ret) {
7764                         torture_warning(tctx, "Testing ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
7765                 }
7766                 break;
7767         case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
7768         case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT:
7769         case TORTURE_SAMR_PASSWORDS_LOCKOUT:
7770                 if (!torture_setting_bool(tctx, "samba3", false)) {
7771                         ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, ctx->machine_credentials);
7772                 }
7773                 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, ctx->machine_credentials, true);
7774                 if (!ret) {
7775                         torture_warning(tctx, "Testing PASSWORDS PWDLASTSET or BADPWDCOUNT on domain %s failed!\n", dom_sid_string(tctx, sid));
7776                 }
7777                 break;
7778         case TORTURE_SAMR_MANY_ACCOUNTS:
7779         case TORTURE_SAMR_MANY_GROUPS:
7780         case TORTURE_SAMR_MANY_ALIASES:
7781                 ret &= test_ManyObjects(p, tctx, &domain_handle, sid, ctx);
7782                 if (!ret) {
7783                         torture_warning(tctx, "Testing MANY-{ACCOUNTS,GROUPS,ALIASES} on domain %s failed!\n", dom_sid_string(tctx, sid));
7784                 }
7785                 break;
7786         case TORTURE_SAMR_OTHER:
7787                 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
7788                 if (!ret) {
7789                         torture_warning(tctx, "Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
7790                 }
7791                 if (!torture_setting_bool(tctx, "samba3", false)) {
7792                         ret &= test_QuerySecurity(b, tctx, &domain_handle);
7793                 }
7794                 ret &= test_RemoveMemberFromForeignDomain(b, tctx, &domain_handle);
7795                 ret &= test_CreateAlias(b, tctx, &domain_handle, TEST_ALIASNAME, &alias_handle, sid, true);
7796                 ret &= test_CreateDomainGroup(b, tctx, &domain_handle, TEST_GROUPNAME, &group_handle, sid, true);
7797                 ret &= test_GetAliasMembership(b, tctx, &domain_handle);
7798                 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
7799                 ret &= test_QueryDomainInfo2(b, tctx, &domain_handle);
7800                 ret &= test_EnumDomainUsers_all(b, tctx, &domain_handle);
7801                 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
7802                 ret &= test_EnumDomainGroups_all(b, tctx, &domain_handle);
7803                 ret &= test_EnumDomainAliases_all(b, tctx, &domain_handle);
7804                 ret &= test_QueryDisplayInfo2(b, tctx, &domain_handle);
7805                 ret &= test_QueryDisplayInfo3(b, tctx, &domain_handle);
7806                 ret &= test_QueryDisplayInfo_continue(b, tctx, &domain_handle);
7807
7808                 if (torture_setting_bool(tctx, "samba4", false)) {
7809                         torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
7810                 } else {
7811                         ret &= test_GetDisplayEnumerationIndex(b, tctx, &domain_handle);
7812                         ret &= test_GetDisplayEnumerationIndex2(b, tctx, &domain_handle);
7813                 }
7814                 ret &= test_GroupList(b, tctx, sid, &domain_handle);
7815                 ret &= test_TestPrivateFunctionsDomain(b, tctx, &domain_handle);
7816                 ret &= test_RidToSid(b, tctx, sid, &domain_handle);
7817                 ret &= test_GetBootKeyInformation(b, tctx, &domain_handle);
7818                 if (!ret) {
7819                         torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
7820                 }
7821                 break;
7822         }
7823
7824         if (!ndr_policy_handle_empty(&user_handle) &&
7825             !test_DeleteUser(b, tctx, &user_handle)) {
7826                 ret = false;
7827         }
7828
7829         if (!ndr_policy_handle_empty(&alias_handle) &&
7830             !test_DeleteAlias(b, tctx, &alias_handle)) {
7831                 ret = false;
7832         }
7833
7834         if (!ndr_policy_handle_empty(&group_handle) &&
7835             !test_DeleteDomainGroup(b, tctx, &group_handle)) {
7836                 ret = false;
7837         }
7838
7839         torture_assert(tctx, test_samr_handle_Close(b, tctx, &domain_handle), "Failed to close SAMR domain handle");
7840
7841         torture_assert(tctx, test_Connect(b, tctx, &ctx->handle), "Faile to re-connect SAMR handle");
7842         /* reconnect the main handle */
7843
7844         if (!ret) {
7845                 torture_warning(tctx, "Testing domain %s failed!\n", dom_sid_string(tctx, sid));
7846         }
7847
7848         return ret;
7849 }
7850
7851 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
7852                               struct torture_samr_context *ctx, const char *domain)
7853 {
7854         struct samr_LookupDomain r;
7855         struct dom_sid2 *sid = NULL;
7856         struct lsa_String n1;
7857         struct lsa_String n2;
7858         bool ret = true;
7859         struct dcerpc_binding_handle *b = p->binding_handle;
7860
7861         torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
7862
7863         /* check for correct error codes */
7864         r.in.connect_handle = &ctx->handle;
7865         r.in.domain_name = &n2;
7866         r.out.sid = &sid;
7867         n2.string = NULL;
7868
7869         torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
7870                 "LookupDomain failed");
7871         torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, r.out.result, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
7872
7873         init_lsa_String(&n2, "xxNODOMAINxx");
7874
7875         torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
7876                 "LookupDomain failed");
7877         torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, r.out.result, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
7878
7879         r.in.connect_handle = &ctx->handle;
7880
7881         init_lsa_String(&n1, domain);
7882         r.in.domain_name = &n1;
7883
7884         torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
7885                 "LookupDomain failed");
7886         torture_assert_ntstatus_ok(tctx, r.out.result, "LookupDomain");
7887
7888         if (!test_GetDomPwInfo(p, tctx, &n1)) {
7889                 ret = false;
7890         }
7891
7892         if (!test_OpenDomain(p, tctx, ctx, *r.out.sid)) {
7893                 ret = false;
7894         }
7895
7896         return ret;
7897 }
7898
7899
7900 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
7901                              struct torture_samr_context *ctx)
7902 {
7903         struct samr_EnumDomains r;
7904         uint32_t resume_handle = 0;
7905         uint32_t num_entries = 0;
7906         struct samr_SamArray *sam = NULL;
7907         int i;
7908         bool ret = true;
7909         struct dcerpc_binding_handle *b = p->binding_handle;
7910
7911         r.in.connect_handle = &ctx->handle;
7912         r.in.resume_handle = &resume_handle;
7913         r.in.buf_size = (uint32_t)-1;
7914         r.out.resume_handle = &resume_handle;
7915         r.out.num_entries = &num_entries;
7916         r.out.sam = &sam;
7917
7918         torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomains_r(b, tctx, &r),
7919                 "EnumDomains failed");
7920         torture_assert_ntstatus_ok(tctx, r.out.result, "EnumDomains failed");
7921
7922         if (!*r.out.sam) {
7923                 return false;
7924         }
7925
7926         for (i=0;i<sam->count;i++) {
7927                 if (!test_LookupDomain(p, tctx, ctx,
7928                                        sam->entries[i].name.string)) {
7929                         ret = false;
7930                 }
7931         }
7932
7933         torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomains_r(b, tctx, &r),
7934                 "EnumDomains failed");
7935         torture_assert_ntstatus_ok(tctx, r.out.result, "EnumDomains failed");
7936
7937         return ret;
7938 }
7939
7940
7941 static bool test_Connect(struct dcerpc_binding_handle *b,
7942                          struct torture_context *tctx,
7943                          struct policy_handle *handle)
7944 {
7945         struct samr_Connect r;
7946         struct samr_Connect2 r2;
7947         struct samr_Connect3 r3;
7948         struct samr_Connect4 r4;
7949         struct samr_Connect5 r5;
7950         union samr_ConnectInfo info;
7951         struct policy_handle h;
7952         uint32_t level_out = 0;
7953         bool ret = true, got_handle = false;
7954
7955         torture_comment(tctx, "Testing samr_Connect\n");
7956
7957         r.in.system_name = NULL;
7958         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7959         r.out.connect_handle = &h;
7960
7961         torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect_r(b, tctx, &r),
7962                 "Connect failed");
7963         if (!NT_STATUS_IS_OK(r.out.result)) {
7964                 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(r.out.result));
7965                 ret = false;
7966         } else {
7967                 got_handle = true;
7968                 *handle = h;
7969         }
7970
7971         torture_comment(tctx, "Testing samr_Connect2\n");
7972
7973         r2.in.system_name = NULL;
7974         r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7975         r2.out.connect_handle = &h;
7976
7977         torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect2_r(b, tctx, &r2),
7978                 "Connect2 failed");
7979         if (!NT_STATUS_IS_OK(r2.out.result)) {
7980                 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(r2.out.result));
7981                 ret = false;
7982         } else {
7983                 if (got_handle) {
7984                         test_samr_handle_Close(b, tctx, handle);
7985                 }
7986                 got_handle = true;
7987                 *handle = h;
7988         }
7989
7990         torture_comment(tctx, "Testing samr_Connect3\n");
7991
7992         r3.in.system_name = NULL;
7993         r3.in.unknown = 0;
7994         r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7995         r3.out.connect_handle = &h;
7996
7997         torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect3_r(b, tctx, &r3),
7998                 "Connect3 failed");
7999         if (!NT_STATUS_IS_OK(r3.out.result)) {
8000                 torture_warning(tctx, "Connect3 failed - %s\n", nt_errstr(r3.out.result));
8001                 ret = false;
8002         } else {
8003                 if (got_handle) {
8004                         test_samr_handle_Close(b, tctx, handle);
8005                 }
8006                 got_handle = true;
8007                 *handle = h;
8008         }
8009
8010         torture_comment(tctx, "Testing samr_Connect4\n");
8011
8012         r4.in.system_name = "";
8013         r4.in.client_version = 0;
8014         r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
8015         r4.out.connect_handle = &h;
8016
8017         torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect4_r(b, tctx, &r4),
8018                 "Connect4 failed");
8019         if (!NT_STATUS_IS_OK(r4.out.result)) {
8020                 torture_warning(tctx, "Connect4 failed - %s\n", nt_errstr(r4.out.result));
8021                 ret = false;
8022         } else {
8023                 if (got_handle) {
8024                         test_samr_handle_Close(b, tctx, handle);
8025                 }
8026                 got_handle = true;
8027                 *handle = h;
8028         }
8029
8030         torture_comment(tctx, "Testing samr_Connect5\n");
8031
8032         info.info1.client_version = 0;
8033         info.info1.unknown2 = 0;
8034
8035         r5.in.system_name = "";
8036         r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
8037         r5.in.level_in = 1;
8038         r5.out.level_out = &level_out;
8039         r5.in.info_in = &info;
8040         r5.out.info_out = &info;
8041         r5.out.connect_handle = &h;
8042
8043         torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect5_r(b, tctx, &r5),
8044                 "Connect5 failed");
8045         if (!NT_STATUS_IS_OK(r5.out.result)) {
8046                 torture_warning(tctx, "Connect5 failed - %s\n", nt_errstr(r5.out.result));
8047                 ret = false;
8048         } else {
8049                 if (got_handle) {
8050                         test_samr_handle_Close(b, tctx, handle);
8051                 }
8052                 got_handle = true;
8053                 *handle = h;
8054         }
8055
8056         return ret;
8057 }
8058
8059
8060 static bool test_samr_ValidatePassword(struct torture_context *tctx,
8061                                        struct dcerpc_pipe *p)
8062 {
8063         struct samr_ValidatePassword r;
8064         union samr_ValidatePasswordReq req;
8065         union samr_ValidatePasswordRep *repp = NULL;
8066         NTSTATUS status;
8067         const char *passwords[] = { "penguin", "p@ssw0rd", "p@ssw0rd123$", NULL };
8068         int i;
8069         struct dcerpc_binding_handle *b = p->binding_handle;
8070
8071         torture_comment(tctx, "Testing samr_ValidatePassword\n");
8072
8073         if (p->conn->transport.transport != NCACN_IP_TCP) {
8074                 torture_comment(tctx, "samr_ValidatePassword only should succeed over NCACN_IP_TCP!\n");
8075         }
8076
8077         ZERO_STRUCT(r);
8078         r.in.level = NetValidatePasswordReset;
8079         r.in.req = &req;
8080         r.out.rep = &repp;
8081
8082         ZERO_STRUCT(req);
8083         req.req3.account.string = "non-existent-account-aklsdji";
8084
8085         for (i=0; passwords[i]; i++) {
8086                 req.req3.password.string = passwords[i];
8087
8088                 status = dcerpc_samr_ValidatePassword_r(b, tctx, &r);
8089                 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
8090                         torture_skip(tctx, "ValidatePassword not supported by server\n");
8091                 }
8092                 torture_assert_ntstatus_ok(tctx, status,
8093                                            "samr_ValidatePassword failed");
8094                 torture_assert_ntstatus_ok(tctx, r.out.result,
8095                                            "samr_ValidatePassword failed");
8096                 torture_comment(tctx, "Server %s password '%s' with code %i\n",
8097                                 repp->ctr3.status==SAMR_VALIDATION_STATUS_SUCCESS?"allowed":"refused",
8098                                 req.req3.password.string, repp->ctr3.status);
8099         }
8100
8101         return true;
8102 }
8103
8104 bool torture_rpc_samr(struct torture_context *torture)
8105 {
8106         NTSTATUS status;
8107         struct dcerpc_pipe *p;
8108         bool ret = true;
8109         struct torture_samr_context *ctx;
8110         struct dcerpc_binding_handle *b;
8111
8112         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8113         if (!NT_STATUS_IS_OK(status)) {
8114                 return false;
8115         }
8116         b = p->binding_handle;
8117
8118         ctx = talloc_zero(torture, struct torture_samr_context);
8119
8120         ctx->choice = TORTURE_SAMR_OTHER;
8121
8122         ret &= test_Connect(b, torture, &ctx->handle);
8123
8124         if (!torture_setting_bool(torture, "samba3", false)) {
8125                 ret &= test_QuerySecurity(b, torture, &ctx->handle);
8126         }
8127
8128         ret &= test_EnumDomains(p, torture, ctx);
8129
8130         ret &= test_SetDsrmPassword(b, torture, &ctx->handle);
8131
8132         ret &= test_Shutdown(b, torture, &ctx->handle);
8133
8134         ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8135
8136         return ret;
8137 }
8138
8139
8140 bool torture_rpc_samr_users(struct torture_context *torture)
8141 {
8142         NTSTATUS status;
8143         struct dcerpc_pipe *p;
8144         bool ret = true;
8145         struct torture_samr_context *ctx;
8146         struct dcerpc_binding_handle *b;
8147
8148         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8149         if (!NT_STATUS_IS_OK(status)) {
8150                 return false;
8151         }
8152         b = p->binding_handle;
8153
8154         ctx = talloc_zero(torture, struct torture_samr_context);
8155
8156         ctx->choice = TORTURE_SAMR_USER_ATTRIBUTES;
8157
8158         ret &= test_Connect(b, torture, &ctx->handle);
8159
8160         if (!torture_setting_bool(torture, "samba3", false)) {
8161                 ret &= test_QuerySecurity(b, torture, &ctx->handle);
8162         }
8163
8164         ret &= test_EnumDomains(p, torture, ctx);
8165
8166         ret &= test_SetDsrmPassword(b, torture, &ctx->handle);
8167
8168         ret &= test_Shutdown(b, torture, &ctx->handle);
8169
8170         ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8171
8172         return ret;
8173 }
8174
8175
8176 bool torture_rpc_samr_passwords(struct torture_context *torture)
8177 {
8178         NTSTATUS status;
8179         struct dcerpc_pipe *p;
8180         bool ret = true;
8181         struct torture_samr_context *ctx;
8182         struct dcerpc_binding_handle *b;
8183
8184         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8185         if (!NT_STATUS_IS_OK(status)) {
8186                 return false;
8187         }
8188         b = p->binding_handle;
8189
8190         ctx = talloc_zero(torture, struct torture_samr_context);
8191
8192         ctx->choice = TORTURE_SAMR_PASSWORDS;
8193
8194         ret &= test_Connect(b, torture, &ctx->handle);
8195
8196         ret &= test_EnumDomains(p, torture, ctx);
8197
8198         ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8199
8200         return ret;
8201 }
8202
8203 static bool torture_rpc_samr_pwdlastset(struct torture_context *torture,
8204                                         struct dcerpc_pipe *p2,
8205                                         struct cli_credentials *machine_credentials)
8206 {
8207         NTSTATUS status;
8208         struct dcerpc_pipe *p;
8209         bool ret = true;
8210         struct torture_samr_context *ctx;
8211         struct dcerpc_binding_handle *b;
8212
8213         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8214         if (!NT_STATUS_IS_OK(status)) {
8215                 return false;
8216         }
8217         b = p->binding_handle;
8218
8219         ctx = talloc_zero(torture, struct torture_samr_context);
8220
8221         ctx->choice = TORTURE_SAMR_PASSWORDS_PWDLASTSET;
8222         ctx->machine_credentials = machine_credentials;
8223
8224         ret &= test_Connect(b, torture, &ctx->handle);
8225
8226         ret &= test_EnumDomains(p, torture, ctx);
8227
8228         ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8229
8230         return ret;
8231 }
8232
8233 struct torture_suite *torture_rpc_samr_passwords_pwdlastset(TALLOC_CTX *mem_ctx)
8234 {
8235         struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.pwdlastset");
8236         struct torture_rpc_tcase *tcase;
8237
8238         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8239                                                           &ndr_table_samr,
8240                                                           TEST_ACCOUNT_NAME_PWD);
8241
8242         torture_rpc_tcase_add_test_creds(tcase, "pwdLastSet",
8243                                          torture_rpc_samr_pwdlastset);
8244
8245         return suite;
8246 }
8247
8248 static bool torture_rpc_samr_users_privileges_delete_user(struct torture_context *torture,
8249                                                           struct dcerpc_pipe *p2,
8250                                                           struct cli_credentials *machine_credentials)
8251 {
8252         NTSTATUS status;
8253         struct dcerpc_pipe *p;
8254         bool ret = true;
8255         struct torture_samr_context *ctx;
8256         struct dcerpc_binding_handle *b;
8257
8258         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8259         if (!NT_STATUS_IS_OK(status)) {
8260                 return false;
8261         }
8262         b = p->binding_handle;
8263
8264         ctx = talloc_zero(torture, struct torture_samr_context);
8265
8266         ctx->choice = TORTURE_SAMR_USER_PRIVILEGES;
8267         ctx->machine_credentials = machine_credentials;
8268
8269         ret &= test_Connect(b, torture, &ctx->handle);
8270
8271         ret &= test_EnumDomains(p, torture, ctx);
8272
8273         ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8274
8275         return ret;
8276 }
8277
8278 struct torture_suite *torture_rpc_samr_user_privileges(TALLOC_CTX *mem_ctx)
8279 {
8280         struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.users.privileges");
8281         struct torture_rpc_tcase *tcase;
8282
8283         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8284                                                           &ndr_table_samr,
8285                                                           TEST_ACCOUNT_NAME_PWD);
8286
8287         torture_rpc_tcase_add_test_creds(tcase, "delete_privileged_user",
8288                                          torture_rpc_samr_users_privileges_delete_user);
8289
8290         return suite;
8291 }
8292
8293 static bool torture_rpc_samr_many_accounts(struct torture_context *torture,
8294                                            struct dcerpc_pipe *p2,
8295                                            void *data)
8296 {
8297         NTSTATUS status;
8298         struct dcerpc_pipe *p;
8299         bool ret = true;
8300         struct torture_samr_context *ctx =
8301                 talloc_get_type_abort(data, struct torture_samr_context);
8302         struct dcerpc_binding_handle *b;
8303
8304         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8305         if (!NT_STATUS_IS_OK(status)) {
8306                 return false;
8307         }
8308         b = p->binding_handle;
8309
8310         ctx->choice = TORTURE_SAMR_MANY_ACCOUNTS;
8311         ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8312                                                         ctx->num_objects_large_dc);
8313
8314         ret &= test_Connect(b, torture, &ctx->handle);
8315
8316         ret &= test_EnumDomains(p, torture, ctx);
8317
8318         ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8319
8320         return ret;
8321 }
8322
8323 static bool torture_rpc_samr_many_groups(struct torture_context *torture,
8324                                          struct dcerpc_pipe *p2,
8325                                          void *data)
8326 {
8327         NTSTATUS status;
8328         struct dcerpc_pipe *p;
8329         bool ret = true;
8330         struct torture_samr_context *ctx =
8331                 talloc_get_type_abort(data, struct torture_samr_context);
8332         struct dcerpc_binding_handle *b;
8333
8334         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8335         if (!NT_STATUS_IS_OK(status)) {
8336                 return false;
8337         }
8338         b = p->binding_handle;
8339
8340         ctx->choice = TORTURE_SAMR_MANY_GROUPS;
8341         ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8342                                                         ctx->num_objects_large_dc);
8343
8344         ret &= test_Connect(b, torture, &ctx->handle);
8345
8346         ret &= test_EnumDomains(p, torture, ctx);
8347
8348         ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8349
8350         return ret;
8351 }
8352
8353 static bool torture_rpc_samr_many_aliases(struct torture_context *torture,
8354                                           struct dcerpc_pipe *p2,
8355                                           void *data)
8356 {
8357         NTSTATUS status;
8358         struct dcerpc_pipe *p;
8359         bool ret = true;
8360         struct torture_samr_context *ctx =
8361                 talloc_get_type_abort(data, struct torture_samr_context);
8362         struct dcerpc_binding_handle *b;
8363
8364         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8365         if (!NT_STATUS_IS_OK(status)) {
8366                 return false;
8367         }
8368         b = p->binding_handle;
8369
8370         ctx->choice = TORTURE_SAMR_MANY_ALIASES;
8371         ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8372                                                         ctx->num_objects_large_dc);
8373
8374         ret &= test_Connect(b, torture, &ctx->handle);
8375
8376         ret &= test_EnumDomains(p, torture, ctx);
8377
8378         ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8379
8380         return ret;
8381 }
8382
8383 struct torture_suite *torture_rpc_samr_large_dc(TALLOC_CTX *mem_ctx)
8384 {
8385         struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.large-dc");
8386         struct torture_rpc_tcase *tcase;
8387         struct torture_samr_context *ctx;
8388
8389         tcase = torture_suite_add_rpc_iface_tcase(suite, "samr", &ndr_table_samr);
8390
8391         ctx = talloc_zero(suite, struct torture_samr_context);
8392         ctx->num_objects_large_dc = 150;
8393
8394         torture_rpc_tcase_add_test_ex(tcase, "many_aliases",
8395                                       torture_rpc_samr_many_aliases, ctx);
8396         torture_rpc_tcase_add_test_ex(tcase, "many_groups",
8397                                       torture_rpc_samr_many_groups, ctx);
8398         torture_rpc_tcase_add_test_ex(tcase, "many_accounts",
8399                                       torture_rpc_samr_many_accounts, ctx);
8400
8401         return suite;
8402 }
8403
8404 static bool torture_rpc_samr_badpwdcount(struct torture_context *torture,
8405                                          struct dcerpc_pipe *p2,
8406                                          struct cli_credentials *machine_credentials)
8407 {
8408         NTSTATUS status;
8409         struct dcerpc_pipe *p;
8410         bool ret = true;
8411         struct torture_samr_context *ctx;
8412         struct dcerpc_binding_handle *b;
8413
8414         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8415         if (!NT_STATUS_IS_OK(status)) {
8416                 return false;
8417         }
8418         b = p->binding_handle;
8419
8420         ctx = talloc_zero(torture, struct torture_samr_context);
8421
8422         ctx->choice = TORTURE_SAMR_PASSWORDS_BADPWDCOUNT;
8423         ctx->machine_credentials = machine_credentials;
8424
8425         ret &= test_Connect(b, torture, &ctx->handle);
8426
8427         ret &= test_EnumDomains(p, torture, ctx);
8428
8429         ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8430
8431         return ret;
8432 }
8433
8434 struct torture_suite *torture_rpc_samr_passwords_badpwdcount(TALLOC_CTX *mem_ctx)
8435 {
8436         struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.badpwdcount");
8437         struct torture_rpc_tcase *tcase;
8438
8439         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8440                                                           &ndr_table_samr,
8441                                                           TEST_ACCOUNT_NAME_PWD);
8442
8443         torture_rpc_tcase_add_test_creds(tcase, "badPwdCount",
8444                                          torture_rpc_samr_badpwdcount);
8445
8446         return suite;
8447 }
8448
8449 static bool torture_rpc_samr_lockout(struct torture_context *torture,
8450                                      struct dcerpc_pipe *p2,
8451                                      struct cli_credentials *machine_credentials)
8452 {
8453         NTSTATUS status;
8454         struct dcerpc_pipe *p;
8455         bool ret = true;
8456         struct torture_samr_context *ctx;
8457         struct dcerpc_binding_handle *b;
8458
8459         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8460         if (!NT_STATUS_IS_OK(status)) {
8461                 return false;
8462         }
8463         b = p->binding_handle;
8464
8465         ctx = talloc_zero(torture, struct torture_samr_context);
8466
8467         ctx->choice = TORTURE_SAMR_PASSWORDS_LOCKOUT;
8468         ctx->machine_credentials = machine_credentials;
8469
8470         ret &= test_Connect(b, torture, &ctx->handle);
8471
8472         ret &= test_EnumDomains(p, torture, ctx);
8473
8474         ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8475
8476         return ret;
8477 }
8478
8479 struct torture_suite *torture_rpc_samr_passwords_lockout(TALLOC_CTX *mem_ctx)
8480 {
8481         struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.lockout");
8482         struct torture_rpc_tcase *tcase;
8483
8484         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8485                                                           &ndr_table_samr,
8486                                                           TEST_ACCOUNT_NAME_PWD);
8487
8488         torture_rpc_tcase_add_test_creds(tcase, "lockout",
8489                                          torture_rpc_samr_lockout);
8490
8491         return suite;
8492 }
8493
8494 struct torture_suite *torture_rpc_samr_passwords_validate(TALLOC_CTX *mem_ctx)
8495 {
8496         struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.validate");
8497         struct torture_rpc_tcase *tcase;
8498
8499         tcase = torture_suite_add_rpc_iface_tcase(suite, "samr",
8500                                                   &ndr_table_samr);
8501         torture_rpc_tcase_add_test(tcase, "validate",
8502                                    test_samr_ValidatePassword);
8503
8504         return suite;
8505 }