s4-torture: fix some build warnings in rpc samr test.
[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_result(tctx, TORTURE_FAIL, #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_result(tctx, TORTURE_FAIL, "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_result(tctx, TORTURE_FAIL, "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_result(tctx, TORTURE_FAIL, "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, test_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, test_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, test_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, test_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, test_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, test_account_name, 0);
377         test_account_name = base_account_name;
378         TEST_USERINFO_STRING(21, account_name, 21, account_name, test_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_result(tctx, TORTURE_FAIL, "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_result(tctx, TORTURE_FAIL, "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_result(tctx, TORTURE_FAIL, "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_result(tctx, TORTURE_FAIL, "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_result(tctx, TORTURE_FAIL, "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_result(tctx, TORTURE_FAIL, "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_result(tctx, TORTURE_FAIL, "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_result(tctx, TORTURE_FAIL, "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_result(tctx, TORTURE_FAIL, "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_result(tctx, TORTURE_FAIL, "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_result(tctx, TORTURE_FAIL, "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_result(tctx, TORTURE_FAIL, "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_result(tctx, TORTURE_FAIL, "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_result(tctx, TORTURE_FAIL, "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_result(tctx, TORTURE_FAIL, "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_result(tctx, TORTURE_FAIL, "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_result(tctx, TORTURE_FAIL, "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_result(tctx, TORTURE_FAIL, "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_result(tctx, TORTURE_FAIL, "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_result(tctx, TORTURE_FAIL, "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_result(tctx, TORTURE_FAIL, "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_result(tctx, TORTURE_FAIL, "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_result(tctx, TORTURE_FAIL, "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_result(tctx, TORTURE_FAIL, "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_result(tctx, TORTURE_FAIL, "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_result(tctx, TORTURE_FAIL, "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_result(tctx, TORTURE_FAIL, "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_result(tctx, TORTURE_FAIL, "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 NT hash */
1745         hash3.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 NT hash */
1773         hash3.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 LM hash */
1780         hash1.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_result(tctx, TORTURE_FAIL, "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_result(tctx, TORTURE_FAIL, "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_result(tctx, TORTURE_FAIL, "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_result(tctx, TORTURE_FAIL, "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_result(tctx, TORTURE_FAIL, "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_result(tctx, TORTURE_FAIL, "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_result(tctx, TORTURE_FAIL, "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_result(tctx, TORTURE_FAIL, "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_result(tctx, TORTURE_FAIL, "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_result(tctx, TORTURE_FAIL, "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_result(tctx, TORTURE_FAIL, "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_result(tctx, TORTURE_FAIL, "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_result(tctx, TORTURE_FAIL, "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_result(tctx, TORTURE_FAIL, "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 static bool test_ChangePasswordUser2_ntstatus(struct dcerpc_pipe *p, struct torture_context *tctx,
2302                                               const char *acct_name,
2303                                               const char *password, NTSTATUS status)
2304 {
2305         struct samr_ChangePasswordUser2 r;
2306         struct lsa_String server, account;
2307         struct samr_CryptPassword nt_pass, lm_pass;
2308         struct samr_Password nt_verifier, lm_verifier;
2309         const char *oldpass;
2310         struct dcerpc_binding_handle *b = p->binding_handle;
2311         uint8_t old_nt_hash[16], new_nt_hash[16];
2312         uint8_t old_lm_hash[16], new_lm_hash[16];
2313
2314         struct samr_GetDomPwInfo dom_pw_info;
2315         struct samr_PwInfo info;
2316
2317         struct lsa_String domain_name;
2318         char *newpass;
2319         int policy_min_pw_len = 0;
2320
2321         domain_name.string = "";
2322         dom_pw_info.in.domain_name = &domain_name;
2323         dom_pw_info.out.info = &info;
2324
2325         torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
2326
2327         oldpass = password;
2328
2329         torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDomPwInfo_r(b, tctx, &dom_pw_info),
2330                                    "GetDomPwInfo failed");
2331         if (NT_STATUS_IS_OK(dom_pw_info.out.result)) {
2332                 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
2333         }
2334
2335         newpass = samr_rand_pass(tctx, policy_min_pw_len);
2336
2337         server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2338         init_lsa_String(&account, acct_name);
2339
2340         E_md4hash(oldpass, old_nt_hash);
2341         E_md4hash(newpass, new_nt_hash);
2342
2343         E_deshash(oldpass, old_lm_hash);
2344         E_deshash(newpass, new_lm_hash);
2345
2346         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
2347         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2348         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2349
2350         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2351         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2352         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2353
2354         r.in.server = &server;
2355         r.in.account = &account;
2356         r.in.nt_password = &nt_pass;
2357         r.in.nt_verifier = &nt_verifier;
2358         r.in.lm_change = 1;
2359         r.in.lm_password = &lm_pass;
2360         r.in.lm_verifier = &lm_verifier;
2361
2362         torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser2_r(b, tctx, &r),
2363                 "ChangePasswordUser2 failed");
2364         torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2365                         __location__, __FUNCTION__,
2366                         oldpass, newpass, nt_errstr(r.out.result));
2367
2368         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2369                 torture_comment(tctx, "ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(r.out.result));
2370         } else {
2371                 torture_assert_ntstatus_equal(tctx, r.out.result, status, "ChangePasswordUser2 returned unexpected value");
2372         }
2373
2374         return true;
2375 }
2376
2377
2378 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
2379                               const char *account_string,
2380                               int policy_min_pw_len,
2381                               char **password,
2382                               const char *newpass,
2383                               NTTIME last_password_change,
2384                               bool handle_reject_reason)
2385 {
2386         struct samr_ChangePasswordUser3 r;
2387         bool ret = true;
2388         struct lsa_String server, account, account_bad;
2389         struct samr_CryptPassword nt_pass, lm_pass;
2390         struct samr_Password nt_verifier, lm_verifier;
2391         char *oldpass;
2392         struct dcerpc_binding_handle *b = p->binding_handle;
2393         uint8_t old_nt_hash[16], new_nt_hash[16];
2394         uint8_t old_lm_hash[16], new_lm_hash[16];
2395         NTTIME t;
2396         struct samr_DomInfo1 *dominfo = NULL;
2397         struct userPwdChangeFailureInformation *reject = NULL;
2398
2399         torture_comment(tctx, "Testing ChangePasswordUser3\n");
2400
2401         if (newpass == NULL) {
2402                 do {
2403                         if (policy_min_pw_len == 0) {
2404                                 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2405                         } else {
2406                                 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
2407                         }
2408                 } while (check_password_quality(newpass) == false);
2409         } else {
2410                 torture_comment(tctx, "Using password '%s'\n", newpass);
2411         }
2412
2413         torture_assert(tctx, *password != NULL,
2414                                    "Failing ChangePasswordUser3 as old password was NULL.  Previous test failed?");
2415
2416         oldpass = *password;
2417         server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2418         init_lsa_String(&account, account_string);
2419
2420         E_md4hash(oldpass, old_nt_hash);
2421         E_md4hash(newpass, new_nt_hash);
2422
2423         E_deshash(oldpass, old_lm_hash);
2424         E_deshash(newpass, new_lm_hash);
2425
2426         encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2427         arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2428         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2429
2430         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2431         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2432         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2433
2434         /* Break the verification */
2435         nt_verifier.hash[0]++;
2436
2437         r.in.server = &server;
2438         r.in.account = &account;
2439         r.in.nt_password = &nt_pass;
2440         r.in.nt_verifier = &nt_verifier;
2441         r.in.lm_change = 1;
2442         r.in.lm_password = &lm_pass;
2443         r.in.lm_verifier = &lm_verifier;
2444         r.in.password3 = NULL;
2445         r.out.dominfo = &dominfo;
2446         r.out.reject = &reject;
2447
2448         torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2449                 "ChangePasswordUser3 failed");
2450         torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2451                         __location__, __FUNCTION__,
2452                         oldpass, newpass, nt_errstr(r.out.result));
2453         if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION) &&
2454             (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD))) {
2455                 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2456                         nt_errstr(r.out.result));
2457                 ret = false;
2458         }
2459
2460         encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2461         arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2462         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2463
2464         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2465         /* Break the NT hash */
2466         old_nt_hash[0]++;
2467         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2468         /* Unbreak it again */
2469         old_nt_hash[0]--;
2470         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2471
2472         r.in.server = &server;
2473         r.in.account = &account;
2474         r.in.nt_password = &nt_pass;
2475         r.in.nt_verifier = &nt_verifier;
2476         r.in.lm_change = 1;
2477         r.in.lm_password = &lm_pass;
2478         r.in.lm_verifier = &lm_verifier;
2479         r.in.password3 = NULL;
2480         r.out.dominfo = &dominfo;
2481         r.out.reject = &reject;
2482
2483         torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2484                 "ChangePasswordUser3 failed");
2485         torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2486                         __location__, __FUNCTION__,
2487                         oldpass, newpass, nt_errstr(r.out.result));
2488         if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION) &&
2489             (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD))) {
2490                 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2491                         nt_errstr(r.out.result));
2492                 ret = false;
2493         }
2494
2495         /* This shouldn't be a valid name */
2496         init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
2497
2498         r.in.account = &account_bad;
2499         torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2500                 "ChangePasswordUser3 failed");
2501         torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2502                         __location__, __FUNCTION__,
2503                         oldpass, newpass, nt_errstr(r.out.result));
2504         if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
2505                 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
2506                         nt_errstr(r.out.result));
2507                 ret = false;
2508         }
2509
2510         E_md4hash(oldpass, old_nt_hash);
2511         E_md4hash(newpass, new_nt_hash);
2512
2513         E_deshash(oldpass, old_lm_hash);
2514         E_deshash(newpass, new_lm_hash);
2515
2516         encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2517         arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2518         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2519
2520         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2521         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2522         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2523
2524         r.in.server = &server;
2525         r.in.account = &account;
2526         r.in.nt_password = &nt_pass;
2527         r.in.nt_verifier = &nt_verifier;
2528         r.in.lm_change = 1;
2529         r.in.lm_password = &lm_pass;
2530         r.in.lm_verifier = &lm_verifier;
2531         r.in.password3 = NULL;
2532         r.out.dominfo = &dominfo;
2533         r.out.reject = &reject;
2534
2535         unix_to_nt_time(&t, time(NULL));
2536
2537         torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2538                 "ChangePasswordUser3 failed");
2539         torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2540                         __location__, __FUNCTION__,
2541                         oldpass, newpass, nt_errstr(r.out.result));
2542
2543         torture_comment(tctx, "(%s): dominfo[%s], reject[%s], handle_reject_reason[%s], "
2544                         "last_password_change[%s], dominfo->min_password_age[%lld]\n",
2545                         __location__,
2546                         (dominfo == NULL)? "NULL" : "present",
2547                         reject ? "true" : "false",
2548                         handle_reject_reason ? "true" : "false",
2549                         null_nttime(last_password_change) ? "null" : "not null",
2550                         dominfo ? (long long)dominfo->min_password_age : (long long)0);
2551
2552         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)
2553             && dominfo
2554             && reject
2555             && handle_reject_reason
2556             && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
2557                 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
2558
2559                         if (reject && (reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR)) {
2560                                 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2561                                         SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2562                                 return false;
2563                         }
2564                 }
2565
2566                 /* We tested the order of precendence which is as follows:
2567
2568                 * pwd min_age
2569                 * pwd length
2570                 * pwd complexity
2571                 * pwd history
2572
2573                 Guenther */
2574
2575                 if ((dominfo->min_password_age < 0) && !null_nttime(last_password_change) &&
2576                            (last_password_change - dominfo->min_password_age > t)) {
2577
2578                         if (reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2579                                 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2580                                         SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2581                                 return false;
2582                         }
2583
2584                 } else if ((dominfo->min_password_length > 0) &&
2585                            (strlen(newpass) < dominfo->min_password_length)) {
2586
2587                         if (reject->extendedFailureReason != SAM_PWD_CHANGE_PASSWORD_TOO_SHORT) {
2588                                 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_PASSWORD_TOO_SHORT (%d), got %d\n",
2589                                         SAM_PWD_CHANGE_PASSWORD_TOO_SHORT, reject->extendedFailureReason);
2590                                 return false;
2591                         }
2592
2593                 } else if ((dominfo->password_history_length > 0) &&
2594                             strequal(oldpass, newpass)) {
2595
2596                         if (reject->extendedFailureReason != SAM_PWD_CHANGE_PWD_IN_HISTORY) {
2597                                 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_PWD_IN_HISTORY (%d), got %d\n",
2598                                         SAM_PWD_CHANGE_PWD_IN_HISTORY, reject->extendedFailureReason);
2599                                 return false;
2600                         }
2601                 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
2602
2603                         if (reject->extendedFailureReason != SAM_PWD_CHANGE_NOT_COMPLEX) {
2604                                 torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_NOT_COMPLEX (%d), got %d\n",
2605                                         SAM_PWD_CHANGE_NOT_COMPLEX, reject->extendedFailureReason);
2606                                 return false;
2607                         }
2608
2609                 }
2610
2611                 if (reject->extendedFailureReason == SAM_PWD_CHANGE_PASSWORD_TOO_SHORT) {
2612                         /* retry with adjusted size */
2613                         return test_ChangePasswordUser3(p, tctx, account_string,
2614                                                         dominfo->min_password_length,
2615                                                         password, NULL, 0, false);
2616
2617                 }
2618
2619         } else if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2620                 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2621                         torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2622                                SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2623                         return false;
2624                 }
2625                 /* Perhaps the server has a 'min password age' set? */
2626
2627         } else {
2628                 torture_assert_ntstatus_ok(tctx, r.out.result, "ChangePasswordUser3");
2629
2630                 *password = talloc_strdup(tctx, newpass);
2631         }
2632
2633         return ret;
2634 }
2635
2636 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
2637                                     const char *account_string,
2638                                     struct policy_handle *handle,
2639                                     char **password)
2640 {
2641         NTSTATUS status;
2642         struct samr_ChangePasswordUser3 r;
2643         struct samr_SetUserInfo s;
2644         union samr_UserInfo u;
2645         DATA_BLOB session_key;
2646         DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
2647         uint8_t confounder[16];
2648         MD5_CTX ctx;
2649
2650         bool ret = true;
2651         struct lsa_String server, account;
2652         struct samr_CryptPassword nt_pass;
2653         struct samr_Password nt_verifier;
2654         DATA_BLOB new_random_pass;
2655         char *newpass;
2656         char *oldpass;
2657         struct dcerpc_binding_handle *b = p->binding_handle;
2658         uint8_t old_nt_hash[16], new_nt_hash[16];
2659         NTTIME t;
2660         struct samr_DomInfo1 *dominfo = NULL;
2661         struct userPwdChangeFailureInformation *reject = NULL;
2662
2663         new_random_pass = samr_very_rand_pass(tctx, 128);
2664
2665         torture_assert(tctx, *password != NULL,
2666                                    "Failing ChangePasswordUser3 as old password was NULL.  Previous test failed?");
2667
2668         oldpass = *password;
2669         server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2670         init_lsa_String(&account, account_string);
2671
2672         s.in.user_handle = handle;
2673         s.in.info = &u;
2674         s.in.level = 25;
2675
2676         ZERO_STRUCT(u);
2677
2678         u.info25.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT;
2679
2680         set_pw_in_buffer(u.info25.password.data, &new_random_pass);
2681
2682         status = dcerpc_fetch_session_key(p, &session_key);
2683         if (!NT_STATUS_IS_OK(status)) {
2684                 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u - no session key - %s\n",
2685                        s.in.level, nt_errstr(status));
2686                 return false;
2687         }
2688
2689         generate_random_buffer((uint8_t *)confounder, 16);
2690
2691         MD5Init(&ctx);
2692         MD5Update(&ctx, confounder, 16);
2693         MD5Update(&ctx, session_key.data, session_key.length);
2694         MD5Final(confounded_session_key.data, &ctx);
2695
2696         arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
2697         memcpy(&u.info25.password.data[516], confounder, 16);
2698
2699         torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2700
2701         torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &s),
2702                 "SetUserInfo failed");
2703         torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2704                         __location__, __FUNCTION__,
2705                         oldpass, "RANDOM", nt_errstr(s.out.result));
2706         if (!NT_STATUS_IS_OK(s.out.result)) {
2707                 torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u failed - %s\n",
2708                        s.in.level, nt_errstr(s.out.result));
2709                 ret = false;
2710         }
2711
2712         torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2713
2714         mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2715
2716         new_random_pass = samr_very_rand_pass(tctx, 128);
2717
2718         mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
2719
2720         set_pw_in_buffer(nt_pass.data, &new_random_pass);
2721         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2722         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2723
2724         r.in.server = &server;
2725         r.in.account = &account;
2726         r.in.nt_password = &nt_pass;
2727         r.in.nt_verifier = &nt_verifier;
2728         r.in.lm_change = 0;
2729         r.in.lm_password = NULL;
2730         r.in.lm_verifier = NULL;
2731         r.in.password3 = NULL;
2732         r.out.dominfo = &dominfo;
2733         r.out.reject = &reject;
2734
2735         unix_to_nt_time(&t, time(NULL));
2736
2737         torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2738                 "ChangePasswordUser3 failed");
2739         torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2740                         __location__, __FUNCTION__,
2741                         oldpass, "RANDOM", nt_errstr(r.out.result));
2742
2743         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2744                 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2745                         torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2746                                SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2747                         return false;
2748                 }
2749                 /* Perhaps the server has a 'min password age' set? */
2750
2751         } else if (!NT_STATUS_IS_OK(r.out.result)) {
2752                 torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser3 failed - %s\n", nt_errstr(r.out.result));
2753                 ret = false;
2754         }
2755
2756         newpass = samr_rand_pass(tctx, 128);
2757
2758         mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2759
2760         E_md4hash(newpass, new_nt_hash);
2761
2762         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2763         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2764         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2765
2766         r.in.server = &server;
2767         r.in.account = &account;
2768         r.in.nt_password = &nt_pass;
2769         r.in.nt_verifier = &nt_verifier;
2770         r.in.lm_change = 0;
2771         r.in.lm_password = NULL;
2772         r.in.lm_verifier = NULL;
2773         r.in.password3 = NULL;
2774         r.out.dominfo = &dominfo;
2775         r.out.reject = &reject;
2776
2777         unix_to_nt_time(&t, time(NULL));
2778
2779         torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser3_r(b, tctx, &r),
2780                 "ChangePasswordUser3 failed");
2781         torture_comment(tctx, "(%s:%s) old_password[%s] new_password[%s] status[%s]\n",
2782                         __location__, __FUNCTION__,
2783                         oldpass, newpass, nt_errstr(r.out.result));
2784
2785         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
2786                 if (reject && reject->extendedFailureReason != SAM_PWD_CHANGE_NO_ERROR) {
2787                         torture_result(tctx, TORTURE_FAIL, "expected SAM_PWD_CHANGE_NO_ERROR (%d), got %d\n",
2788                                SAM_PWD_CHANGE_NO_ERROR, reject->extendedFailureReason);
2789                         return false;
2790                 }
2791                 /* Perhaps the server has a 'min password age' set? */
2792
2793         } else {
2794                 torture_assert_ntstatus_ok(tctx, r.out.result, "ChangePasswordUser3 (on second random password)");
2795                 *password = talloc_strdup(tctx, newpass);
2796         }
2797
2798         return ret;
2799 }
2800
2801
2802 static bool test_GetMembersInAlias(struct dcerpc_binding_handle *b,
2803                                    struct torture_context *tctx,
2804                                    struct policy_handle *alias_handle)
2805 {
2806         struct samr_GetMembersInAlias r;
2807         struct lsa_SidArray sids;
2808
2809         torture_comment(tctx, "Testing GetMembersInAlias\n");
2810
2811         r.in.alias_handle = alias_handle;
2812         r.out.sids = &sids;
2813
2814         torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetMembersInAlias_r(b, tctx, &r),
2815                 "GetMembersInAlias failed");
2816         torture_assert_ntstatus_ok(tctx, r.out.result, "GetMembersInAlias failed");
2817
2818         return true;
2819 }
2820
2821 static bool test_AddMemberToAlias(struct dcerpc_binding_handle *b,
2822                                   struct torture_context *tctx,
2823                                   struct policy_handle *alias_handle,
2824                                   const struct dom_sid *domain_sid)
2825 {
2826         struct samr_AddAliasMember r;
2827         struct samr_DeleteAliasMember d;
2828         struct dom_sid *sid;
2829
2830         sid = dom_sid_add_rid(tctx, domain_sid, 512);
2831
2832         torture_comment(tctx, "Testing AddAliasMember\n");
2833         r.in.alias_handle = alias_handle;
2834         r.in.sid = sid;
2835
2836         torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddAliasMember_r(b, tctx, &r),
2837                 "AddAliasMember failed");
2838         torture_assert_ntstatus_ok(tctx, r.out.result, "AddAliasMember failed");
2839
2840         d.in.alias_handle = alias_handle;
2841         d.in.sid = sid;
2842
2843         torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteAliasMember_r(b, tctx, &d),
2844                 "DeleteAliasMember failed");
2845         torture_assert_ntstatus_ok(tctx, d.out.result, "DelAliasMember failed");
2846
2847         return true;
2848 }
2849
2850 static bool test_AddMultipleMembersToAlias(struct dcerpc_binding_handle *b,
2851                                            struct torture_context *tctx,
2852                                            struct policy_handle *alias_handle)
2853 {
2854         struct samr_AddMultipleMembersToAlias a;
2855         struct samr_RemoveMultipleMembersFromAlias r;
2856         struct lsa_SidArray sids;
2857
2858         torture_comment(tctx, "Testing AddMultipleMembersToAlias\n");
2859         a.in.alias_handle = alias_handle;
2860         a.in.sids = &sids;
2861
2862         sids.num_sids = 3;
2863         sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2864
2865         sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2866         sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2867         sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2868
2869         torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddMultipleMembersToAlias_r(b, tctx, &a),
2870                 "AddMultipleMembersToAlias failed");
2871         torture_assert_ntstatus_ok(tctx, a.out.result, "AddMultipleMembersToAlias");
2872
2873
2874         torture_comment(tctx, "Testing RemoveMultipleMembersFromAlias\n");
2875         r.in.alias_handle = alias_handle;
2876         r.in.sids = &sids;
2877
2878         torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b, tctx, &r),
2879                 "RemoveMultipleMembersFromAlias failed");
2880         torture_assert_ntstatus_ok(tctx, r.out.result, "RemoveMultipleMembersFromAlias failed");
2881
2882         /* strange! removing twice doesn't give any error */
2883         torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b, tctx, &r),
2884                 "RemoveMultipleMembersFromAlias failed");
2885         torture_assert_ntstatus_ok(tctx, r.out.result, "RemoveMultipleMembersFromAlias failed");
2886
2887         /* but removing an alias that isn't there does */
2888         sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2889
2890         torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMultipleMembersFromAlias_r(b, tctx, &r),
2891                 "RemoveMultipleMembersFromAlias failed");
2892         torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2893
2894         return true;
2895 }
2896
2897 static bool test_GetAliasMembership(struct dcerpc_binding_handle *b,
2898                                     struct torture_context *tctx,
2899                                     struct policy_handle *domain_handle)
2900 {
2901         struct samr_GetAliasMembership r;
2902         struct lsa_SidArray sids;
2903         struct samr_Ids rids;
2904
2905         torture_comment(tctx, "Testing GetAliasMembership\n");
2906
2907         r.in.domain_handle      = domain_handle;
2908         r.in.sids               = &sids;
2909         r.out.rids              = &rids;
2910
2911         sids.num_sids = 0;
2912         sids.sids = talloc_zero_array(tctx, struct lsa_SidPtr, sids.num_sids);
2913
2914         torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetAliasMembership_r(b, tctx, &r),
2915                 "GetAliasMembership failed");
2916         torture_assert_ntstatus_ok(tctx, r.out.result,
2917                 "samr_GetAliasMembership failed");
2918
2919         torture_assert_int_equal(tctx, sids.num_sids, rids.count,
2920                 "protocol misbehaviour");
2921
2922         sids.num_sids = 1;
2923         sids.sids = talloc_zero_array(tctx, struct lsa_SidPtr, sids.num_sids);
2924         sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2925
2926         torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetAliasMembership_r(b, tctx, &r),
2927                 "samr_GetAliasMembership failed");
2928         torture_assert_ntstatus_ok(tctx, r.out.result,
2929                 "samr_GetAliasMembership failed");
2930
2931 #if 0
2932         /* only true for w2k8 it seems
2933          * win7, xp, w2k3 will return a 0 length array pointer */
2934
2935         if (rids.ids && (rids.count == 0)) {
2936                 torture_fail(tctx, "samr_GetAliasMembership returned 0 count and a rids array");
2937         }
2938 #endif
2939         if (!rids.ids && rids.count) {
2940                 torture_fail(tctx, "samr_GetAliasMembership returned non-0 count but no rids");
2941         }
2942
2943         return true;
2944 }
2945
2946 static bool test_TestPrivateFunctionsUser(struct dcerpc_binding_handle *b,
2947                                           struct torture_context *tctx,
2948                                           struct policy_handle *user_handle)
2949 {
2950         struct samr_TestPrivateFunctionsUser r;
2951
2952         torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2953
2954         r.in.user_handle = user_handle;
2955
2956         torture_assert_ntstatus_ok(tctx, dcerpc_samr_TestPrivateFunctionsUser_r(b, tctx, &r),
2957                 "TestPrivateFunctionsUser failed");
2958         torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2959
2960         return true;
2961 }
2962
2963 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_binding_handle *b,
2964                                           struct torture_context *tctx,
2965                                           struct policy_handle *handle,
2966                                           bool use_info2,
2967                                           NTTIME *pwdlastset)
2968 {
2969         NTSTATUS status;
2970         uint16_t levels[] = { /* 3, */ 5, 21 };
2971         int i;
2972         /* NTTIME pwdlastset3 = 0; */
2973         NTTIME pwdlastset5 = 0;
2974         NTTIME pwdlastset21 = 0;
2975
2976         torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
2977                         use_info2 ? "2":"");
2978
2979         for (i=0; i<ARRAY_SIZE(levels); i++) {
2980
2981                 struct samr_QueryUserInfo r;
2982                 struct samr_QueryUserInfo2 r2;
2983                 union samr_UserInfo *info;
2984
2985                 if (use_info2) {
2986                         r2.in.user_handle = handle;
2987                         r2.in.level = levels[i];
2988                         r2.out.info = &info;
2989                         torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo2_r(b, tctx, &r2),
2990                                 "QueryUserInfo2 failed");
2991                         status = r2.out.result;
2992
2993                 } else {
2994                         r.in.user_handle = handle;
2995                         r.in.level = levels[i];
2996                         r.out.info = &info;
2997                         torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
2998                                 "QueryUserInfo failed");
2999                         status = r.out.result;
3000                 }
3001
3002                 if (!NT_STATUS_IS_OK(status) &&
3003                     !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
3004                         torture_result(tctx, TORTURE_FAIL, "QueryUserInfo%s level %u failed - %s\n",
3005                                use_info2 ? "2":"", levels[i], nt_errstr(status));
3006                         return false;
3007                 }
3008
3009                 switch (levels[i]) {
3010                 case 3:
3011                         /* pwdlastset3 = info->info3.last_password_change; */
3012                         break;
3013                 case 5:
3014                         pwdlastset5 = info->info5.last_password_change;
3015                         break;
3016                 case 21:
3017                         pwdlastset21 = info->info21.last_password_change;
3018                         break;
3019                 default:
3020                         return false;
3021                 }
3022         }
3023         /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
3024                                     "pwdlastset mixup"); */
3025         torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
3026                                  "pwdlastset mixup");
3027
3028         *pwdlastset = pwdlastset21;
3029
3030         torture_comment(tctx, "(pwdlastset: %llu)\n",
3031                         (unsigned long long) *pwdlastset);
3032
3033         return true;
3034 }
3035
3036 static bool test_SamLogon(struct torture_context *tctx,
3037                           struct dcerpc_pipe *p,
3038                           struct cli_credentials *machine_credentials,
3039                           struct cli_credentials *test_credentials,
3040                           NTSTATUS expected_result,
3041                           bool interactive)
3042 {
3043         NTSTATUS status;
3044         struct netr_LogonSamLogonEx r;
3045         union netr_LogonLevel logon;
3046         union netr_Validation validation;
3047         uint8_t authoritative;
3048         struct netr_IdentityInfo identity;
3049         struct netr_NetworkInfo ninfo;
3050         struct netr_PasswordInfo pinfo;
3051         DATA_BLOB names_blob, chal, lm_resp, nt_resp;
3052         int flags = CLI_CRED_NTLM_AUTH;
3053         uint32_t samlogon_flags = 0;
3054         struct netlogon_creds_CredentialState *creds;
3055         struct netr_Authenticator a;
3056         struct dcerpc_binding_handle *b = p->binding_handle;
3057
3058         torture_assert(tctx, (creds = cli_credentials_get_netlogon_creds(machine_credentials)), "");
3059
3060         if (lpcfg_client_lanman_auth(tctx->lp_ctx)) {
3061                 flags |= CLI_CRED_LANMAN_AUTH;
3062         }
3063
3064         if (lpcfg_client_ntlmv2_auth(tctx->lp_ctx)) {
3065                 flags |= CLI_CRED_NTLMv2_AUTH;
3066         }
3067
3068         cli_credentials_get_ntlm_username_domain(test_credentials, tctx,
3069                                                  &identity.account_name.string,
3070                                                  &identity.domain_name.string);
3071
3072         identity.parameter_control =
3073                 MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT |
3074                 MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
3075         identity.logon_id_low = 0;
3076         identity.logon_id_high = 0;
3077         identity.workstation.string = cli_credentials_get_workstation(test_credentials);
3078
3079         if (interactive) {
3080                 netlogon_creds_client_authenticator(creds, &a);
3081
3082                 if (!E_deshash(cli_credentials_get_password(test_credentials), pinfo.lmpassword.hash)) {
3083                         ZERO_STRUCT(pinfo.lmpassword.hash);
3084                 }
3085                 E_md4hash(cli_credentials_get_password(test_credentials), pinfo.ntpassword.hash);
3086
3087                 if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
3088                         netlogon_creds_aes_encrypt(creds, pinfo.lmpassword.hash, 16);
3089                         netlogon_creds_aes_encrypt(creds, pinfo.ntpassword.hash, 16);
3090                 } else if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
3091                         netlogon_creds_arcfour_crypt(creds, pinfo.lmpassword.hash, 16);
3092                         netlogon_creds_arcfour_crypt(creds, pinfo.ntpassword.hash, 16);
3093                 } else {
3094                         netlogon_creds_des_encrypt(creds, &pinfo.lmpassword);
3095                         netlogon_creds_des_encrypt(creds, &pinfo.ntpassword);
3096                 }
3097
3098                 pinfo.identity_info = identity;
3099                 logon.password = &pinfo;
3100
3101                 r.in.logon_level = NetlogonInteractiveInformation;
3102         } else {
3103                 generate_random_buffer(ninfo.challenge,
3104                                        sizeof(ninfo.challenge));
3105                 chal = data_blob_const(ninfo.challenge,
3106                                        sizeof(ninfo.challenge));
3107
3108                 names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(test_credentials),
3109                                                         cli_credentials_get_domain(test_credentials));
3110
3111                 status = cli_credentials_get_ntlm_response(test_credentials, tctx,
3112                                                            &flags,
3113                                                            chal,
3114                                                            names_blob,
3115                                                            &lm_resp, &nt_resp,
3116                                                            NULL, NULL);
3117                 torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
3118
3119                 ninfo.lm.data = lm_resp.data;
3120                 ninfo.lm.length = lm_resp.length;
3121
3122                 ninfo.nt.data = nt_resp.data;
3123                 ninfo.nt.length = nt_resp.length;
3124
3125                 ninfo.identity_info = identity;
3126                 logon.network = &ninfo;
3127
3128                 r.in.logon_level = NetlogonNetworkInformation;
3129         }
3130
3131         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3132         r.in.computer_name = cli_credentials_get_workstation(test_credentials);
3133         r.in.logon = &logon;
3134         r.in.flags = &samlogon_flags;
3135         r.out.flags = &samlogon_flags;
3136         r.out.validation = &validation;
3137         r.out.authoritative = &authoritative;
3138
3139         torture_comment(tctx, "Testing LogonSamLogon with name %s\n", identity.account_name.string);
3140
3141         r.in.validation_level = 6;
3142
3143         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogonEx_r(b, tctx, &r),
3144                 "netr_LogonSamLogonEx failed");
3145         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_INFO_CLASS)) {
3146                 r.in.validation_level = 3;
3147                 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogonEx_r(b, tctx, &r),
3148                         "netr_LogonSamLogonEx failed");
3149         }
3150         if (!NT_STATUS_IS_OK(r.out.result)) {
3151                 torture_assert_ntstatus_equal(tctx, r.out.result, expected_result, "LogonSamLogonEx failed");
3152                 return true;
3153         } else {
3154                 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogonEx failed");
3155         }
3156
3157         return true;
3158 }
3159
3160 static bool test_SamLogon_with_creds(struct torture_context *tctx,
3161                                      struct dcerpc_pipe *p,
3162                                      struct cli_credentials *machine_creds,
3163                                      const char *acct_name,
3164                                      const char *password,
3165                                      NTSTATUS expected_samlogon_result,
3166                                      bool interactive)
3167 {
3168         bool ret = true;
3169         struct cli_credentials *test_credentials;
3170
3171         test_credentials = cli_credentials_init(tctx);
3172
3173         cli_credentials_set_workstation(test_credentials,
3174                                         cli_credentials_get_workstation(machine_creds), CRED_SPECIFIED);
3175         cli_credentials_set_domain(test_credentials,
3176                                    cli_credentials_get_domain(machine_creds), CRED_SPECIFIED);
3177         cli_credentials_set_username(test_credentials,
3178                                      acct_name, CRED_SPECIFIED);
3179         cli_credentials_set_password(test_credentials,
3180                                      password, CRED_SPECIFIED);
3181
3182         torture_comment(tctx, "Testing samlogon (%s) as %s password: %s\n",
3183                 interactive ? "interactive" : "network", acct_name, password);
3184
3185         if (!test_SamLogon(tctx, p, machine_creds, test_credentials,
3186                             expected_samlogon_result, interactive)) {
3187                 torture_result(tctx, TORTURE_FAIL, "new password did not work\n");
3188                 ret = false;
3189         }
3190
3191         return ret;
3192 }
3193
3194 static bool test_SetPassword_level(struct dcerpc_pipe *p,
3195                                    struct dcerpc_pipe *np,
3196                                    struct torture_context *tctx,
3197                                    struct policy_handle *handle,
3198                                    uint16_t level,
3199                                    uint32_t fields_present,
3200                                    uint8_t password_expired,
3201                                    bool *matched_expected_error,
3202                                    bool use_setinfo2,
3203                                    const char *acct_name,
3204                                    char **password,
3205                                    struct cli_credentials *machine_creds,
3206                                    bool use_queryinfo2,
3207                                    NTTIME *pwdlastset,
3208                                    NTSTATUS expected_samlogon_result)
3209 {
3210         const char *fields = NULL;
3211         bool ret = true;
3212         struct dcerpc_binding_handle *b = p->binding_handle;
3213
3214         switch (level) {
3215         case 21:
3216         case 23:
3217         case 25:
3218                 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
3219                                          fields_present);
3220                 break;
3221         default:
3222                 break;
3223         }
3224
3225         torture_comment(tctx, "Testing SetUserInfo%s level %d call "
3226                 "(password_expired: %d) %s\n",
3227                 use_setinfo2 ? "2":"", level, password_expired,
3228                 fields ? fields : "");
3229
3230         if (!test_SetUserPass_level_ex(p, tctx, handle, level,
3231                                        fields_present,
3232                                        password,
3233                                        password_expired,
3234                                        use_setinfo2,
3235                                        matched_expected_error)) {
3236                 ret = false;
3237         }
3238
3239         if (!test_QueryUserInfo_pwdlastset(b, tctx, handle,
3240                                            use_queryinfo2,
3241                                            pwdlastset)) {
3242                 ret = false;
3243         }
3244
3245         if (*matched_expected_error == true) {
3246                 return ret;
3247         }
3248
3249         if (!test_SamLogon_with_creds(tctx, np,
3250                                       machine_creds,
3251                                       acct_name,
3252                                       *password,
3253                                       expected_samlogon_result,
3254                                       false)) {
3255                 ret = false;
3256         }
3257
3258         return ret;
3259 }
3260
3261 static bool setup_schannel_netlogon_pipe(struct torture_context *tctx,
3262                                          struct cli_credentials *credentials,
3263                                          struct dcerpc_pipe **p)
3264 {
3265         struct dcerpc_binding *b;
3266         NTSTATUS status;
3267
3268         torture_assert_ntstatus_ok(tctx, torture_rpc_binding(tctx, &b),
3269                 "failed to get rpc binding");
3270
3271         /* We have to use schannel, otherwise the SamLogonEx fails
3272          * with INTERNAL_ERROR */
3273
3274         status = dcerpc_binding_set_flags(b,
3275                                           DCERPC_SCHANNEL | DCERPC_SIGN |
3276                                           DCERPC_SCHANNEL_AUTO,
3277                                           DCERPC_AUTH_OPTIONS);
3278         torture_assert_ntstatus_ok(tctx, status, "set flags");
3279
3280         torture_assert_ntstatus_ok(tctx,
3281                 dcerpc_pipe_connect_b(tctx, p, b, &ndr_table_netlogon,
3282                                       credentials, tctx->ev, tctx->lp_ctx),
3283                 "failed to bind to netlogon");
3284
3285         return true;
3286 }
3287
3288 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
3289                                         struct torture_context *tctx,
3290                                         uint32_t acct_flags,
3291                                         const char *acct_name,
3292                                         struct policy_handle *handle,
3293                                         char **password,
3294                                         struct cli_credentials *machine_credentials)
3295 {
3296         int s = 0, q = 0, f = 0, l = 0, z = 0;
3297         bool ret = true;
3298         int delay = 50000;
3299         bool set_levels[] = { false, true };
3300         bool query_levels[] = { false, true };
3301         uint32_t levels[] = { 18, 21, 26, 23, 24, 25 }; /* Second half only used when TEST_ALL_LEVELS defined */
3302         uint32_t nonzeros[] = { 1, 24 };
3303         uint32_t fields_present[] = {
3304                 0,
3305                 SAMR_FIELD_EXPIRED_FLAG,
3306                 SAMR_FIELD_LAST_PWD_CHANGE,
3307                 SAMR_FIELD_EXPIRED_FLAG | SAMR_FIELD_LAST_PWD_CHANGE,
3308                 SAMR_FIELD_COMMENT,
3309                 SAMR_FIELD_NT_PASSWORD_PRESENT,
3310                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
3311                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
3312                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
3313                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
3314                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
3315                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE | SAMR_FIELD_EXPIRED_FLAG
3316         };
3317         struct dcerpc_pipe *np = NULL;
3318
3319         if (torture_setting_bool(tctx, "samba3", false) ||
3320             torture_setting_bool(tctx, "samba4", false)) {
3321                 delay = 999999;
3322                 torture_comment(tctx, "Samba3 has second granularity, setting delay to: %d\n",
3323                         delay);
3324         }
3325
3326         torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
3327
3328         /* set to 1 to enable testing for all possible opcode
3329            (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
3330            combinations */
3331 #if 0
3332 #define TEST_ALL_LEVELS 1
3333 #define TEST_SET_LEVELS 1
3334 #define TEST_QUERY_LEVELS 1
3335 #endif
3336 #ifdef TEST_ALL_LEVELS
3337         for (l=0; l<ARRAY_SIZE(levels); l++) {
3338 #else
3339         for (l=0; l<(ARRAY_SIZE(levels))/2; l++) {
3340 #endif
3341         for (z=0; z<ARRAY_SIZE(nonzeros); z++) {
3342         for (f=0; f<ARRAY_SIZE(fields_present); f++) {
3343 #ifdef TEST_SET_LEVELS
3344         for (s=0; s<ARRAY_SIZE(set_levels); s++) {
3345 #endif
3346 #ifdef TEST_QUERY_LEVELS
3347         for (q=0; q<ARRAY_SIZE(query_levels); q++) {
3348 #endif
3349                 NTTIME pwdlastset_old = 0;
3350                 NTTIME pwdlastset_new = 0;
3351                 bool matched_expected_error = false;
3352                 NTSTATUS expected_samlogon_result = NT_STATUS_ACCOUNT_DISABLED;
3353
3354                 torture_comment(tctx, "------------------------------\n"
3355                                 "Testing pwdLastSet attribute for flags: 0x%08x "
3356                                 "(s: %d (l: %d), q: %d)\n",
3357                                 acct_flags, s, levels[l], q);
3358
3359                 switch (levels[l]) {
3360                 case 21:
3361                 case 23:
3362                 case 25:
3363                         if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3364                               (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT))) {
3365                                 expected_samlogon_result = NT_STATUS_WRONG_PASSWORD;
3366                         }
3367                         break;
3368                 }
3369
3370
3371                 /* set #1 */
3372
3373                 /* set a password and force password change (pwdlastset 0) by
3374                  * setting the password expired flag to a non-0 value */
3375
3376                 if (!test_SetPassword_level(p, np, tctx, handle,
3377                                             levels[l],
3378                                             fields_present[f],
3379                                             nonzeros[z],
3380                                             &matched_expected_error,
3381                                             set_levels[s],
3382                                             acct_name,
3383                                             password,
3384                                             machine_credentials,
3385                                             query_levels[q],
3386                                             &pwdlastset_new,
3387                                             expected_samlogon_result)) {
3388                         ret = false;
3389                 }
3390
3391                 if (matched_expected_error == true) {
3392                         /* skipping on expected failure */
3393                         continue;
3394                 }
3395
3396                 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3397                  * set without the SAMR_FIELD_EXPIRED_FLAG */
3398
3399                 switch (levels[l]) {
3400                 case 21:
3401                 case 23:
3402                 case 25:
3403                         if ((pwdlastset_new != 0) &&
3404                             !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3405                                 torture_comment(tctx, "not considering a non-0 "
3406                                         "pwdLastSet as a an error as the "
3407                                         "SAMR_FIELD_EXPIRED_FLAG has not "
3408                                         "been set\n");
3409                                 break;
3410                         }
3411                         break;
3412                 default:
3413                         if (pwdlastset_new != 0) {
3414                                 torture_result(tctx, TORTURE_FAIL, "pwdLastSet test failed: "
3415                                         "expected pwdLastSet 0 but got %llu\n",
3416                                         (unsigned long long) pwdlastset_old);
3417                                 ret = false;
3418                         }
3419                         break;
3420                 }
3421
3422                 switch (levels[l]) {
3423                 case 21:
3424                 case 23:
3425                 case 25:
3426                         if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3427                              (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3428                              (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3429                              (pwdlastset_old >= pwdlastset_new)) {
3430                                 torture_result(tctx, TORTURE_FAIL, "pwdlastset not increasing\n");
3431                                 ret = false;
3432                         }
3433                         break;
3434                 }
3435
3436                 pwdlastset_old = pwdlastset_new;
3437
3438                 usleep(delay);
3439
3440                 /* set #2 */
3441
3442                 /* set a password, pwdlastset needs to get updated (increased
3443                  * value), password_expired value used here is 0 */
3444
3445                 if (!test_SetPassword_level(p, np, tctx, handle,
3446                                             levels[l],
3447                                             fields_present[f],
3448                                             0,
3449                                             &matched_expected_error,
3450                                             set_levels[s],
3451                                             acct_name,
3452                                             password,
3453                                             machine_credentials,
3454                                             query_levels[q],
3455                                             &pwdlastset_new,
3456                                             expected_samlogon_result)) {
3457                         ret = false;
3458                 }
3459
3460                 /* when a password has been changed, pwdlastset must not be 0 afterwards
3461                  * and must be larger then the old value */
3462
3463                 switch (levels[l]) {
3464                 case 21:
3465                 case 23:
3466                 case 25:
3467                         /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3468                          * password has been changed, old and new pwdlastset
3469                          * need to be the same value */
3470
3471                         if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3472                             !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3473                               (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3474                         {
3475                                 torture_assert_int_equal(tctx, pwdlastset_old,
3476                                         pwdlastset_new, "pwdlastset must be equal");
3477                                 break;
3478                         }
3479                         break;
3480                 default:
3481                         if (pwdlastset_old >= pwdlastset_new) {
3482                                 torture_result(tctx, TORTURE_FAIL, "pwdLastSet test failed: "
3483                                         "expected last pwdlastset (%llu) < new pwdlastset (%llu)\n",
3484                                         (unsigned long long) pwdlastset_old,
3485                                         (unsigned long long) pwdlastset_new);
3486                                 ret = false;
3487                         }
3488                         if (pwdlastset_new == 0) {
3489                                 torture_result(tctx, TORTURE_FAIL, "pwdLastSet test failed: "
3490                                         "expected non-0 pwdlastset, got: %llu\n",
3491                                         (unsigned long long) pwdlastset_new);
3492                                 ret = false;
3493                         }
3494                         break;
3495                 }
3496
3497                 switch (levels[l]) {
3498                 case 21:
3499                 case 23:
3500                 case 25:
3501                         if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3502                              (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3503                              (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3504                              (pwdlastset_old >= pwdlastset_new)) {
3505                                 torture_result(tctx, TORTURE_FAIL, "pwdlastset not increasing\n");
3506                                 ret = false;
3507                         }
3508                         break;
3509                 }
3510
3511                 pwdlastset_old = pwdlastset_new;
3512
3513                 usleep(delay);
3514
3515                 /* set #2b */
3516
3517                 /* set a password, pwdlastset needs to get updated (increased
3518                  * value), password_expired value used here is 0 */
3519
3520                 if (!test_SetPassword_level(p, np, tctx, handle,
3521                                             levels[l],
3522                                             fields_present[f],
3523                                             0,
3524                                             &matched_expected_error,
3525                                             set_levels[s],
3526                                             acct_name,
3527                                             password,
3528                                             machine_credentials,
3529                                             query_levels[q],
3530                                             &pwdlastset_new,
3531                                             expected_samlogon_result)) {
3532                         ret = false;
3533                 }
3534
3535                 /* when a password has been changed, pwdlastset must not be 0 afterwards
3536                  * and must be larger then the old value */
3537
3538                 switch (levels[l]) {
3539                 case 21:
3540                 case 23:
3541                 case 25:
3542
3543                         /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3544                          * password has been changed, old and new pwdlastset
3545                          * need to be the same value */
3546
3547                         if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3548                             !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3549                               (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3550                         {
3551                                 torture_assert_int_equal(tctx, pwdlastset_old,
3552                                         pwdlastset_new, "pwdlastset must be equal");
3553                                 break;
3554                         }
3555                         break;
3556                 default:
3557                         if (pwdlastset_old >= pwdlastset_new) {
3558                                 torture_result(tctx, TORTURE_FAIL, "pwdLastSet test failed: "
3559                                         "expected last pwdlastset (%llu) < new pwdlastset (%llu)\n",
3560                                         (unsigned long long) pwdlastset_old,
3561                                         (unsigned long long) pwdlastset_new);
3562                                 ret = false;
3563                         }
3564                         if (pwdlastset_new == 0) {
3565                                 torture_result(tctx, TORTURE_FAIL, "pwdLastSet test failed: "
3566                                         "expected non-0 pwdlastset, got: %llu\n",
3567                                         (unsigned long long) pwdlastset_new);
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_result(tctx, TORTURE_FAIL, "pwdlastset not increasing\n");
3582                                 ret = false;
3583                         }
3584                         break;
3585                 }
3586
3587                 pwdlastset_old = pwdlastset_new;
3588
3589                 usleep(delay);
3590
3591                 /* set #3 */
3592
3593                 /* set a password and force password change (pwdlastset 0) by
3594                  * setting the password expired flag to a non-0 value */
3595
3596                 if (!test_SetPassword_level(p, np, tctx, handle,
3597                                             levels[l],
3598                                             fields_present[f],
3599                                             nonzeros[z],
3600                                             &matched_expected_error,
3601                                             set_levels[s],
3602                                             acct_name,
3603                                             password,
3604                                             machine_credentials,
3605                                             query_levels[q],
3606                                             &pwdlastset_new,
3607                                             expected_samlogon_result)) {
3608                         ret = false;
3609                 }
3610
3611                 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3612                  * set without the SAMR_FIELD_EXPIRED_FLAG */
3613
3614                 switch (levels[l]) {
3615                 case 21:
3616                 case 23:
3617                 case 25:
3618                         if ((pwdlastset_new != 0) &&
3619                             !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3620                                 torture_comment(tctx, "not considering a non-0 "
3621                                         "pwdLastSet as a an error as the "
3622                                         "SAMR_FIELD_EXPIRED_FLAG has not "
3623                                         "been set\n");
3624                                 break;
3625                         }
3626
3627                         /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3628                          * password has been changed, old and new pwdlastset
3629                          * need to be the same value */
3630
3631                         if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3632                             !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3633                               (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3634                         {
3635                                 torture_assert_int_equal(tctx, pwdlastset_old,
3636                                         pwdlastset_new, "pwdlastset must be equal");
3637                                 break;
3638                         }
3639                         break;
3640                 default:
3641                         if (pwdlastset_new != 0) {
3642                                 torture_result(tctx, TORTURE_FAIL, "pwdLastSet test failed: "
3643                                         "expected pwdLastSet 0, got %llu\n",
3644                                         (unsigned long long) pwdlastset_old);
3645                                 ret = false;
3646                         }
3647                         break;
3648                 }
3649
3650                 switch (levels[l]) {
3651                 case 21:
3652                 case 23:
3653                 case 25:
3654                         if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3655                              (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3656                              (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3657                              (pwdlastset_old >= pwdlastset_new)) {
3658                                 torture_result(tctx, TORTURE_FAIL, "pwdlastset not increasing\n");
3659                                 ret = false;
3660                         }
3661                         break;
3662                 }
3663
3664                 /* if the level we are testing does not have a fields_present
3665                  * field, skip all fields present tests by setting f to to
3666                  * arraysize */
3667                 switch (levels[l]) {
3668                 case 18:
3669                 case 24:
3670                 case 26:
3671                         f = ARRAY_SIZE(fields_present);
3672                         break;
3673                 }
3674
3675 #ifdef TEST_QUERY_LEVELS
3676         }
3677 #endif
3678 #ifdef TEST_SET_LEVELS
3679         }
3680 #endif
3681         } /* fields present */
3682         } /* nonzeros */
3683         } /* levels */
3684
3685 #undef TEST_SET_LEVELS
3686 #undef TEST_QUERY_LEVELS
3687
3688         talloc_free(np);
3689
3690         return ret;
3691 }
3692
3693 static bool test_QueryUserInfo_badpwdcount(struct dcerpc_binding_handle *b,
3694                                            struct torture_context *tctx,
3695                                            struct policy_handle *handle,
3696                                            uint32_t *badpwdcount)
3697 {
3698         union samr_UserInfo *info;
3699         struct samr_QueryUserInfo r;
3700
3701         r.in.user_handle = handle;
3702         r.in.level = 3;
3703         r.out.info = &info;
3704
3705         torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
3706
3707         torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
3708                 "failed to query userinfo");
3709         torture_assert_ntstatus_ok(tctx, r.out.result,
3710                 "failed to query userinfo");
3711
3712         *badpwdcount = info->info3.bad_password_count;
3713
3714         torture_comment(tctx, " (bad password count: %d)\n", *badpwdcount);
3715
3716         return true;
3717 }
3718
3719 static bool test_SetUserInfo_acct_flags(struct dcerpc_binding_handle *b,
3720                                         struct torture_context *tctx,
3721                                         struct policy_handle *user_handle,
3722                                         uint32_t acct_flags)
3723 {
3724         struct samr_SetUserInfo r;
3725         union samr_UserInfo user_info;
3726
3727         torture_comment(tctx, "Testing SetUserInfo level 16\n");
3728
3729         user_info.info16.acct_flags = acct_flags;
3730
3731         r.in.user_handle = user_handle;
3732         r.in.level = 16;
3733         r.in.info = &user_info;
3734
3735         torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetUserInfo_r(b, tctx, &r),
3736                 "failed to set account flags");
3737         torture_assert_ntstatus_ok(tctx, r.out.result,
3738                 "failed to set account flags");
3739
3740         return true;
3741 }
3742
3743 static bool test_reset_badpwdcount(struct dcerpc_pipe *p,
3744                                    struct torture_context *tctx,
3745                                    struct policy_handle *user_handle,
3746                                    uint32_t acct_flags,
3747                                    char **password)
3748 {
3749         struct dcerpc_binding_handle *b = p->binding_handle;
3750
3751         torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
3752                 "failed to set password");
3753
3754         torture_comment(tctx, "Testing SetUserInfo level 16 (enable account)\n");
3755
3756         torture_assert(tctx,
3757                        test_SetUserInfo_acct_flags(b, tctx, user_handle,
3758                                                    acct_flags & ~ACB_DISABLED),
3759                        "failed to enable user");
3760
3761         torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
3762                 "failed to set password");
3763
3764         return true;
3765 }
3766
3767 static bool test_SetDomainInfo(struct dcerpc_binding_handle *b,
3768                                struct torture_context *tctx,
3769                                struct policy_handle *domain_handle,
3770                                enum samr_DomainInfoClass level,
3771                                union samr_DomainInfo *info)
3772 {
3773         struct samr_SetDomainInfo r;
3774
3775         r.in.domain_handle = domain_handle;
3776         r.in.level = level;
3777         r.in.info = info;
3778
3779         torture_assert_ntstatus_ok(tctx,
3780                                    dcerpc_samr_SetDomainInfo_r(b, tctx, &r),
3781                                    "failed to set domain info");
3782         torture_assert_ntstatus_ok(tctx, r.out.result,
3783                                    "failed to set domain info");
3784
3785         return true;
3786 }
3787
3788 static bool test_SetDomainInfo_ntstatus(struct dcerpc_binding_handle *b,
3789                                         struct torture_context *tctx,
3790                                         struct policy_handle *domain_handle,
3791                                         enum samr_DomainInfoClass level,
3792                                         union samr_DomainInfo *info,
3793                                         NTSTATUS expected)
3794 {
3795         struct samr_SetDomainInfo r;
3796
3797         r.in.domain_handle = domain_handle;
3798         r.in.level = level;
3799         r.in.info = info;
3800
3801         torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &r),
3802                 "SetDomainInfo failed");
3803         torture_assert_ntstatus_equal(tctx, r.out.result, expected, "");
3804
3805         return true;
3806 }
3807
3808 static bool test_QueryDomainInfo2_level(struct dcerpc_binding_handle *b,
3809                                         struct torture_context *tctx,
3810                                         struct policy_handle *domain_handle,
3811                                         enum samr_DomainInfoClass level,
3812                                         union samr_DomainInfo **q_info)
3813 {
3814         struct samr_QueryDomainInfo2 r;
3815
3816         r.in.domain_handle = domain_handle;
3817         r.in.level = level;
3818         r.out.info = q_info;
3819
3820         torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
3821                 "failed to query domain info");
3822         torture_assert_ntstatus_ok(tctx, r.out.result,
3823                 "failed to query domain info");
3824
3825         return true;
3826 }
3827
3828 static bool test_Password_badpwdcount(struct dcerpc_pipe *p,
3829                                       struct dcerpc_pipe *np,
3830                                       struct torture_context *tctx,
3831                                       uint32_t acct_flags,
3832                                       const char *acct_name,
3833                                       struct policy_handle *domain_handle,
3834                                       struct policy_handle *user_handle,
3835                                       char **password,
3836                                       struct cli_credentials *machine_credentials,
3837                                       const char *comment,
3838                                       bool disable,
3839                                       bool interactive,
3840                                       NTSTATUS expected_success_status,
3841                                       struct samr_DomInfo1 *info1,
3842                                       struct samr_DomInfo12 *info12)
3843 {
3844         union samr_DomainInfo info;
3845         char **passwords;
3846         int i;
3847         uint32_t badpwdcount, tmp;
3848         uint32_t password_history_length = 12;
3849         uint32_t lockout_threshold = 15;
3850         uint32_t lockout_seconds = 5;
3851         uint64_t delta_time_factor = 10 * 1000 * 1000;
3852         struct dcerpc_binding_handle *b = p->binding_handle;
3853
3854         if (torture_setting_bool(tctx, "samba3", false)) {
3855                 lockout_seconds = 60;
3856         }
3857
3858         torture_comment(tctx, "\nTesting bad pwd count with: %s\n", comment);
3859
3860         torture_assert(tctx, password_history_length < lockout_threshold,
3861                 "password history length needs to be smaller than account lockout threshold for this test");
3862
3863
3864         /* set policies */
3865
3866         info.info1 = *info1;
3867         info.info1.password_history_length = password_history_length;
3868         info.info1.min_password_age = 0;
3869
3870         torture_assert(tctx,
3871                        test_SetDomainInfo(b, tctx, domain_handle,
3872                                           DomainPasswordInformation, &info),
3873                        "failed to set password history length and min passwd age");
3874
3875         info.info12 = *info12;
3876         info.info12.lockout_threshold = lockout_threshold;
3877
3878         /* set lockout duration of 5 seconds */
3879         info.info12.lockout_duration = ~(lockout_seconds * delta_time_factor);
3880         info.info12.lockout_window = ~(lockout_seconds * delta_time_factor);
3881
3882         torture_assert(tctx,
3883                        test_SetDomainInfo(b, tctx, domain_handle,
3884                                           DomainLockoutInformation, &info),
3885                        "failed to set lockout threshold");
3886
3887         /* reset bad pwd count */
3888
3889         torture_assert(tctx,
3890                 test_reset_badpwdcount(p, tctx, user_handle, acct_flags, password), "");
3891
3892
3893         /* enable or disable account */
3894         if (disable) {
3895                 torture_assert(tctx,
3896                                test_SetUserInfo_acct_flags(b, tctx, user_handle,
3897                                                 acct_flags | ACB_DISABLED),
3898                                "failed to disable user");
3899         } else {
3900                 torture_assert(tctx,
3901                                test_SetUserInfo_acct_flags(b, tctx, user_handle,
3902                                                 acct_flags & ~ACB_DISABLED),
3903                                "failed to enable user");
3904         }
3905
3906
3907         /* setup password history */
3908
3909         passwords = talloc_array(tctx, char *, password_history_length);
3910
3911         for (i=0; i < password_history_length; i++) {
3912
3913                 torture_assert(tctx, test_SetUserPass(p, tctx, user_handle, password),
3914                         "failed to set password");
3915                 passwords[i] = talloc_strdup(tctx, *password);
3916
3917                 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3918                                               acct_name, passwords[i],
3919                                               expected_success_status, interactive)) {
3920                         torture_fail(tctx, "failed to auth with latest password");
3921                 }
3922
3923                 torture_assert(tctx,
3924                         test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3925
3926                 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
3927         }
3928
3929
3930         /* test with wrong password */
3931
3932         if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3933                                       acct_name, "random_crap",
3934                                       NT_STATUS_WRONG_PASSWORD, interactive)) {
3935                 torture_fail(tctx, "succeeded to authenticate with wrong password");
3936         }
3937
3938         torture_assert(tctx,
3939                 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3940
3941         torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
3942
3943
3944         /* test with latest good password */
3945
3946         if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
3947                                       passwords[password_history_length-1],
3948                                       expected_success_status, interactive)) {
3949                 torture_fail(tctx, "succeeded to authenticate with wrong password");
3950         }
3951
3952         torture_assert(tctx,
3953                 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3954
3955         if (disable) {
3956                 torture_assert_int_equal(tctx, badpwdcount, 1, "expected badpwdcount to be 1");
3957         } else {
3958                 /* only enabled accounts get the bad pwd count reset upon
3959                  * successful logon */
3960                 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
3961         }
3962
3963         tmp = badpwdcount;
3964
3965
3966         /* test password history */
3967
3968         for (i=0; i < password_history_length; i++) {
3969
3970                 torture_comment(tctx, "Testing bad password count behavior with "
3971                                       "password #%d of #%d\n", i, password_history_length);
3972
3973                 /* - network samlogon will succeed auth and not
3974                  *   increase badpwdcount for 2 last entries
3975                  * - interactive samlogon only for the last one */
3976
3977                 if (i == password_history_length - 1 ||
3978                     (i == password_history_length - 2 && !interactive)) {
3979
3980                         if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
3981                                                       acct_name, passwords[i],
3982                                                       expected_success_status, interactive)) {
3983                                 torture_fail(tctx, talloc_asprintf(tctx, "did not successfully to obtain %s for %s login with old password (#%d of #%d in history)",
3984                                                                    nt_errstr(expected_success_status),
3985                                                                    interactive ? "interactive" : "network", i, password_history_length));
3986                         }
3987
3988                         torture_assert(tctx,
3989                                 test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
3990
3991                         if (disable) {
3992                                 /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE* for pwd history entry %d\n", i); */
3993                                 torture_assert_int_equal(tctx, badpwdcount, tmp, "unexpected badpwdcount");
3994                         } else {
3995                                 /* torture_comment(tctx, "expecting bad pwd count to be 0 for pwd history entry %d\n", i); */
3996                                 torture_assert_int_equal(tctx, badpwdcount, 0, "expected badpwdcount to be 0");
3997                         }
3998
3999                         tmp = badpwdcount;
4000
4001                         continue;
4002                 }
4003
4004                 if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4005                                               acct_name, passwords[i],
4006                                               NT_STATUS_WRONG_PASSWORD, interactive)) {
4007                         torture_fail(tctx, talloc_asprintf(tctx, "succeeded to authenticate with old password (#%d of #%d in history)", i, password_history_length));
4008                 }
4009
4010                 torture_assert(tctx,
4011                         test_QueryUserInfo_badpwdcount(b, tctx, user_handle, &badpwdcount), "");
4012
4013                 /* - network samlogon will fail auth but not increase
4014                  *   badpwdcount for 3rd last entry
4015                  * - interactive samlogon for 3rd and 2nd last entry */
4016
4017                 if (i == password_history_length - 3 ||
4018                     (i == password_history_length - 2 && interactive)) {
4019                         /* torture_comment(tctx, "expecting bad pwd count to *NOT INCREASE * by one for pwd history entry %d\n", i); */
4020                         torture_assert_int_equal(tctx, badpwdcount, tmp, "unexpected badpwdcount");
4021                 } else {
4022                         /* torture_comment(tctx, "expecting bad pwd count to increase by one for pwd history entry %d\n", i); */
4023                         torture_assert_int_equal(tctx, badpwdcount, tmp + 1, "unexpected badpwdcount");
4024                 }
4025
4026                 tmp = badpwdcount;
4027         }
4028
4029         return true;
4030 }
4031
4032 static bool test_Password_badpwdcount_wrap(struct dcerpc_pipe *p,
4033                                            struct torture_context *tctx,
4034                                            uint32_t acct_flags,
4035                                            const char *acct_name,
4036                                            struct policy_handle *domain_handle,
4037                                            struct policy_handle *user_handle,
4038                                            char **password,
4039                                            struct cli_credentials *machine_credentials)
4040 {
4041         union samr_DomainInfo *q_info, s_info;
4042         struct samr_DomInfo1 info1, _info1;
4043         struct samr_DomInfo12 info12, _info12;
4044         bool ret = true;
4045         struct dcerpc_binding_handle *b = p->binding_handle;
4046         struct dcerpc_pipe *np;
4047         int i;
4048
4049         struct {
4050                 const char *comment;
4051                 bool disabled;
4052                 bool interactive;
4053                 NTSTATUS expected_success_status;
4054         } creds[] = {
4055                 {
4056                         .comment                = "network logon (disabled account)",
4057                         .disabled               = true,
4058                         .interactive            = false,
4059                         .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4060                 },
4061                 {
4062                         .comment                = "network logon (enabled account)",
4063                         .disabled               = false,
4064                         .interactive            = false,
4065                         .expected_success_status= NT_STATUS_OK
4066                 },
4067                 {
4068                         .comment                = "interactive logon (disabled account)",
4069                         .disabled               = true,
4070                         .interactive            = true,
4071                         .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4072                 },
4073                 {
4074                         .comment                = "interactive logon (enabled account)",
4075                         .disabled               = false,
4076                         .interactive            = true,
4077                         .expected_success_status= NT_STATUS_OK
4078                 },
4079         };
4080
4081         torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
4082
4083         /* backup old policies */
4084
4085         torture_assert(tctx,
4086                 test_QueryDomainInfo2_level(b, tctx, domain_handle,
4087                                             DomainPasswordInformation, &q_info),
4088                 "failed to query domain info level 1");
4089
4090         info1 = q_info->info1;
4091         _info1 = info1;
4092
4093         torture_assert(tctx,
4094                 test_QueryDomainInfo2_level(b, tctx, domain_handle,
4095                                             DomainLockoutInformation, &q_info),
4096                 "failed to query domain info level 12");
4097
4098         info12 = q_info->info12;
4099         _info12 = info12;
4100
4101         /* run tests */
4102
4103         for (i=0; i < ARRAY_SIZE(creds); i++) {
4104
4105                 /* skip trust tests for now */
4106                 if (acct_flags & ACB_WSTRUST ||
4107                     acct_flags & ACB_SVRTRUST ||
4108                     acct_flags & ACB_DOMTRUST) {
4109                         continue;
4110                 }
4111
4112                 if (!test_Password_badpwdcount(p, np, tctx, acct_flags, acct_name,
4113                                                domain_handle, user_handle, password,
4114                                                machine_credentials,
4115                                                creds[i].comment,
4116                                                creds[i].disabled,
4117                                                creds[i].interactive,
4118                                                creds[i].expected_success_status,
4119                                                &_info1, &_info12)) {
4120                         torture_result(tctx, TORTURE_FAIL, "TEST #%d (%s) failed\n", i, creds[i].comment);
4121                         ret = false;
4122                 } else {
4123                         torture_comment(tctx, "TEST #%d (%s) succeeded\n", i, creds[i].comment);
4124                 }
4125         }
4126
4127         /* restore policies */
4128
4129         s_info.info1 = info1;
4130
4131         torture_assert(tctx,
4132                        test_SetDomainInfo(b, tctx, domain_handle,
4133                                           DomainPasswordInformation, &s_info),
4134                        "failed to set password information");
4135
4136         s_info.info12 = info12;
4137
4138         torture_assert(tctx,
4139                        test_SetDomainInfo(b, tctx, domain_handle,
4140                                           DomainLockoutInformation, &s_info),
4141                        "failed to set lockout information");
4142
4143         return ret;
4144 }
4145
4146 static bool test_QueryUserInfo_lockout(struct dcerpc_binding_handle *b,
4147                                        struct torture_context *tctx,
4148                                        struct policy_handle *domain_handle,
4149                                        const char *acct_name,
4150                                        uint16_t raw_bad_password_count,
4151                                        uint16_t effective_bad_password_count,
4152                                        uint32_t effective_acb_lockout)
4153 {
4154         struct policy_handle user_handle;
4155         union samr_UserInfo *i;
4156         struct samr_QueryUserInfo r;
4157
4158         NTSTATUS status = test_OpenUser_byname(b, tctx, domain_handle, acct_name, &user_handle);
4159         if (!NT_STATUS_IS_OK(status)) {
4160                 return false;
4161         }
4162
4163         r.in.user_handle = &user_handle;
4164         r.in.level = 3;
4165         r.out.info = &i;
4166         torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
4167         torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
4168                 "failed to query userinfo");
4169         torture_assert_ntstatus_ok(tctx, r.out.result,
4170                 "failed to query userinfo");
4171         torture_comment(tctx, "  (acct_flags: 0x%08x) (raw_bad_pwd_count: %u)\n",
4172                         i->info3.acct_flags, i->info3.bad_password_count);
4173         torture_assert_int_equal(tctx, i->info3.bad_password_count,
4174                                  raw_bad_password_count,
4175                                  "raw badpwdcount");
4176         torture_assert_int_equal(tctx, i->info3.acct_flags & ACB_AUTOLOCK,
4177                                  effective_acb_lockout,
4178                                  "effective acb_lockout");
4179         TALLOC_FREE(i);
4180
4181         r.in.user_handle = &user_handle;
4182         r.in.level = 5;
4183         r.out.info = &i;
4184         torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
4185         torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
4186                 "failed to query userinfo");
4187         torture_assert_ntstatus_ok(tctx, r.out.result,
4188                 "failed to query userinfo");
4189         torture_comment(tctx, "  (acct_flags: 0x%08x) (effective_bad_pwd_count: %u)\n",
4190                         i->info5.acct_flags, i->info5.bad_password_count);
4191         torture_assert_int_equal(tctx, i->info5.bad_password_count,
4192                                  effective_bad_password_count,
4193                                  "effective badpwdcount");
4194         torture_assert_int_equal(tctx, i->info5.acct_flags & ACB_AUTOLOCK,
4195                                  effective_acb_lockout,
4196                                  "effective acb_lockout");
4197         TALLOC_FREE(i);
4198
4199         r.in.user_handle = &user_handle;
4200         r.in.level = 16;
4201         r.out.info = &i;
4202         torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
4203         torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
4204                 "failed to query userinfo");
4205         torture_assert_ntstatus_ok(tctx, r.out.result,
4206                 "failed to query userinfo");
4207         torture_comment(tctx, "  (acct_flags: 0x%08x)\n",
4208                         i->info16.acct_flags);
4209         torture_assert_int_equal(tctx, i->info16.acct_flags & ACB_AUTOLOCK,
4210                                  effective_acb_lockout,
4211                                  "effective acb_lockout");
4212         TALLOC_FREE(i);
4213
4214         r.in.user_handle = &user_handle;
4215         r.in.level = 21;
4216         r.out.info = &i;
4217         torture_comment(tctx, "Testing QueryUserInfo level %d", r.in.level);
4218         torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
4219                 "failed to query userinfo");
4220         torture_assert_ntstatus_ok(tctx, r.out.result,
4221                 "failed to query userinfo");
4222         torture_comment(tctx, "  (acct_flags: 0x%08x) (effective_bad_pwd_count: %u)\n",
4223                         i->info21.acct_flags, i->info21.bad_password_count);
4224         torture_assert_int_equal(tctx, i->info21.bad_password_count,
4225                                  effective_bad_password_count,
4226                                  "effective badpwdcount");
4227         torture_assert_int_equal(tctx, i->info21.acct_flags & ACB_AUTOLOCK,
4228                                  effective_acb_lockout,
4229                                  "effective acb_lockout");
4230         TALLOC_FREE(i);
4231
4232         if (!test_samr_handle_Close(b, tctx, &user_handle)) {
4233                 return false;
4234         }
4235
4236         return true;
4237 }
4238
4239 static bool test_Password_lockout(struct dcerpc_pipe *p,
4240                                   struct dcerpc_pipe *np,
4241                                   struct torture_context *tctx,
4242                                   uint32_t acct_flags,
4243                                   const char *acct_name,
4244                                   struct policy_handle *domain_handle,
4245                                   struct policy_handle *user_handle,
4246                                   char **password,
4247                                   struct cli_credentials *machine_credentials,
4248                                   const char *comment,
4249                                   bool disable,
4250                                   bool interactive,
4251                                   uint32_t password_history_length,
4252                                   NTSTATUS expected_success_status,
4253                                   struct samr_DomInfo1 *info1,
4254                                   struct samr_DomInfo12 *info12)
4255 {
4256         union samr_DomainInfo info;
4257         uint64_t lockout_threshold = 1;
4258         uint32_t lockout_seconds = 5;
4259         uint64_t delta_time_factor = 10 * 1000 * 1000;
4260         struct dcerpc_binding_handle *b = p->binding_handle;
4261
4262         if (torture_setting_bool(tctx, "samba3", false)) {
4263                 lockout_seconds = 60;
4264         }
4265
4266         torture_comment(tctx, "\nTesting account lockout: %s\n", comment);
4267
4268         /* set policies */
4269
4270         info.info1 = *info1;
4271
4272         torture_comment(tctx, "setting password history length to %d.\n", password_history_length);
4273         info.info1.password_history_length = password_history_length;
4274
4275         torture_comment(tctx, "setting min password again.\n");
4276         info.info1.min_password_age = 0;
4277
4278         torture_assert(tctx,
4279                        test_SetDomainInfo(b, tctx, domain_handle,
4280                                           DomainPasswordInformation, &info),
4281                        "failed to set password history length");
4282
4283         info.info12 = *info12;
4284         info.info12.lockout_threshold = lockout_threshold;
4285
4286         /* set lockout duration < lockout window: should fail */
4287         info.info12.lockout_duration = ~(lockout_seconds * delta_time_factor);
4288         info.info12.lockout_window = ~((lockout_seconds + 1) * delta_time_factor);
4289
4290         torture_assert(tctx,
4291                 test_SetDomainInfo_ntstatus(b, tctx, domain_handle,
4292                                             DomainLockoutInformation, &info,
4293                                             NT_STATUS_INVALID_PARAMETER),
4294                 "setting lockout duration < lockout window gave unexpected result");
4295
4296         info.info12.lockout_duration = 0;
4297         info.info12.lockout_window = 0;
4298
4299         torture_assert(tctx,
4300                        test_SetDomainInfo(b, tctx, domain_handle,
4301                                           DomainLockoutInformation, &info),
4302                        "failed to set lockout window and duration to 0");
4303
4304
4305         /* set lockout duration of 5 seconds */
4306         info.info12.lockout_duration = ~(lockout_seconds * delta_time_factor);
4307         info.info12.lockout_window = ~(lockout_seconds * delta_time_factor);
4308
4309         torture_assert(tctx,
4310                        test_SetDomainInfo(b, tctx, domain_handle,
4311                                           DomainLockoutInformation, &info),
4312                        "failed to set lockout window and duration to 5 seconds");
4313
4314         /* reset bad pwd count */
4315
4316         torture_assert(tctx,
4317                 test_reset_badpwdcount(p, tctx, user_handle, acct_flags, password), "");
4318
4319
4320         /* enable or disable account */
4321
4322         if (disable) {
4323                 torture_assert(tctx,
4324                                test_SetUserInfo_acct_flags(b, tctx, user_handle,
4325                                                 acct_flags | ACB_DISABLED),
4326                                "failed to disable user");
4327         } else {
4328                 torture_assert(tctx,
4329                                test_SetUserInfo_acct_flags(b, tctx, user_handle,
4330                                                 acct_flags & ~ACB_DISABLED),
4331                                "failed to enable user");
4332         }
4333
4334
4335         /* test logon with right password */
4336
4337         if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4338                                       acct_name, *password,
4339                                       expected_success_status, interactive)) {
4340                 torture_fail(tctx, "failed to auth with latest password");
4341         }
4342
4343         torture_assert(tctx,
4344                 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4345                         0, 0, 0),
4346                 "expected account to not be locked");
4347
4348         /* test with wrong password ==> lockout */
4349
4350         if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4351                                       acct_name, "random_crap",
4352                                       NT_STATUS_WRONG_PASSWORD, interactive)) {
4353                 torture_fail(tctx, "succeeded to authenticate with wrong password");
4354         }
4355
4356         /*
4357          * curiously, windows does _not_ return fresh values of
4358          * effective bad_password_count and ACB_AUTOLOCK.
4359          */
4360         torture_assert(tctx,
4361                 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4362                         1, 1, ACB_AUTOLOCK),
4363                 "expected account to not be locked");
4364
4365         /* test with good password */
4366
4367         if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
4368                                      *password,
4369                                      NT_STATUS_ACCOUNT_LOCKED_OUT, interactive))
4370         {
4371                 torture_fail(tctx, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
4372         }
4373
4374         /* bad pwd count should not get updated */
4375         torture_assert(tctx,
4376                 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4377                         1, 1, ACB_AUTOLOCK),
4378                 "expected account to be locked");
4379
4380         torture_assert(tctx,
4381                        test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, *password,
4382                                                          NT_STATUS_ACCOUNT_LOCKED_OUT),
4383                        "got wrong status from ChangePasswordUser2");
4384
4385         /* bad pwd count should not get updated */
4386         torture_assert(tctx,
4387                 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4388                         1, 1, ACB_AUTOLOCK),
4389                 "expected account to be locked");
4390
4391         torture_assert(tctx,
4392                        test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, "random_crap", NT_STATUS_ACCOUNT_LOCKED_OUT),
4393                        "got wrong status from ChangePasswordUser2");
4394
4395         /* bad pwd count should not get updated */
4396         torture_assert(tctx,
4397                 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4398                         1, 1, ACB_AUTOLOCK),
4399                 "expected account to be locked");
4400
4401         /* with bad password */
4402
4403         if (!test_SamLogon_with_creds(tctx, np, machine_credentials,
4404                                       acct_name, "random_crap2",
4405                                       NT_STATUS_ACCOUNT_LOCKED_OUT, interactive))
4406         {
4407                 torture_fail(tctx, "authenticate did not return NT_STATUS_ACCOUNT_LOCKED_OUT");
4408         }
4409
4410         /* bad pwd count should not get updated */
4411         torture_assert(tctx,
4412                 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4413                         1, 1, ACB_AUTOLOCK),
4414                 "expected account to be locked");
4415
4416         /* let lockout duration expire ==> unlock */
4417
4418         torture_comment(tctx, "let lockout duration expire...\n");
4419         sleep(lockout_seconds + 1);
4420
4421         torture_assert(tctx,
4422                 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4423                         1, 0, 0),
4424                 "expected account to not be locked");
4425
4426         if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
4427                                      *password,
4428                                      expected_success_status, interactive))
4429         {
4430                 torture_fail(tctx, "failed to authenticate after lockout expired");
4431         }
4432
4433         if (NT_STATUS_IS_OK(expected_success_status)) {
4434                 torture_assert(tctx,
4435                         test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4436                                 0, 0, 0),
4437                         "expected account to not be locked");
4438         } else {
4439                 torture_assert(tctx,
4440                         test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4441                                 1, 0, 0),
4442                         "expected account to not be locked");
4443         }
4444
4445         torture_assert(tctx,
4446                        test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, "random_crap", NT_STATUS_WRONG_PASSWORD),
4447                        "got wrong status from ChangePasswordUser2");
4448
4449         torture_assert(tctx,
4450                 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4451                         1, 1, ACB_AUTOLOCK),
4452                 "expected account to be locked");
4453
4454         torture_assert(tctx,
4455                        test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, *password, NT_STATUS_ACCOUNT_LOCKED_OUT),
4456                        "got wrong status from ChangePasswordUser2");
4457
4458         torture_assert(tctx,
4459                 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4460                         1, 1, ACB_AUTOLOCK),
4461                 "expected account to be locked");
4462
4463         torture_assert(tctx,
4464                        test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, "random_crap", NT_STATUS_ACCOUNT_LOCKED_OUT),
4465                        "got wrong status from ChangePasswordUser2");
4466
4467         torture_assert(tctx,
4468                 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4469                         1, 1, ACB_AUTOLOCK),
4470                 "expected account to be locked");
4471
4472         /* let lockout duration expire ==> unlock */
4473
4474         torture_comment(tctx, "let lockout duration expire...\n");
4475         sleep(lockout_seconds + 1);
4476
4477         torture_assert(tctx,
4478                 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4479                         1, 0, 0),
4480                 "expected account to not be locked");
4481
4482         if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
4483                                      *password,
4484                                      expected_success_status, interactive))
4485         {
4486                 torture_fail(tctx, "failed to authenticate after lockout expired");
4487         }
4488
4489         if (NT_STATUS_IS_OK(expected_success_status)) {
4490                 torture_assert(tctx,
4491                         test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4492                                 0, 0, 0),
4493                         "expected account to not be locked");
4494         } else {
4495                 torture_assert(tctx,
4496                         test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4497                                 1, 0, 0),
4498                         "expected account to not be locked");
4499         }
4500
4501         /* Testing ChangePasswordUser behaviour with 3 attempts */
4502         info.info12.lockout_threshold = 3;
4503
4504         torture_assert(tctx,
4505                        test_SetDomainInfo(b, tctx, domain_handle,
4506                                           DomainLockoutInformation, &info),
4507                        "failed to set lockout threshold to 3");
4508
4509         if (NT_STATUS_IS_OK(expected_success_status)) {
4510                 torture_assert(tctx,
4511                         test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4512                                 0, 0, 0),
4513                         "expected account to not be locked");
4514         } else {
4515                 torture_assert(tctx,
4516                         test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4517                                 1, 0, 0),
4518                         "expected account to not be locked");
4519         }
4520
4521         torture_assert(tctx,
4522                        test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, "random_crap", NT_STATUS_WRONG_PASSWORD),
4523                        "got wrong status from ChangePasswordUser2");
4524
4525         /* bad pwd count will get updated */
4526         torture_assert(tctx,
4527                 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4528                         1, 1, 0),
4529                 "expected account to not be locked");
4530
4531         torture_assert(tctx,
4532                        test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, "random_crap", NT_STATUS_WRONG_PASSWORD),
4533                        "got wrong status from ChangePasswordUser2");
4534
4535         /* bad pwd count will get updated */
4536         torture_assert(tctx,
4537                 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4538                         2, 2, 0),
4539                 "expected account to not be locked");
4540
4541         torture_assert(tctx,
4542                        test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, "random_crap", NT_STATUS_WRONG_PASSWORD),
4543                        "got wrong status from ChangePasswordUser2");
4544
4545         /* bad pwd count should get updated */
4546         torture_assert(tctx,
4547                 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4548                         3, 3, ACB_AUTOLOCK),
4549                 "expected account to be locked");
4550
4551         torture_assert(tctx,
4552                        test_ChangePasswordUser2_ntstatus(p, tctx, acct_name, *password, NT_STATUS_ACCOUNT_LOCKED_OUT),
4553                        "got wrong status from ChangePasswordUser2");
4554
4555         /* bad pwd count should not get updated */
4556         torture_assert(tctx,
4557                 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4558                         3, 3, ACB_AUTOLOCK),
4559                 "expected account to be locked");
4560
4561         /* let lockout duration expire ==> unlock */
4562
4563         torture_comment(tctx, "let lockout duration expire...\n");
4564         sleep(lockout_seconds + 1);
4565
4566         torture_assert(tctx,
4567                 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4568                         3, 0, 0),
4569                 "expected account to not be locked");
4570
4571         torture_assert(tctx,
4572                        test_ChangePasswordUser2(p, tctx, acct_name, password, NULL, false),
4573                        "got wrong status from ChangePasswordUser2");
4574
4575         torture_assert(tctx,
4576                 test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4577                         3, 0, 0),
4578                 "expected account to not be locked");
4579
4580         /* Used to reset the badPwdCount for the other tests */
4581         if (!test_SamLogon_with_creds(tctx, np, machine_credentials, acct_name,
4582                                       *password,
4583                                       expected_success_status, interactive))
4584         {
4585                 torture_fail(tctx, "failed to authenticate after lockout expired");
4586         }
4587
4588         if (NT_STATUS_IS_OK(expected_success_status)) {
4589                 torture_assert(tctx,
4590                         test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4591                                 0, 0, 0),
4592                         "expected account to not be locked");
4593         } else {
4594                 torture_assert(tctx,
4595                         test_QueryUserInfo_lockout(b, tctx, domain_handle, acct_name,
4596                                 3, 0, 0),
4597                         "expected account to not be locked");
4598         }
4599
4600         return true;
4601 }
4602
4603 static bool test_Password_lockout_wrap(struct dcerpc_pipe *p,
4604                                        struct torture_context *tctx,
4605                                        uint32_t acct_flags,
4606                                        const char *acct_name,
4607                                        struct policy_handle *domain_handle,
4608                                        struct policy_handle *user_handle,
4609                                        char **password,
4610                                        struct cli_credentials *machine_credentials)
4611 {
4612         union samr_DomainInfo *q_info, s_info;
4613         struct samr_DomInfo1 info1, _info1;
4614         struct samr_DomInfo12 info12, _info12;
4615         bool ret = true;
4616         struct dcerpc_binding_handle *b = p->binding_handle;
4617         struct dcerpc_pipe *np;
4618         int i;
4619
4620         struct {
4621                 const char *comment;
4622                 bool disabled;
4623                 bool interactive;
4624                 uint32_t password_history_length;
4625                 NTSTATUS expected_success_status;
4626         } creds[] = {
4627                 {
4628                         .comment                = "network logon (disabled account)",
4629                         .disabled               = true,
4630                         .interactive            = false,
4631                         .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4632                 },
4633                 {
4634                         .comment                = "network logon (enabled account)",
4635                         .disabled               = false,
4636                         .interactive            = false,
4637                         .expected_success_status= NT_STATUS_OK
4638                 },
4639                 {
4640                         .comment                = "network logon (enabled account, history len = 1)",
4641                         .disabled               = false,
4642                         .interactive            = false,
4643                         .expected_success_status= NT_STATUS_OK,
4644                         .password_history_length = 1
4645                 },
4646                 {
4647                         .comment                = "interactive logon (disabled account)",
4648                         .disabled               = true,
4649                         .interactive            = true,
4650                         .expected_success_status= NT_STATUS_ACCOUNT_DISABLED
4651                 },
4652                 {
4653                         .comment                = "interactive logon (enabled account)",
4654                         .disabled               = false,
4655                         .interactive            = true,
4656                         .expected_success_status= NT_STATUS_OK
4657                 },
4658                 {
4659                         .comment                = "interactive logon (enabled account, history len = 1)",
4660                         .disabled               = false,
4661                         .interactive            = true,
4662                         .expected_success_status= NT_STATUS_OK,
4663                         .password_history_length = 1
4664                 },
4665         };
4666
4667         torture_assert(tctx, setup_schannel_netlogon_pipe(tctx, machine_credentials, &np), "");
4668
4669         /* backup old policies */
4670
4671         torture_assert(tctx,
4672                 test_QueryDomainInfo2_level(b, tctx, domain_handle,
4673                                             DomainPasswordInformation, &q_info),
4674                 "failed to query domain info level 1");
4675
4676         info1 = q_info->info1;
4677         _info1 = info1;
4678
4679         torture_assert(tctx,
4680                 test_QueryDomainInfo2_level(b, tctx, domain_handle,
4681                                             DomainLockoutInformation, &q_info),
4682                 "failed to query domain info level 12");
4683
4684         info12 = q_info->info12;
4685         _info12 = info12;
4686
4687         /* run tests */
4688
4689         for (i=0; i < ARRAY_SIZE(creds); i++) {
4690                 bool test_passed;
4691                 /* skip trust tests for now */
4692                 if (acct_flags & ACB_WSTRUST ||
4693                     acct_flags & ACB_SVRTRUST ||
4694                     acct_flags & ACB_DOMTRUST) {
4695                         continue;
4696                 }
4697
4698                 test_passed = test_Password_lockout(p, np, tctx, acct_flags, acct_name,
4699                                              domain_handle, user_handle, password,
4700                                              machine_credentials,
4701                                              creds[i].comment,
4702                                              creds[i].disabled,
4703                                              creds[i].interactive,
4704                                              creds[i].password_history_length,
4705                                              creds[i].expected_success_status,
4706                                              &_info1, &_info12);
4707                 ret &= test_passed;
4708                 if (!test_passed) {
4709                         torture_result(tctx, TORTURE_FAIL, "TEST #%d (%s) failed\n", i, creds[i].comment);
4710                         break;
4711                 } else {
4712                         torture_comment(tctx, "TEST #%d (%s) succeeded\n", i, creds[i].comment);
4713                 }
4714         }
4715
4716         /* restore policies */
4717
4718         s_info.info1 = info1;
4719
4720         torture_assert(tctx,
4721                        test_SetDomainInfo(b, tctx, domain_handle,
4722                                           DomainPasswordInformation, &s_info),
4723                        "failed to set password information");
4724
4725         s_info.info12 = info12;
4726
4727         torture_assert(tctx,
4728                        test_SetDomainInfo(b, tctx, domain_handle,
4729                                           DomainLockoutInformation, &s_info),
4730                        "failed to set lockout information");
4731
4732         return ret;
4733 }
4734
4735 static bool test_DeleteUser_with_privs(struct dcerpc_pipe *p,
4736                                        struct dcerpc_pipe *lp,
4737                                        struct torture_context *tctx,
4738                                        struct policy_handle *domain_handle,
4739                                        struct policy_handle *lsa_handle,
4740                                        struct policy_handle *user_handle,
4741                                        const struct dom_sid *domain_sid,
4742                                        uint32_t rid,
4743                                        struct cli_credentials *machine_credentials)
4744 {
4745         bool ret = true;
4746         struct dcerpc_binding_handle *b = p->binding_handle;
4747         struct dcerpc_binding_handle *lb = lp->binding_handle;
4748
4749         struct policy_handle lsa_acct_handle;
4750         struct dom_sid *user_sid;
4751
4752         user_sid = dom_sid_add_rid(tctx, domain_sid, rid);
4753
4754         {
4755                 struct lsa_EnumAccountRights r;
4756                 struct lsa_RightSet rights;
4757
4758                 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4759
4760                 r.in.handle = lsa_handle;
4761                 r.in.sid = user_sid;
4762                 r.out.rights = &rights;
4763
4764                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4765                         "lsa_EnumAccountRights failed");
4766                 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4767                         "Expected enum rights for account to fail");
4768         }
4769
4770         {
4771                 struct lsa_RightSet rights;
4772                 struct lsa_StringLarge names[2];
4773                 struct lsa_AddAccountRights r;
4774
4775                 torture_comment(tctx, "Testing LSA AddAccountRights\n");
4776
4777                 init_lsa_StringLarge(&names[0], "SeMachineAccountPrivilege");
4778                 init_lsa_StringLarge(&names[1], NULL);
4779
4780                 rights.count = 1;
4781                 rights.names = names;
4782
4783                 r.in.handle = lsa_handle;
4784                 r.in.sid = user_sid;
4785                 r.in.rights = &rights;
4786
4787                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_AddAccountRights_r(lb, tctx, &r),
4788                         "lsa_AddAccountRights failed");
4789                 torture_assert_ntstatus_ok(tctx, r.out.result,
4790                         "Failed to add privileges");
4791         }
4792
4793         {
4794                 struct lsa_EnumAccounts r;
4795                 uint32_t resume_handle = 0;
4796                 struct lsa_SidArray lsa_sid_array;
4797                 int i;
4798                 bool found_sid = false;
4799
4800                 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4801
4802                 r.in.handle = lsa_handle;
4803                 r.in.num_entries = 0x1000;
4804                 r.in.resume_handle = &resume_handle;
4805                 r.out.sids = &lsa_sid_array;
4806                 r.out.resume_handle = &resume_handle;
4807
4808                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
4809                         "lsa_EnumAccounts failed");
4810                 torture_assert_ntstatus_ok(tctx, r.out.result,
4811                         "Failed to enum accounts");
4812
4813                 for (i=0; i < lsa_sid_array.num_sids; i++) {
4814                         if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
4815                                 found_sid = true;
4816                         }
4817                 }
4818
4819                 torture_assert(tctx, found_sid,
4820                         "failed to list privileged account");
4821         }
4822
4823         {
4824                 struct lsa_EnumAccountRights r;
4825                 struct lsa_RightSet user_rights;
4826
4827                 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4828
4829                 r.in.handle = lsa_handle;
4830                 r.in.sid = user_sid;
4831                 r.out.rights = &user_rights;
4832
4833                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4834                         "lsa_EnumAccountRights failed");
4835                 torture_assert_ntstatus_ok(tctx, r.out.result,
4836                         "Failed to enum rights for account");
4837
4838                 if (user_rights.count < 1) {
4839                         torture_result(tctx, TORTURE_FAIL, "failed to find newly added rights");
4840                         return false;
4841                 }
4842         }
4843
4844         {
4845                 struct lsa_OpenAccount r;
4846
4847                 torture_comment(tctx, "Testing LSA OpenAccount\n");
4848
4849                 r.in.handle = lsa_handle;
4850                 r.in.sid = user_sid;
4851                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4852                 r.out.acct_handle = &lsa_acct_handle;
4853
4854                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(lb, tctx, &r),
4855                         "lsa_OpenAccount failed");
4856                 torture_assert_ntstatus_ok(tctx, r.out.result,
4857                         "Failed to open lsa account");
4858         }
4859
4860         {
4861                 struct lsa_GetSystemAccessAccount r;
4862                 uint32_t access_mask;
4863
4864                 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
4865
4866                 r.in.handle = &lsa_acct_handle;
4867                 r.out.access_mask = &access_mask;
4868
4869                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetSystemAccessAccount_r(lb, tctx, &r),
4870                         "lsa_GetSystemAccessAccount failed");
4871                 torture_assert_ntstatus_ok(tctx, r.out.result,
4872                         "Failed to get lsa system access account");
4873         }
4874
4875         {
4876                 struct lsa_Close r;
4877
4878                 torture_comment(tctx, "Testing LSA Close\n");
4879
4880                 r.in.handle = &lsa_acct_handle;
4881                 r.out.handle = &lsa_acct_handle;
4882
4883                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Close_r(lb, tctx, &r),
4884                         "lsa_Close failed");
4885                 torture_assert_ntstatus_ok(tctx, r.out.result,
4886                         "Failed to close lsa");
4887         }
4888
4889         {
4890                 struct samr_DeleteUser r;
4891
4892                 torture_comment(tctx, "Testing SAMR DeleteUser\n");
4893
4894                 r.in.user_handle = user_handle;
4895                 r.out.user_handle = user_handle;
4896
4897                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &r),
4898                         "DeleteUser failed");
4899                 torture_assert_ntstatus_ok(tctx, r.out.result,
4900                         "DeleteUser failed");
4901         }
4902
4903         {
4904                 struct lsa_EnumAccounts r;
4905                 uint32_t resume_handle = 0;
4906                 struct lsa_SidArray lsa_sid_array;
4907                 int i;
4908                 bool found_sid = false;
4909
4910                 torture_comment(tctx, "Testing LSA EnumAccounts\n");
4911
4912                 r.in.handle = lsa_handle;
4913                 r.in.num_entries = 0x1000;
4914                 r.in.resume_handle = &resume_handle;
4915                 r.out.sids = &lsa_sid_array;
4916                 r.out.resume_handle = &resume_handle;
4917
4918                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
4919                         "lsa_EnumAccounts failed");
4920                 torture_assert_ntstatus_ok(tctx, r.out.result,
4921                         "Failed to enum accounts");
4922
4923                 for (i=0; i < lsa_sid_array.num_sids; i++) {
4924                         if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
4925                                 found_sid = true;
4926                         }
4927                 }
4928
4929                 torture_assert(tctx, found_sid,
4930                         "failed to list privileged account");
4931         }
4932
4933         {
4934                 struct lsa_EnumAccountRights r;
4935                 struct lsa_RightSet user_rights;
4936
4937                 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
4938
4939                 r.in.handle = lsa_handle;
4940                 r.in.sid = user_sid;
4941                 r.out.rights = &user_rights;
4942
4943                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
4944                         "lsa_EnumAccountRights failed");
4945                 torture_assert_ntstatus_ok(tctx, r.out.result,
4946                         "Failed to enum rights for account");
4947
4948                 if (user_rights.count < 1) {
4949                         torture_result(tctx, TORTURE_FAIL, "failed to find newly added rights");
4950                         return false;
4951                 }
4952         }
4953
4954         {
4955                 struct lsa_OpenAccount r;
4956
4957                 torture_comment(tctx, "Testing LSA OpenAccount\n");
4958
4959                 r.in.handle = lsa_handle;
4960                 r.in.sid = user_sid;
4961                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4962                 r.out.acct_handle = &lsa_acct_handle;
4963
4964                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(lb, tctx, &r),
4965                         "lsa_OpenAccount failed");
4966                 torture_assert_ntstatus_ok(tctx, r.out.result,
4967                         "Failed to open lsa account");
4968         }
4969
4970         {
4971                 struct lsa_GetSystemAccessAccount r;
4972                 uint32_t access_mask;
4973
4974                 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
4975
4976                 r.in.handle = &lsa_acct_handle;
4977                 r.out.access_mask = &access_mask;
4978
4979                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetSystemAccessAccount_r(lb, tctx, &r),
4980                         "lsa_GetSystemAccessAccount failed");
4981                 torture_assert_ntstatus_ok(tctx, r.out.result,
4982                         "Failed to get lsa system access account");
4983         }
4984
4985         {
4986                 struct lsa_DeleteObject r;
4987
4988                 torture_comment(tctx, "Testing LSA DeleteObject\n");
4989
4990                 r.in.handle = &lsa_acct_handle;
4991                 r.out.handle = &lsa_acct_handle;
4992
4993                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_DeleteObject_r(lb, tctx, &r),
4994                         "lsa_DeleteObject failed");
4995                 torture_assert_ntstatus_ok(tctx, r.out.result,
4996                         "Failed to delete object");
4997         }
4998
4999         {
5000                 struct lsa_EnumAccounts r;
5001                 uint32_t resume_handle = 0;
5002                 struct lsa_SidArray lsa_sid_array;
5003                 int i;
5004                 bool found_sid = false;
5005
5006                 torture_comment(tctx, "Testing LSA EnumAccounts\n");
5007
5008                 r.in.handle = lsa_handle;
5009                 r.in.num_entries = 0x1000;
5010                 r.in.resume_handle = &resume_handle;
5011                 r.out.sids = &lsa_sid_array;
5012                 r.out.resume_handle = &resume_handle;
5013
5014                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(lb, tctx, &r),
5015                         "lsa_EnumAccounts failed");
5016                 torture_assert_ntstatus_ok(tctx, r.out.result,
5017                         "Failed to enum accounts");
5018
5019                 for (i=0; i < lsa_sid_array.num_sids; i++) {
5020                         if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
5021                                 found_sid = true;
5022                         }
5023                 }
5024
5025                 torture_assert(tctx, !found_sid,
5026                         "should not have listed privileged account");
5027         }
5028
5029         {
5030                 struct lsa_EnumAccountRights r;
5031                 struct lsa_RightSet user_rights;
5032
5033                 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
5034
5035                 r.in.handle = lsa_handle;
5036                 r.in.sid = user_sid;
5037                 r.out.rights = &user_rights;
5038
5039                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(lb, tctx, &r),
5040                         "lsa_EnumAccountRights failed");
5041                 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND,
5042                         "Failed to enum rights for account");
5043         }
5044
5045         return ret;
5046 }
5047
5048 static bool test_user_ops(struct dcerpc_pipe *p,
5049                           struct torture_context *tctx,
5050                           struct policy_handle *user_handle,
5051                           struct policy_handle *domain_handle,
5052                           const struct dom_sid *domain_sid,
5053                           uint32_t base_acct_flags,
5054                           const char *base_acct_name, enum torture_samr_choice which_ops,
5055                           struct cli_credentials *machine_credentials)
5056 {
5057         char *password = NULL;
5058         struct samr_QueryUserInfo q;
5059         union samr_UserInfo *info;
5060         NTSTATUS status;
5061         struct dcerpc_binding_handle *b = p->binding_handle;
5062
5063         bool ret = true;
5064         int i;
5065         uint32_t rid;
5066         const uint32_t password_fields[] = {
5067                 SAMR_FIELD_NT_PASSWORD_PRESENT,
5068                 SAMR_FIELD_LM_PASSWORD_PRESENT,
5069                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
5070                 0
5071         };
5072
5073         status = test_LookupName(b, tctx, domain_handle, base_acct_name, &rid);
5074         if (!NT_STATUS_IS_OK(status)) {
5075                 ret = false;
5076         }
5077
5078         switch (which_ops) {
5079         case TORTURE_SAMR_USER_ATTRIBUTES:
5080                 if (!test_QuerySecurity(b, tctx, user_handle)) {
5081                         ret = false;
5082                 }
5083
5084                 if (!test_QueryUserInfo(b, tctx, user_handle)) {
5085                         ret = false;
5086                 }
5087
5088                 if (!test_QueryUserInfo2(b, tctx, user_handle)) {
5089                         ret = false;
5090                 }
5091
5092                 if (!test_SetUserInfo(b, tctx, user_handle, base_acct_flags,
5093                                       base_acct_name)) {
5094                         ret = false;
5095                 }
5096
5097                 if (!test_GetUserPwInfo(b, tctx, user_handle)) {
5098                         ret = false;
5099                 }
5100
5101                 if (!test_TestPrivateFunctionsUser(b, tctx, user_handle)) {
5102                         ret = false;
5103                 }
5104
5105                 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
5106                         ret = false;
5107                 }
5108                 break;
5109         case TORTURE_SAMR_PASSWORDS:
5110                 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
5111                         char simple_pass[9];
5112                         char *v = generate_random_str(tctx, 1);
5113
5114                         ZERO_STRUCT(simple_pass);
5115                         memset(simple_pass, *v, sizeof(simple_pass) - 1);
5116
5117                         torture_comment(tctx, "Testing machine account password policy rules\n");
5118
5119                         /* Workstation trust accounts don't seem to need to honour password quality policy */
5120                         if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
5121                                 ret = false;
5122                         }
5123
5124                         if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
5125                                 ret = false;
5126                         }
5127
5128                         /* reset again, to allow another 'user' password change */
5129                         if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
5130                                 ret = false;
5131                         }
5132
5133                         /* Try a 'short' password */
5134                         if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
5135                                 ret = false;
5136                         }
5137
5138                         /* Try a compleatly random password */
5139                         if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
5140                                 ret = false;
5141                         }
5142                 }
5143
5144                 for (i = 0; password_fields[i]; i++) {
5145                         if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
5146                                 ret = false;
5147                         }
5148
5149                         /* check it was set right */
5150                         if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
5151                                 ret = false;
5152                         }
5153                 }
5154
5155                 for (i = 0; password_fields[i]; i++) {
5156                         if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
5157                                 ret = false;
5158                         }
5159
5160                         /* check it was set right */
5161                         if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
5162                                 ret = false;
5163                         }
5164                 }
5165
5166                 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
5167                         ret = false;
5168                 }
5169
5170                 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
5171                         ret = false;
5172                 }
5173
5174                 if (!test_SetUserPass_18(p, tctx, user_handle, &password)) {
5175                         ret = false;
5176                 }
5177
5178                 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
5179                         ret = false;
5180                 }
5181
5182                 for (i = 0; password_fields[i]; i++) {
5183
5184                         if (password_fields[i] == SAMR_FIELD_LM_PASSWORD_PRESENT) {
5185                                 /* we need to skip as that would break
5186                                  * the ChangePasswordUser3 verify */
5187                                 continue;
5188                         }
5189
5190                         if (!test_SetUserPass_21(p, tctx, user_handle, password_fields[i], &password)) {
5191                                 ret = false;
5192                         }
5193
5194                         /* check it was set right */
5195                         if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
5196                                 ret = false;
5197                         }
5198                 }
5199
5200                 q.in.user_handle = user_handle;
5201                 q.in.level = 5;
5202                 q.out.info = &info;
5203
5204                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
5205                         "QueryUserInfo failed");
5206                 if (!NT_STATUS_IS_OK(q.out.result)) {
5207                         torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level %u failed - %s\n",
5208                                q.in.level, nt_errstr(q.out.result));
5209                         ret = false;
5210                 } else {
5211                         uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
5212                         if ((info->info5.acct_flags) != expected_flags) {
5213                                 /* FIXME: GD */
5214                                 if (!torture_setting_bool(tctx, "samba3", false)) {
5215                                         torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5216                                                       info->info5.acct_flags,
5217                                                       expected_flags);
5218                                         ret = false;
5219                                 }
5220                         }
5221                         if (info->info5.rid != rid) {
5222                                 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
5223                                        info->info5.rid, rid);
5224
5225                         }
5226                 }
5227
5228                 break;
5229
5230         case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
5231
5232                 /* test last password change timestamp behaviour */
5233                 torture_assert(tctx, test_SetPassword_pwdlastset(p, tctx, base_acct_flags,
5234                                                                  base_acct_name,
5235                                                                  user_handle, &password,
5236                                                                  machine_credentials),
5237                                "pwdLastSet test failed\n");
5238                 break;
5239
5240         case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT:
5241
5242                 /* test bad pwd count change behaviour */
5243                 torture_assert(tctx, test_Password_badpwdcount_wrap(p, tctx, base_acct_flags,
5244                                                                     base_acct_name,
5245                                                                     domain_handle,
5246                                                                     user_handle, &password,
5247                                                                     machine_credentials),
5248                                "badPwdCount test failed\n");
5249                 break;
5250
5251         case TORTURE_SAMR_PASSWORDS_LOCKOUT:
5252
5253                 torture_assert(tctx, test_Password_lockout_wrap(p, tctx, base_acct_flags,
5254                                                                 base_acct_name,
5255                                                                 domain_handle,
5256                                                                 user_handle, &password,
5257                                                                 machine_credentials),
5258                                "Lockout test failed");
5259                 break;
5260
5261
5262         case TORTURE_SAMR_USER_PRIVILEGES: {
5263
5264                 struct dcerpc_pipe *lp;
5265                 struct policy_handle *lsa_handle;
5266                 struct dcerpc_binding_handle *lb;
5267
5268                 status = torture_rpc_connection(tctx, &lp, &ndr_table_lsarpc);
5269                 torture_assert_ntstatus_ok(tctx, status, "Failed to open LSA pipe");
5270                 lb = lp->binding_handle;
5271
5272                 if (!test_lsa_OpenPolicy2(lb, tctx, &lsa_handle)) {
5273                         ret = false;
5274                 }
5275
5276                 if (!test_DeleteUser_with_privs(p, lp, tctx,
5277                                                 domain_handle, lsa_handle, user_handle,
5278                                                 domain_sid, rid,
5279                                                 machine_credentials)) {
5280                         ret = false;
5281                 }
5282
5283                 if (!test_lsa_Close(lb, tctx, lsa_handle)) {
5284                         ret = false;
5285                 }
5286
5287                 if (!ret) {
5288                         torture_result(tctx, TORTURE_FAIL, "privileged user delete test failed\n");
5289                 }
5290
5291                 break;
5292         }
5293         case TORTURE_SAMR_OTHER:
5294         case TORTURE_SAMR_MANY_ACCOUNTS:
5295         case TORTURE_SAMR_MANY_GROUPS:
5296         case TORTURE_SAMR_MANY_ALIASES:
5297                 /* We just need the account to exist */
5298                 break;
5299         }
5300         return ret;
5301 }
5302
5303 static bool test_alias_ops(struct dcerpc_binding_handle *b,
5304                            struct torture_context *tctx,
5305                            struct policy_handle *alias_handle,
5306                            const struct dom_sid *domain_sid)
5307 {
5308         bool ret = true;
5309
5310         if (!torture_setting_bool(tctx, "samba3", false)) {
5311                 if (!test_QuerySecurity(b, tctx, alias_handle)) {
5312                         ret = false;
5313                 }
5314         }
5315
5316         if (!test_QueryAliasInfo(b, tctx, alias_handle)) {
5317                 ret = false;
5318         }
5319
5320         if (!test_SetAliasInfo(b, tctx, alias_handle)) {
5321                 ret = false;
5322         }
5323
5324         if (!test_AddMemberToAlias(b, tctx, alias_handle, domain_sid)) {
5325                 ret = false;
5326         }
5327
5328         if (torture_setting_bool(tctx, "samba3", false) ||
5329             torture_setting_bool(tctx, "samba4", false)) {
5330                 torture_comment(tctx, "skipping MultipleMembers Alias tests against Samba\n");
5331                 return ret;
5332         }
5333
5334         if (!test_AddMultipleMembersToAlias(b, tctx, alias_handle)) {
5335                 ret = false;
5336         }
5337
5338         return ret;
5339 }
5340
5341
5342 static bool test_DeleteUser(struct dcerpc_binding_handle *b,
5343                             struct torture_context *tctx,
5344                             struct policy_handle *user_handle)
5345 {
5346         struct samr_DeleteUser d;
5347         torture_comment(tctx, "Testing DeleteUser\n");
5348
5349         d.in.user_handle = user_handle;
5350         d.out.user_handle = user_handle;
5351
5352         torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &d),
5353                 "DeleteUser failed");
5354         torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteUser");
5355
5356         return true;
5357 }
5358
5359 bool test_DeleteUser_byname(struct dcerpc_binding_handle *b,
5360                             struct torture_context *tctx,
5361                             struct policy_handle *handle, const char *name)
5362 {
5363         NTSTATUS status;
5364         struct samr_DeleteUser d;
5365         struct policy_handle user_handle;
5366         uint32_t rid;
5367
5368         status = test_LookupName(b, tctx, handle, name, &rid);
5369         if (!NT_STATUS_IS_OK(status)) {
5370                 goto failed;
5371         }
5372
5373         status = test_OpenUser_byname(b, tctx, handle, name, &user_handle);
5374         if (!NT_STATUS_IS_OK(status)) {
5375                 goto failed;
5376         }
5377
5378         d.in.user_handle = &user_handle;
5379         d.out.user_handle = &user_handle;
5380         torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, tctx, &d),
5381                 "DeleteUser failed");
5382         if (!NT_STATUS_IS_OK(d.out.result)) {
5383                 status = d.out.result;
5384                 goto failed;
5385         }
5386
5387         return true;
5388
5389 failed:
5390         torture_result(tctx, TORTURE_FAIL, "DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
5391         return false;
5392 }
5393
5394
5395 static bool test_DeleteGroup_byname(struct dcerpc_binding_handle *b,
5396                                     struct torture_context *tctx,
5397                                     struct policy_handle *handle, const char *name)
5398 {
5399         NTSTATUS status;
5400         struct samr_OpenGroup r;
5401         struct samr_DeleteDomainGroup d;
5402         struct policy_handle group_handle;
5403         uint32_t rid;
5404
5405         status = test_LookupName(b, tctx, handle, name, &rid);
5406         if (!NT_STATUS_IS_OK(status)) {
5407                 goto failed;
5408         }
5409
5410         r.in.domain_handle = handle;
5411         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5412         r.in.rid = rid;
5413         r.out.group_handle = &group_handle;
5414         torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenGroup_r(b, tctx, &r),
5415                 "OpenGroup failed");
5416         if (!NT_STATUS_IS_OK(r.out.result)) {
5417                 status = r.out.result;
5418                 goto failed;
5419         }
5420
5421         d.in.group_handle = &group_handle;
5422         d.out.group_handle = &group_handle;
5423         torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomainGroup_r(b, tctx, &d),
5424                 "DeleteDomainGroup failed");
5425         if (!NT_STATUS_IS_OK(d.out.result)) {
5426                 status = d.out.result;
5427                 goto failed;
5428         }
5429
5430         return true;
5431
5432 failed:
5433         torture_result(tctx, TORTURE_FAIL, "DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
5434         return false;
5435 }
5436
5437
5438 static bool test_DeleteAlias_byname(struct dcerpc_binding_handle *b,
5439                                     struct torture_context *tctx,
5440                                     struct policy_handle *domain_handle,
5441                                     const char *name)
5442 {
5443         NTSTATUS status;
5444         struct samr_OpenAlias r;
5445         struct samr_DeleteDomAlias d;
5446         struct policy_handle alias_handle;
5447         uint32_t rid;
5448
5449         torture_comment(tctx, "Testing DeleteAlias_byname\n");
5450
5451         status = test_LookupName(b, tctx, domain_handle, name, &rid);
5452         if (!NT_STATUS_IS_OK(status)) {
5453                 goto failed;
5454         }
5455
5456         r.in.domain_handle = domain_handle;
5457         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5458         r.in.rid = rid;
5459         r.out.alias_handle = &alias_handle;
5460         torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenAlias_r(b, tctx, &r),
5461                 "OpenAlias failed");
5462         if (!NT_STATUS_IS_OK(r.out.result)) {
5463                 status = r.out.result;
5464                 goto failed;
5465         }
5466
5467         d.in.alias_handle = &alias_handle;
5468         d.out.alias_handle = &alias_handle;
5469         torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomAlias_r(b, tctx, &d),
5470                 "DeleteDomAlias failed");
5471         if (!NT_STATUS_IS_OK(d.out.result)) {
5472                 status = d.out.result;
5473                 goto failed;
5474         }
5475
5476         return true;
5477
5478 failed:
5479         torture_result(tctx, TORTURE_FAIL, "DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
5480         return false;
5481 }
5482
5483 static bool test_DeleteAlias(struct dcerpc_binding_handle *b,
5484                              struct torture_context *tctx,
5485                              struct policy_handle *alias_handle)
5486 {
5487         struct samr_DeleteDomAlias d;
5488         bool ret = true;
5489
5490         torture_comment(tctx, "Testing DeleteAlias\n");
5491
5492         d.in.alias_handle = alias_handle;
5493         d.out.alias_handle = alias_handle;
5494
5495         torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomAlias_r(b, tctx, &d),
5496                 "DeleteDomAlias failed");
5497         if (!NT_STATUS_IS_OK(d.out.result)) {
5498                 torture_result(tctx, TORTURE_FAIL, "DeleteAlias failed - %s\n", nt_errstr(d.out.result));
5499                 ret = false;
5500         }
5501
5502         return ret;
5503 }
5504
5505 static bool test_CreateAlias(struct dcerpc_binding_handle *b,
5506                              struct torture_context *tctx,
5507                              struct policy_handle *domain_handle,
5508                              const char *alias_name,
5509                              struct policy_handle *alias_handle,
5510                              const struct dom_sid *domain_sid,
5511                              bool test_alias)
5512 {
5513         struct samr_CreateDomAlias r;
5514         struct lsa_String name;
5515         uint32_t rid;
5516         bool ret = true;
5517
5518         init_lsa_String(&name, alias_name);
5519         r.in.domain_handle = domain_handle;
5520         r.in.alias_name = &name;
5521         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5522         r.out.alias_handle = alias_handle;
5523         r.out.rid = &rid;
5524
5525         torture_comment(tctx, "Testing CreateAlias (%s)\n", r.in.alias_name->string);
5526
5527         torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomAlias_r(b, tctx, &r),
5528                 "CreateDomAlias failed");
5529
5530         if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5531                 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED)) {
5532                         torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.alias_name->string);
5533                         return true;
5534                 } else {
5535                         torture_result(tctx, TORTURE_FAIL, "Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
5536                                nt_errstr(r.out.result));
5537                         return false;
5538                 }
5539         }
5540
5541         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ALIAS_EXISTS)) {
5542                 if (!test_DeleteAlias_byname(b, tctx, domain_handle, r.in.alias_name->string)) {
5543                         return false;
5544                 }
5545                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomAlias_r(b, tctx, &r),
5546                         "CreateDomAlias failed");
5547         }
5548
5549         if (!NT_STATUS_IS_OK(r.out.result)) {
5550                 torture_result(tctx, TORTURE_FAIL, "CreateAlias failed - %s\n", nt_errstr(r.out.result));
5551                 return false;
5552         }
5553
5554         if (!test_alias) {
5555                 return ret;
5556         }
5557
5558         if (!test_alias_ops(b, tctx, alias_handle, domain_sid)) {
5559                 ret = false;
5560         }
5561
5562         return ret;
5563 }
5564
5565 static bool test_ChangePassword(struct dcerpc_pipe *p,
5566                                 struct torture_context *tctx,
5567                                 const char *acct_name,
5568                                 struct policy_handle *domain_handle, char **password)
5569 {
5570         bool ret = true;
5571         struct dcerpc_binding_handle *b = p->binding_handle;
5572
5573         if (!*password) {
5574                 return false;
5575         }
5576
5577         if (!test_ChangePasswordUser(b, tctx, acct_name, domain_handle, password)) {
5578                 ret = false;
5579         }
5580
5581         if (!test_ChangePasswordUser2(p, tctx, acct_name, password, 0, true)) {
5582                 ret = false;
5583         }
5584
5585         if (!test_OemChangePasswordUser2(p, tctx, acct_name, domain_handle, password)) {
5586                 ret = false;
5587         }
5588
5589         /* test what happens when setting the old password again */
5590         if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, *password, 0, true)) {
5591                 ret = false;
5592         }
5593
5594         {
5595                 char simple_pass[9];
5596                 char *v = generate_random_str(tctx, 1);
5597
5598                 ZERO_STRUCT(simple_pass);
5599                 memset(simple_pass, *v, sizeof(simple_pass) - 1);
5600
5601                 /* test what happens when picking a simple password */
5602                 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, simple_pass, 0, true)) {
5603                         ret = false;
5604                 }
5605         }
5606
5607         /* set samr_SetDomainInfo level 1 with min_length 5 */
5608         {
5609                 struct samr_QueryDomainInfo r;
5610                 union samr_DomainInfo *info = NULL;
5611                 struct samr_SetDomainInfo s;
5612                 uint16_t len_old, len;
5613                 uint32_t pwd_prop_old;
5614                 int64_t min_pwd_age_old;
5615
5616                 len = 5;
5617
5618                 r.in.domain_handle = domain_handle;
5619                 r.in.level = 1;
5620                 r.out.info = &info;
5621
5622                 torture_comment(tctx, "Testing samr_QueryDomainInfo level 1\n");
5623                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
5624                         "QueryDomainInfo failed");
5625                 if (!NT_STATUS_IS_OK(r.out.result)) {
5626                         return false;
5627                 }
5628
5629                 s.in.domain_handle = domain_handle;
5630                 s.in.level = 1;
5631                 s.in.info = info;
5632
5633                 /* remember the old min length, so we can reset it */
5634                 len_old = s.in.info->info1.min_password_length;
5635                 s.in.info->info1.min_password_length = len;
5636                 pwd_prop_old = s.in.info->info1.password_properties;
5637                 /* turn off password complexity checks for this test */
5638                 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
5639
5640                 min_pwd_age_old = s.in.info->info1.min_password_age;
5641                 s.in.info->info1.min_password_age = 0;
5642
5643                 torture_comment(tctx, "Testing samr_SetDomainInfo level 1\n");
5644                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
5645                         "SetDomainInfo failed");
5646                 if (!NT_STATUS_IS_OK(s.out.result)) {
5647                         return false;
5648                 }
5649
5650                 torture_comment(tctx, "calling test_ChangePasswordUser3 with too short password\n");
5651
5652                 if (!test_ChangePasswordUser3(p, tctx, acct_name, len - 1, password, NULL, 0, true)) {
5653                         ret = false;
5654                 }
5655
5656                 s.in.info->info1.min_password_length = len_old;
5657                 s.in.info->info1.password_properties = pwd_prop_old;
5658                 s.in.info->info1.min_password_age = min_pwd_age_old;
5659
5660                 torture_comment(tctx, "Testing samr_SetDomainInfo level 1\n");
5661                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
5662                         "SetDomainInfo failed");
5663                 if (!NT_STATUS_IS_OK(s.out.result)) {
5664                         return false;
5665                 }
5666
5667         }
5668
5669         {
5670                 struct samr_OpenUser r;
5671                 struct samr_QueryUserInfo q;
5672                 union samr_UserInfo *info;
5673                 struct samr_LookupNames n;
5674                 struct policy_handle user_handle;
5675                 struct samr_Ids rids, types;
5676
5677                 n.in.domain_handle = domain_handle;
5678                 n.in.num_names = 1;
5679                 n.in.names = talloc_array(tctx, struct lsa_String, 1);
5680                 n.in.names[0].string = acct_name;
5681                 n.out.rids = &rids;
5682                 n.out.types = &types;
5683
5684                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupNames_r(b, tctx, &n),
5685                         "LookupNames failed");
5686                 if (!NT_STATUS_IS_OK(n.out.result)) {
5687                         torture_result(tctx, TORTURE_FAIL, "LookupNames failed - %s\n", nt_errstr(n.out.result));
5688                         return false;
5689                 }
5690
5691                 r.in.domain_handle = domain_handle;
5692                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5693                 r.in.rid = n.out.rids->ids[0];
5694                 r.out.user_handle = &user_handle;
5695
5696                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
5697                         "OpenUser failed");
5698                 if (!NT_STATUS_IS_OK(r.out.result)) {
5699                         torture_result(tctx, TORTURE_FAIL, "OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(r.out.result));
5700                         return false;
5701                 }
5702
5703                 q.in.user_handle = &user_handle;
5704                 q.in.level = 5;
5705                 q.out.info = &info;
5706
5707                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
5708                         "QueryUserInfo failed");
5709                 if (!NT_STATUS_IS_OK(q.out.result)) {
5710                         torture_result(tctx, TORTURE_FAIL, "QueryUserInfo failed - %s\n", nt_errstr(q.out.result));
5711                         return false;
5712                 }
5713
5714                 torture_comment(tctx, "calling test_ChangePasswordUser3 with too early password change\n");
5715
5716                 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL,
5717                                               info->info5.last_password_change, true)) {
5718                         ret = false;
5719                 }
5720         }
5721
5722         /* we change passwords twice - this has the effect of verifying
5723            they were changed correctly for the final call */
5724         if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
5725                 ret = false;
5726         }
5727
5728         if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
5729                 ret = false;
5730         }
5731
5732         return ret;
5733 }
5734
5735 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
5736                             struct policy_handle *domain_handle,
5737                             const char *user_name,
5738                             struct policy_handle *user_handle_out,
5739                             struct dom_sid *domain_sid,
5740                             enum torture_samr_choice which_ops,
5741                             struct cli_credentials *machine_credentials,
5742                             bool test_user)
5743 {
5744
5745         TALLOC_CTX *user_ctx;
5746
5747         struct samr_CreateUser r;
5748         struct samr_QueryUserInfo q;
5749         union samr_UserInfo *info;
5750         struct samr_DeleteUser d;
5751         uint32_t rid;
5752
5753         /* This call creates a 'normal' account - check that it really does */
5754         const uint32_t acct_flags = ACB_NORMAL;
5755         struct lsa_String name;
5756         bool ret = true;
5757         struct dcerpc_binding_handle *b = p->binding_handle;
5758
5759         struct policy_handle user_handle;
5760         user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
5761         init_lsa_String(&name, user_name);
5762
5763         r.in.domain_handle = domain_handle;
5764         r.in.account_name = &name;
5765         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5766         r.out.user_handle = &user_handle;
5767         r.out.rid = &rid;
5768
5769         torture_comment(tctx, "Testing CreateUser(%s)\n", r.in.account_name->string);
5770
5771         torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser_r(b, user_ctx, &r),
5772                 "CreateUser failed");
5773
5774         if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5775                 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
5776                         torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
5777                         return true;
5778                 } else {
5779                         torture_result(tctx, TORTURE_FAIL, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
5780                                nt_errstr(r.out.result));
5781                         return false;
5782                 }
5783         }
5784
5785         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
5786                 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.account_name->string)) {
5787                         talloc_free(user_ctx);
5788                         return false;
5789                 }
5790                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser_r(b, user_ctx, &r),
5791                         "CreateUser failed");
5792         }
5793
5794         if (!NT_STATUS_IS_OK(r.out.result)) {
5795                 talloc_free(user_ctx);
5796                 torture_result(tctx, TORTURE_FAIL, "CreateUser failed - %s\n", nt_errstr(r.out.result));
5797                 return false;
5798         }
5799
5800         if (!test_user) {
5801                 if (user_handle_out) {
5802                         *user_handle_out = user_handle;
5803                 }
5804                 return ret;
5805         }
5806
5807         {
5808                 q.in.user_handle = &user_handle;
5809                 q.in.level = 16;
5810                 q.out.info = &info;
5811
5812                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, user_ctx, &q),
5813                         "QueryUserInfo failed");
5814                 if (!NT_STATUS_IS_OK(q.out.result)) {
5815                         torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level %u failed - %s\n",
5816                                q.in.level, nt_errstr(q.out.result));
5817                         ret = false;
5818                 } else {
5819                         if ((info->info16.acct_flags & acct_flags) != acct_flags) {
5820                                 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5821                                        info->info16.acct_flags,
5822                                        acct_flags);
5823                                 ret = false;
5824                         }
5825                 }
5826
5827                 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
5828                                    domain_sid, acct_flags, name.string, which_ops,
5829                                    machine_credentials)) {
5830                         ret = false;
5831                 }
5832
5833                 if (user_handle_out) {
5834                         *user_handle_out = user_handle;
5835                 } else {
5836                         torture_comment(tctx, "Testing DeleteUser (createuser test)\n");
5837
5838                         d.in.user_handle = &user_handle;
5839                         d.out.user_handle = &user_handle;
5840
5841                         torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, user_ctx, &d),
5842                                 "DeleteUser failed");
5843                         if (!NT_STATUS_IS_OK(d.out.result)) {
5844                                 torture_result(tctx, TORTURE_FAIL, "DeleteUser failed - %s\n", nt_errstr(d.out.result));
5845                                 ret = false;
5846                         }
5847                 }
5848
5849         }
5850
5851         talloc_free(user_ctx);
5852
5853         return ret;
5854 }
5855
5856
5857 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
5858                              struct policy_handle *domain_handle,
5859                              struct dom_sid *domain_sid,
5860                              enum torture_samr_choice which_ops,
5861                              struct cli_credentials *machine_credentials)
5862 {
5863         struct samr_CreateUser2 r;
5864         struct samr_QueryUserInfo q;
5865         union samr_UserInfo *info;
5866         struct samr_DeleteUser d;
5867         struct policy_handle user_handle;
5868         uint32_t rid;
5869         struct lsa_String name;
5870         bool ret = true;
5871         int i;
5872         struct dcerpc_binding_handle *b = p->binding_handle;
5873
5874         struct {
5875                 uint32_t acct_flags;
5876                 const char *account_name;
5877                 NTSTATUS nt_status;
5878         } account_types[] = {
5879                 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
5880                 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5881                 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5882                 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
5883                 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5884                 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5885                 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
5886                 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5887                 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
5888                 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_ACCESS_DENIED },
5889                 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
5890                 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
5891                 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5892                 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
5893                 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
5894         };
5895
5896         for (i = 0; account_types[i].account_name; i++) {
5897                 TALLOC_CTX *user_ctx;
5898                 uint32_t acct_flags = account_types[i].acct_flags;
5899                 uint32_t access_granted;
5900                 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
5901                 init_lsa_String(&name, account_types[i].account_name);
5902
5903                 r.in.domain_handle = domain_handle;
5904                 r.in.account_name = &name;
5905                 r.in.acct_flags = acct_flags;
5906                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5907                 r.out.user_handle = &user_handle;
5908                 r.out.access_granted = &access_granted;
5909                 r.out.rid = &rid;
5910
5911                 torture_comment(tctx, "Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
5912
5913                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser2_r(b, user_ctx, &r),
5914                         "CreateUser2 failed");
5915
5916                 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5917                         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
5918                                 torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.account_name->string);
5919                                 continue;
5920                         } else {
5921                                 torture_result(tctx, TORTURE_FAIL, "Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
5922                                        nt_errstr(r.out.result));
5923                                 ret = false;
5924                                 continue;
5925                         }
5926                 }
5927
5928                 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
5929                         if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.account_name->string)) {
5930                                 talloc_free(user_ctx);
5931                                 ret = false;
5932                                 continue;
5933                         }
5934                         torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateUser2_r(b, user_ctx, &r),
5935                                 "CreateUser2 failed");
5936
5937                 }
5938                 if (!NT_STATUS_EQUAL(r.out.result, account_types[i].nt_status)) {
5939                         torture_result(tctx, TORTURE_FAIL, "CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
5940                                nt_errstr(r.out.result), nt_errstr(account_types[i].nt_status));
5941                         ret = false;
5942                 }
5943
5944                 if (NT_STATUS_IS_OK(r.out.result)) {
5945                         q.in.user_handle = &user_handle;
5946                         q.in.level = 5;
5947                         q.out.info = &info;
5948
5949                         torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, user_ctx, &q),
5950                                 "QueryUserInfo failed");
5951                         if (!NT_STATUS_IS_OK(q.out.result)) {
5952                                 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level %u failed - %s\n",
5953                                        q.in.level, nt_errstr(q.out.result));
5954                                 ret = false;
5955                         } else {
5956                                 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
5957                                 if (acct_flags == ACB_NORMAL) {
5958                                         expected_flags |= ACB_PW_EXPIRED;
5959                                 }
5960                                 if ((info->info5.acct_flags) != expected_flags) {
5961                                         torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
5962                                                info->info5.acct_flags,
5963                                                expected_flags);
5964                                         ret = false;
5965                                 }
5966                                 switch (acct_flags) {
5967                                 case ACB_SVRTRUST:
5968                                         if (info->info5.primary_gid != DOMAIN_RID_DCS) {
5969                                                 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 5: DC should have had Primary Group %d, got %d\n",
5970                                                        DOMAIN_RID_DCS, info->info5.primary_gid);
5971                                                 ret = false;
5972                                         }
5973                                         break;
5974                                 case ACB_WSTRUST:
5975                                         if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
5976                                                 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
5977                                                        DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
5978                                                 ret = false;
5979                                         }
5980                                         break;
5981                                 case ACB_NORMAL:
5982                                         if (info->info5.primary_gid != DOMAIN_RID_USERS) {
5983                                                 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 5: Users should have had Primary Group %d, got %d\n",
5984                                                        DOMAIN_RID_USERS, info->info5.primary_gid);
5985                                                 ret = false;
5986                                         }
5987                                         break;
5988                                 }
5989                         }
5990
5991                         if (!test_user_ops(p, tctx, &user_handle, domain_handle,
5992                                            domain_sid, acct_flags, name.string, which_ops,
5993                                            machine_credentials)) {
5994                                 ret = false;
5995                         }
5996
5997                         if (!ndr_policy_handle_empty(&user_handle)) {
5998                                 torture_comment(tctx, "Testing DeleteUser (createuser2 test)\n");
5999
6000                                 d.in.user_handle = &user_handle;
6001                                 d.out.user_handle = &user_handle;
6002
6003                                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteUser_r(b, user_ctx, &d),
6004                                         "DeleteUser failed");
6005                                 if (!NT_STATUS_IS_OK(d.out.result)) {
6006                                         torture_result(tctx, TORTURE_FAIL, "DeleteUser failed - %s\n", nt_errstr(d.out.result));
6007                                         ret = false;
6008                                 }
6009                         }
6010                 }
6011                 talloc_free(user_ctx);
6012         }
6013
6014         return ret;
6015 }
6016
6017 static bool test_QueryAliasInfo(struct dcerpc_binding_handle *b,
6018                                 struct torture_context *tctx,
6019                                 struct policy_handle *handle)
6020 {
6021         struct samr_QueryAliasInfo r;
6022         union samr_AliasInfo *info;
6023         uint16_t levels[] = {1, 2, 3};
6024         int i;
6025         bool ret = true;
6026
6027         for (i=0;i<ARRAY_SIZE(levels);i++) {
6028                 torture_comment(tctx, "Testing QueryAliasInfo level %u\n", levels[i]);
6029
6030                 r.in.alias_handle = handle;
6031                 r.in.level = levels[i];
6032                 r.out.info = &info;
6033
6034                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryAliasInfo_r(b, tctx, &r),
6035                         "QueryAliasInfo failed");
6036                 if (!NT_STATUS_IS_OK(r.out.result)) {
6037                         torture_result(tctx, TORTURE_FAIL, "QueryAliasInfo level %u failed - %s\n",
6038                                levels[i], nt_errstr(r.out.result));
6039                         ret = false;
6040                 }
6041         }
6042
6043         return ret;
6044 }
6045
6046 static bool test_QueryGroupInfo(struct dcerpc_binding_handle *b,
6047                                 struct torture_context *tctx,
6048                                 struct policy_handle *handle)
6049 {
6050         struct samr_QueryGroupInfo r;
6051         union samr_GroupInfo *info;
6052         uint16_t levels[] = {1, 2, 3, 4, 5};
6053         int i;
6054         bool ret = true;
6055
6056         for (i=0;i<ARRAY_SIZE(levels);i++) {
6057                 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
6058
6059                 r.in.group_handle = handle;
6060                 r.in.level = levels[i];
6061                 r.out.info = &info;
6062
6063                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupInfo_r(b, tctx, &r),
6064                         "QueryGroupInfo failed");
6065                 if (!NT_STATUS_IS_OK(r.out.result)) {
6066                         torture_result(tctx, TORTURE_FAIL, "QueryGroupInfo level %u failed - %s\n",
6067                                levels[i], nt_errstr(r.out.result));
6068                         ret = false;
6069                 }
6070         }
6071
6072         return ret;
6073 }
6074
6075 static bool test_QueryGroupMember(struct dcerpc_binding_handle *b,
6076                                   struct torture_context *tctx,
6077                                   struct policy_handle *handle)
6078 {
6079         struct samr_QueryGroupMember r;
6080         struct samr_RidAttrArray *rids = NULL;
6081         bool ret = true;
6082
6083         torture_comment(tctx, "Testing QueryGroupMember\n");
6084
6085         r.in.group_handle = handle;
6086         r.out.rids = &rids;
6087
6088         torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &r),
6089                 "QueryGroupMember failed");
6090         if (!NT_STATUS_IS_OK(r.out.result)) {
6091                 torture_result(tctx, TORTURE_FAIL, "QueryGroupMember failed - %s\n", nt_errstr(r.out.result));
6092                 ret = false;
6093         }
6094
6095         return ret;
6096 }
6097
6098
6099 static bool test_SetGroupInfo(struct dcerpc_binding_handle *b,
6100                               struct torture_context *tctx,
6101                               struct policy_handle *handle)
6102 {
6103         struct samr_QueryGroupInfo r;
6104         union samr_GroupInfo *info;
6105         struct samr_SetGroupInfo s;
6106         uint16_t levels[] = {1, 2, 3, 4};
6107         uint16_t set_ok[] = {0, 1, 1, 1};
6108         int i;
6109         bool ret = true;
6110
6111         for (i=0;i<ARRAY_SIZE(levels);i++) {
6112                 torture_comment(tctx, "Testing QueryGroupInfo level %u\n", levels[i]);
6113
6114                 r.in.group_handle = handle;
6115                 r.in.level = levels[i];
6116                 r.out.info = &info;
6117
6118                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupInfo_r(b, tctx, &r),
6119                         "QueryGroupInfo failed");
6120                 if (!NT_STATUS_IS_OK(r.out.result)) {
6121                         torture_result(tctx, TORTURE_FAIL, "QueryGroupInfo level %u failed - %s\n",
6122                                levels[i], nt_errstr(r.out.result));
6123                         ret = false;
6124                 }
6125
6126                 torture_comment(tctx, "Testing SetGroupInfo level %u\n", levels[i]);
6127
6128                 s.in.group_handle = handle;
6129                 s.in.level = levels[i];
6130                 s.in.info = *r.out.info;
6131
6132 #if 0
6133                 /* disabled this, as it changes the name only from the point of view of samr,
6134                    but leaves the name from the point of view of w2k3 internals (and ldap). This means
6135                    the name is still reserved, so creating the old name fails, but deleting by the old name
6136                    also fails */
6137                 if (s.in.level == 2) {
6138                         init_lsa_String(&s.in.info->string, "NewName");
6139                 }
6140 #endif
6141
6142                 if (s.in.level == 4) {
6143                         init_lsa_String(&s.in.info->description, "test description");
6144                 }
6145
6146                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetGroupInfo_r(b, tctx, &s),
6147                         "SetGroupInfo failed");
6148                 if (set_ok[i]) {
6149                         if (!NT_STATUS_IS_OK(s.out.result)) {
6150                                 torture_result(tctx, TORTURE_FAIL, "SetGroupInfo level %u failed - %s\n",
6151                                        r.in.level, nt_errstr(s.out.result));
6152                                 ret = false;
6153                                 continue;
6154                         }
6155                 } else {
6156                         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, s.out.result)) {
6157                                 torture_result(tctx, TORTURE_FAIL, "SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
6158                                        r.in.level, nt_errstr(s.out.result));
6159                                 ret = false;
6160                                 continue;
6161                         }
6162                 }
6163         }
6164
6165         return ret;
6166 }
6167
6168 static bool test_QueryUserInfo(struct dcerpc_binding_handle *b,
6169                                struct torture_context *tctx,
6170                                struct policy_handle *handle)
6171 {
6172         struct samr_QueryUserInfo r;
6173         union samr_UserInfo *info;
6174         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
6175                            11, 12, 13, 14, 16, 17, 20, 21};
6176         int i;
6177         bool ret = true;
6178
6179         for (i=0;i<ARRAY_SIZE(levels);i++) {
6180                 torture_comment(tctx, "Testing QueryUserInfo level %u\n", levels[i]);
6181
6182                 r.in.user_handle = handle;
6183                 r.in.level = levels[i];
6184                 r.out.info = &info;
6185
6186                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &r),
6187                         "QueryUserInfo failed");
6188                 if (!NT_STATUS_IS_OK(r.out.result)) {
6189                         torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level %u failed - %s\n",
6190                                levels[i], nt_errstr(r.out.result));
6191                         ret = false;
6192                 }
6193         }
6194
6195         return ret;
6196 }
6197
6198 static bool test_QueryUserInfo2(struct dcerpc_binding_handle *b,
6199                                 struct torture_context *tctx,
6200                                 struct policy_handle *handle)
6201 {
6202         struct samr_QueryUserInfo2 r;
6203         union samr_UserInfo *info;
6204         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
6205                            11, 12, 13, 14, 16, 17, 20, 21};
6206         int i;
6207         bool ret = true;
6208
6209         for (i=0;i<ARRAY_SIZE(levels);i++) {
6210                 torture_comment(tctx, "Testing QueryUserInfo2 level %u\n", levels[i]);
6211
6212                 r.in.user_handle = handle;
6213                 r.in.level = levels[i];
6214                 r.out.info = &info;
6215
6216                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo2_r(b, tctx, &r),
6217                         "QueryUserInfo2 failed");
6218                 if (!NT_STATUS_IS_OK(r.out.result)) {
6219                         torture_result(tctx, TORTURE_FAIL, "QueryUserInfo2 level %u failed - %s\n",
6220                                levels[i], nt_errstr(r.out.result));
6221                         ret = false;
6222                 }
6223         }
6224
6225         return ret;
6226 }
6227
6228 static bool test_OpenUser(struct dcerpc_binding_handle *b,
6229                           struct torture_context *tctx,
6230                           struct policy_handle *handle, uint32_t rid)
6231 {
6232         struct samr_OpenUser r;
6233         struct policy_handle user_handle;
6234         bool ret = true;
6235
6236         torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
6237
6238         r.in.domain_handle = handle;
6239         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6240         r.in.rid = rid;
6241         r.out.user_handle = &user_handle;
6242
6243         torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
6244                 "OpenUser failed");
6245         if (!NT_STATUS_IS_OK(r.out.result)) {
6246                 torture_result(tctx, TORTURE_FAIL, "OpenUser(%u) failed - %s\n", rid, nt_errstr(r.out.result));
6247                 return false;
6248         }
6249
6250         if (!test_QuerySecurity(b, tctx, &user_handle)) {
6251                 ret = false;
6252         }
6253
6254         if (!test_QueryUserInfo(b, tctx, &user_handle)) {
6255                 ret = false;
6256         }
6257
6258         if (!test_QueryUserInfo2(b, tctx, &user_handle)) {
6259                 ret = false;
6260         }
6261
6262         if (!test_GetUserPwInfo(b, tctx, &user_handle)) {
6263                 ret = false;
6264         }
6265
6266         if (!test_GetGroupsForUser(b, tctx, &user_handle)) {
6267                 ret = false;
6268         }
6269
6270         if (!test_samr_handle_Close(b, tctx, &user_handle)) {
6271                 ret = false;
6272         }
6273
6274         return ret;
6275 }
6276
6277 static bool test_OpenGroup(struct dcerpc_binding_handle *b,
6278                            struct torture_context *tctx,
6279                            struct policy_handle *handle, uint32_t rid)
6280 {
6281         struct samr_OpenGroup r;
6282         struct policy_handle group_handle;
6283         bool ret = true;
6284
6285         torture_comment(tctx, "Testing OpenGroup(%u)\n", rid);
6286
6287         r.in.domain_handle = handle;
6288         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6289         r.in.rid = rid;
6290         r.out.group_handle = &group_handle;
6291
6292         torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenGroup_r(b, tctx, &r),
6293                 "OpenGroup failed");
6294         if (!NT_STATUS_IS_OK(r.out.result)) {
6295                 torture_result(tctx, TORTURE_FAIL, "OpenGroup(%u) failed - %s\n", rid, nt_errstr(r.out.result));
6296                 return false;
6297         }
6298
6299         if (!torture_setting_bool(tctx, "samba3", false)) {
6300                 if (!test_QuerySecurity(b, tctx, &group_handle)) {
6301                         ret = false;
6302                 }
6303         }
6304
6305         if (!test_QueryGroupInfo(b, tctx, &group_handle)) {
6306                 ret = false;
6307         }
6308
6309         if (!test_QueryGroupMember(b, tctx, &group_handle)) {
6310                 ret = false;
6311         }
6312
6313         if (!test_samr_handle_Close(b, tctx, &group_handle)) {
6314                 ret = false;
6315         }
6316
6317         return ret;
6318 }
6319
6320 static bool test_OpenAlias(struct dcerpc_binding_handle *b,
6321                            struct torture_context *tctx,
6322                            struct policy_handle *handle, uint32_t rid)
6323 {
6324         struct samr_OpenAlias r;
6325         struct policy_handle alias_handle;
6326         bool ret = true;
6327
6328         torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
6329
6330         r.in.domain_handle = handle;
6331         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6332         r.in.rid = rid;
6333         r.out.alias_handle = &alias_handle;
6334
6335         torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenAlias_r(b, tctx, &r),
6336                 "OpenAlias failed");
6337         if (!NT_STATUS_IS_OK(r.out.result)) {
6338                 torture_result(tctx, TORTURE_FAIL, "OpenAlias(%u) failed - %s\n", rid, nt_errstr(r.out.result));
6339                 return false;
6340         }
6341
6342         if (!torture_setting_bool(tctx, "samba3", false)) {
6343                 if (!test_QuerySecurity(b, tctx, &alias_handle)) {
6344                         ret = false;
6345                 }
6346         }
6347
6348         if (!test_QueryAliasInfo(b, tctx, &alias_handle)) {
6349                 ret = false;
6350         }
6351
6352         if (!test_GetMembersInAlias(b, tctx, &alias_handle)) {
6353                 ret = false;
6354         }
6355
6356         if (!test_samr_handle_Close(b, tctx, &alias_handle)) {
6357                 ret = false;
6358         }
6359
6360         return ret;
6361 }
6362
6363 static bool check_mask(struct dcerpc_binding_handle *b,
6364                        struct torture_context *tctx,
6365                        struct policy_handle *handle, uint32_t rid,
6366                        uint32_t acct_flag_mask)
6367 {
6368         struct samr_OpenUser r;
6369         struct samr_QueryUserInfo q;
6370         union samr_UserInfo *info;
6371         struct policy_handle user_handle;
6372         bool ret = true;
6373
6374         torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
6375
6376         r.in.domain_handle = handle;
6377         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6378         r.in.rid = rid;
6379         r.out.user_handle = &user_handle;
6380
6381         torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
6382                 "OpenUser failed");
6383         if (!NT_STATUS_IS_OK(r.out.result)) {
6384                 torture_result(tctx, TORTURE_FAIL, "OpenUser(%u) failed - %s\n", rid, nt_errstr(r.out.result));
6385                 return false;
6386         }
6387
6388         q.in.user_handle = &user_handle;
6389         q.in.level = 16;
6390         q.out.info = &info;
6391
6392         torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
6393                 "QueryUserInfo failed");
6394         if (!NT_STATUS_IS_OK(q.out.result)) {
6395                 torture_result(tctx, TORTURE_FAIL, "QueryUserInfo level 16 failed - %s\n",
6396                        nt_errstr(q.out.result));
6397                 ret = false;
6398         } else {
6399                 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
6400                         torture_result(tctx, TORTURE_FAIL, "Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
6401                                acct_flag_mask, info->info16.acct_flags, rid);
6402                         ret = false;
6403                 }
6404         }
6405
6406         if (!test_samr_handle_Close(b, tctx, &user_handle)) {
6407                 ret = false;
6408         }
6409
6410         return ret;
6411 }
6412
6413 static bool test_EnumDomainUsers_all(struct dcerpc_binding_handle *b,
6414                                      struct torture_context *tctx,
6415                                      struct policy_handle *handle)
6416 {
6417         struct samr_EnumDomainUsers r;
6418         uint32_t mask, resume_handle=0;
6419         int i, mask_idx;
6420         bool ret = true;
6421         struct samr_LookupNames n;
6422         struct samr_LookupRids  lr ;
6423         struct lsa_Strings names;
6424         struct samr_Ids rids, types;
6425         struct samr_SamArray *sam = NULL;
6426         uint32_t num_entries = 0;
6427
6428         uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
6429                             ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
6430                             ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
6431                             ACB_PWNOEXP, 0};
6432
6433         torture_comment(tctx, "Testing EnumDomainUsers\n");
6434
6435         for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
6436                 r.in.domain_handle = handle;
6437                 r.in.resume_handle = &resume_handle;
6438                 r.in.acct_flags = mask = masks[mask_idx];
6439                 r.in.max_size = (uint32_t)-1;
6440                 r.out.resume_handle = &resume_handle;
6441                 r.out.num_entries = &num_entries;
6442                 r.out.sam = &sam;
6443
6444                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r(b, tctx, &r),
6445                         "EnumDomainUsers failed");
6446                 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) &&
6447                     !NT_STATUS_IS_OK(r.out.result)) {
6448                         torture_result(tctx, TORTURE_FAIL, "EnumDomainUsers failed - %s\n", nt_errstr(r.out.result));
6449                         return false;
6450                 }
6451
6452                 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
6453
6454                 if (sam->count == 0) {
6455                         continue;
6456                 }
6457
6458                 for (i=0;i<sam->count;i++) {
6459                         if (mask) {
6460                                 if (!check_mask(b, tctx, handle, sam->entries[i].idx, mask)) {
6461                                         ret = false;
6462                                 }
6463                         } else if (!test_OpenUser(b, tctx, handle, sam->entries[i].idx)) {
6464                                 ret = false;
6465                         }
6466                 }
6467         }
6468
6469         torture_comment(tctx, "Testing LookupNames\n");
6470         n.in.domain_handle = handle;
6471         n.in.num_names = sam->count;
6472         n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
6473         n.out.rids = &rids;
6474         n.out.types = &types;
6475         for (i=0;i<sam->count;i++) {
6476                 n.in.names[i].string = sam->entries[i].name.string;
6477         }
6478         torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupNames_r(b, tctx, &n),
6479                 "LookupNames failed");
6480         if (!NT_STATUS_IS_OK(n.out.result)) {
6481                 torture_result(tctx, TORTURE_FAIL, "LookupNames failed - %s\n", nt_errstr(n.out.result));
6482                 ret = false;
6483         }
6484
6485
6486         torture_comment(tctx, "Testing LookupRids\n");
6487         lr.in.domain_handle = handle;
6488         lr.in.num_rids = sam->count;
6489         lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
6490         lr.out.names = &names;
6491         lr.out.types = &types;
6492         for (i=0;i<sam->count;i++) {
6493                 lr.in.rids[i] = sam->entries[i].idx;
6494         }
6495         torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupRids_r(b, tctx, &lr),
6496                 "LookupRids failed");
6497         torture_assert_ntstatus_ok(tctx, lr.out.result, "LookupRids");
6498
6499         return ret;
6500 }
6501
6502 /*
6503   try blasting the server with a bunch of sync requests
6504 */
6505 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
6506                                        struct policy_handle *handle)
6507 {
6508         struct samr_EnumDomainUsers r;
6509         uint32_t resume_handle=0;
6510         int i;
6511 #define ASYNC_COUNT 100
6512         struct tevent_req *req[ASYNC_COUNT];
6513
6514         if (!torture_setting_bool(tctx, "dangerous", false)) {
6515                 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
6516         }
6517
6518         torture_comment(tctx, "Testing EnumDomainUsers_async\n");
6519
6520         r.in.domain_handle = handle;
6521         r.in.resume_handle = &resume_handle;
6522         r.in.acct_flags = 0;
6523         r.in.max_size = (uint32_t)-1;
6524         r.out.resume_handle = &resume_handle;
6525
6526         for (i=0;i<ASYNC_COUNT;i++) {
6527                 req[i] = dcerpc_samr_EnumDomainUsers_r_send(tctx, tctx->ev, p->binding_handle, &r);
6528         }
6529
6530         for (i=0;i<ASYNC_COUNT;i++) {
6531                 tevent_req_poll(req[i], tctx->ev);
6532                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r_recv(req[i], tctx),
6533                         talloc_asprintf(tctx, "EnumDomainUsers[%d] failed - %s\n",
6534                                i, nt_errstr(r.out.result)));
6535         }
6536
6537         torture_comment(tctx, "%d async requests OK\n", i);
6538
6539         return true;
6540 }
6541
6542 static bool test_EnumDomainGroups_all(struct dcerpc_binding_handle *b,
6543                                       struct torture_context *tctx,
6544                                       struct policy_handle *handle)
6545 {
6546         struct samr_EnumDomainGroups r;
6547         uint32_t resume_handle=0;
6548         struct samr_SamArray *sam = NULL;
6549         uint32_t num_entries = 0;
6550         int i;
6551         bool ret = true;
6552         bool universal_group_found = false;
6553
6554         torture_comment(tctx, "Testing EnumDomainGroups\n");
6555
6556         r.in.domain_handle = handle;
6557         r.in.resume_handle = &resume_handle;
6558         r.in.max_size = (uint32_t)-1;
6559         r.out.resume_handle = &resume_handle;
6560         r.out.num_entries = &num_entries;
6561         r.out.sam = &sam;
6562
6563         torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &r),
6564                 "EnumDomainGroups failed");
6565         if (!NT_STATUS_IS_OK(r.out.result)) {
6566                 torture_result(tctx, TORTURE_FAIL, "EnumDomainGroups failed - %s\n", nt_errstr(r.out.result));
6567                 return false;
6568         }
6569
6570         if (!sam) {
6571                 return false;
6572         }
6573
6574         for (i=0;i<sam->count;i++) {
6575                 if (!test_OpenGroup(b, tctx, handle, sam->entries[i].idx)) {
6576                         ret = false;
6577                 }
6578                 if ((ret == true) && (strcasecmp(sam->entries[i].name.string,
6579                                                  "Enterprise Admins") == 0)) {
6580                         universal_group_found = true;
6581                 }
6582         }
6583
6584         /* when we are running this on s4 we should get back at least the
6585          * "Enterprise Admins" universal group. If we don't get a group entry
6586          * at all we probably are performing the test on the builtin domain.
6587          * So ignore this case. */
6588         if (torture_setting_bool(tctx, "samba4", false)) {
6589                 if ((sam->count > 0) && (!universal_group_found)) {
6590                         ret = false;
6591                 }
6592         }
6593
6594         return ret;
6595 }
6596
6597 static bool test_EnumDomainAliases_all(struct dcerpc_binding_handle *b,
6598                                        struct torture_context *tctx,
6599                                        struct policy_handle *handle)
6600 {
6601         struct samr_EnumDomainAliases r;
6602         uint32_t resume_handle=0;
6603         struct samr_SamArray *sam = NULL;
6604         uint32_t num_entries = 0;
6605         int i;
6606         bool ret = true;
6607
6608         torture_comment(tctx, "Testing EnumDomainAliases\n");
6609
6610         r.in.domain_handle = handle;
6611         r.in.resume_handle = &resume_handle;
6612         r.in.max_size = (uint32_t)-1;
6613         r.out.sam = &sam;
6614         r.out.num_entries = &num_entries;
6615         r.out.resume_handle = &resume_handle;
6616
6617         torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainAliases_r(b, tctx, &r),
6618                 "EnumDomainAliases failed");
6619         if (!NT_STATUS_IS_OK(r.out.result)) {
6620                 torture_result(tctx, TORTURE_FAIL, "EnumDomainAliases failed - %s\n", nt_errstr(r.out.result));
6621                 return false;
6622         }
6623
6624         if (!sam) {
6625                 return false;
6626         }
6627
6628         for (i=0;i<sam->count;i++) {
6629                 if (!test_OpenAlias(b, tctx, handle, sam->entries[i].idx)) {
6630                         ret = false;
6631                 }
6632         }
6633
6634         return ret;
6635 }
6636
6637 static bool test_GetDisplayEnumerationIndex(struct dcerpc_binding_handle *b,
6638                                             struct torture_context *tctx,
6639                                             struct policy_handle *handle)
6640 {
6641         struct samr_GetDisplayEnumerationIndex r;
6642         bool ret = true;
6643         uint16_t levels[] = {1, 2, 3, 4, 5};
6644         uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
6645         struct lsa_String name;
6646         uint32_t idx = 0;
6647         int i;
6648
6649         for (i=0;i<ARRAY_SIZE(levels);i++) {
6650                 torture_comment(tctx, "Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
6651
6652                 init_lsa_String(&name, TEST_ACCOUNT_NAME);
6653
6654                 r.in.domain_handle = handle;
6655                 r.in.level = levels[i];
6656                 r.in.name = &name;
6657                 r.out.idx = &idx;
6658
6659                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex_r(b, tctx, &r),
6660                         "GetDisplayEnumerationIndex failed");
6661
6662                 if (ok_lvl[i] &&
6663                     !NT_STATUS_IS_OK(r.out.result) &&
6664                     !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6665                         torture_result(tctx, TORTURE_FAIL, "GetDisplayEnumerationIndex level %u failed - %s\n",
6666                                levels[i], nt_errstr(r.out.result));
6667                         ret = false;
6668                 }
6669
6670                 init_lsa_String(&name, "zzzzzzzz");
6671
6672                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex_r(b, tctx, &r),
6673                         "GetDisplayEnumerationIndex failed");
6674
6675                 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6676                         torture_result(tctx, TORTURE_FAIL, "GetDisplayEnumerationIndex level %u failed - %s\n",
6677                                levels[i], nt_errstr(r.out.result));
6678                         ret = false;
6679                 }
6680         }
6681
6682         return ret;
6683 }
6684
6685 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_binding_handle *b,
6686                                              struct torture_context *tctx,
6687                                              struct policy_handle *handle)
6688 {
6689         struct samr_GetDisplayEnumerationIndex2 r;
6690         bool ret = true;
6691         uint16_t levels[] = {1, 2, 3, 4, 5};
6692         uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
6693         struct lsa_String name;
6694         uint32_t idx = 0;
6695         int i;
6696
6697         for (i=0;i<ARRAY_SIZE(levels);i++) {
6698                 torture_comment(tctx, "Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
6699
6700                 init_lsa_String(&name, TEST_ACCOUNT_NAME);
6701
6702                 r.in.domain_handle = handle;
6703                 r.in.level = levels[i];
6704                 r.in.name = &name;
6705                 r.out.idx = &idx;
6706
6707                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex2_r(b, tctx, &r),
6708                         "GetDisplayEnumerationIndex2 failed");
6709                 if (ok_lvl[i] &&
6710                     !NT_STATUS_IS_OK(r.out.result) &&
6711                     !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6712                         torture_result(tctx, TORTURE_FAIL, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6713                                levels[i], nt_errstr(r.out.result));
6714                         ret = false;
6715                 }
6716
6717                 init_lsa_String(&name, "zzzzzzzz");
6718
6719                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_GetDisplayEnumerationIndex2_r(b, tctx, &r),
6720                         "GetDisplayEnumerationIndex2 failed");
6721                 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, r.out.result)) {
6722                         torture_result(tctx, TORTURE_FAIL, "GetDisplayEnumerationIndex2 level %u failed - %s\n",
6723                                levels[i], nt_errstr(r.out.result));
6724                         ret = false;
6725                 }
6726         }
6727
6728         return ret;
6729 }
6730
6731 #define STRING_EQUAL_QUERY(s1, s2, user)                                        \
6732         if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
6733                 /* odd, but valid */                                            \
6734         } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
6735                         torture_result(tctx, TORTURE_FAIL, "%s mismatch for %s: %s != %s (%s)\n", \
6736                                #s1, user.string,  s1.string, s2.string, __location__);   \
6737                         ret = false; \
6738         }
6739 #define INT_EQUAL_QUERY(s1, s2, user)           \
6740                 if (s1 != s2) { \
6741                         torture_result(tctx, TORTURE_FAIL, "%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
6742                                #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
6743                         ret = false; \
6744                 }
6745
6746 static bool test_each_DisplayInfo_user(struct dcerpc_binding_handle *b,
6747                                        struct torture_context *tctx,
6748                                        struct samr_QueryDisplayInfo *querydisplayinfo,
6749                                        bool *seen_testuser)
6750 {
6751         struct samr_OpenUser r;
6752         struct samr_QueryUserInfo q;
6753         union samr_UserInfo *info;
6754         struct policy_handle user_handle;
6755         int i, ret = true;
6756         r.in.domain_handle = querydisplayinfo->in.domain_handle;
6757         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6758         for (i = 0; ; i++) {
6759                 switch (querydisplayinfo->in.level) {
6760                 case 1:
6761                         if (i >= querydisplayinfo->out.info->info1.count) {
6762                                 return ret;
6763                         }
6764                         r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
6765                         break;
6766                 case 2:
6767                         if (i >= querydisplayinfo->out.info->info2.count) {
6768                                 return ret;
6769                         }
6770                         r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
6771                         break;
6772                 case 3:
6773                         /* Groups */
6774                 case 4:
6775                 case 5:
6776                         /* Not interested in validating just the account name */
6777                         return true;
6778                 }
6779
6780                 r.out.user_handle = &user_handle;
6781
6782                 switch (querydisplayinfo->in.level) {
6783                 case 1:
6784                 case 2:
6785                         torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenUser_r(b, tctx, &r),
6786                                 "OpenUser failed");
6787                         if (!NT_STATUS_IS_OK(r.out.result)) {
6788                                 torture_result(tctx, TORTURE_FAIL, "OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(r.out.result));
6789                                 return false;
6790                         }
6791                 }
6792
6793                 q.in.user_handle = &user_handle;
6794                 q.in.level = 21;
6795                 q.out.info = &info;
6796                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryUserInfo_r(b, tctx, &q),
6797                         "QueryUserInfo failed");
6798                 if (!NT_STATUS_IS_OK(r.out.result)) {
6799                         torture_result(tctx, TORTURE_FAIL, "QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(r.out.result));
6800                         return false;
6801                 }
6802
6803                 switch (querydisplayinfo->in.level) {
6804                 case 1:
6805                         if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
6806                                 *seen_testuser = true;
6807                         }
6808                         STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
6809                                            info->info21.full_name, info->info21.account_name);
6810                         STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
6811                                            info->info21.account_name, info->info21.account_name);
6812                         STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
6813                                            info->info21.description, info->info21.account_name);
6814                         INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
6815                                         info->info21.rid, info->info21.account_name);
6816                         INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
6817                                         info->info21.acct_flags, info->info21.account_name);
6818
6819                         break;
6820                 case 2:
6821                         STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
6822                                            info->info21.account_name, info->info21.account_name);
6823                         STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
6824                                            info->info21.description, info->info21.account_name);
6825                         INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
6826                                         info->info21.rid, info->info21.account_name);
6827                         INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
6828                                         info->info21.acct_flags, info->info21.account_name);
6829
6830                         if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
6831                                 torture_result(tctx, TORTURE_FAIL, "Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
6832                                        info->info21.account_name.string);
6833                         }
6834
6835                         if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
6836                                 torture_result(tctx, TORTURE_FAIL, "Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
6837                                        info->info21.account_name.string,
6838                                        querydisplayinfo->out.info->info2.entries[i].acct_flags,
6839                                        info->info21.acct_flags);
6840                                 return false;
6841                         }
6842
6843                         break;
6844                 }
6845
6846                 if (!test_samr_handle_Close(b, tctx, &user_handle)) {
6847                         return false;
6848                 }
6849         }
6850         return ret;
6851 }
6852
6853 static bool test_QueryDisplayInfo(struct dcerpc_binding_handle *b,
6854                                   struct torture_context *tctx,
6855                                   struct policy_handle *handle)
6856 {
6857         struct samr_QueryDisplayInfo r;
6858         struct samr_QueryDomainInfo dom_info;
6859         union samr_DomainInfo *info = NULL;
6860         bool ret = true;
6861         uint16_t levels[] = {1, 2, 3, 4, 5};
6862         int i;
6863         bool seen_testuser = false;
6864         uint32_t total_size;
6865         uint32_t returned_size;
6866         union samr_DispInfo disp_info;
6867
6868
6869         for (i=0;i<ARRAY_SIZE(levels);i++) {
6870                 torture_comment(tctx, "Testing QueryDisplayInfo level %u\n", levels[i]);
6871
6872                 r.in.start_idx = 0;
6873                 r.out.result = STATUS_MORE_ENTRIES;
6874                 while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES)) {
6875                         r.in.domain_handle = handle;
6876                         r.in.level = levels[i];
6877                         r.in.max_entries = 2;
6878                         r.in.buf_size = (uint32_t)-1;
6879                         r.out.total_size = &total_size;
6880                         r.out.returned_size = &returned_size;
6881                         r.out.info = &disp_info;
6882
6883                         torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
6884                                 "QueryDisplayInfo failed");
6885                         if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(r.out.result)) {
6886                                 torture_result(tctx, TORTURE_FAIL, "QueryDisplayInfo level %u failed - %s\n",
6887                                        levels[i], nt_errstr(r.out.result));
6888                                 ret = false;
6889                         }
6890                         switch (r.in.level) {
6891                         case 1:
6892                                 if (!test_each_DisplayInfo_user(b, tctx, &r, &seen_testuser)) {
6893                                         ret = false;
6894                                 }
6895                                 r.in.start_idx += r.out.info->info1.count;
6896                                 break;
6897                         case 2:
6898                                 if (!test_each_DisplayInfo_user(b, tctx, &r, NULL)) {
6899                                         ret = false;
6900                                 }
6901                                 r.in.start_idx += r.out.info->info2.count;
6902                                 break;
6903                         case 3:
6904                                 r.in.start_idx += r.out.info->info3.count;
6905                                 break;
6906                         case 4:
6907                                 r.in.start_idx += r.out.info->info4.count;
6908                                 break;
6909                         case 5:
6910                                 r.in.start_idx += r.out.info->info5.count;
6911                                 break;
6912                         }
6913                 }
6914                 dom_info.in.domain_handle = handle;
6915                 dom_info.in.level = 2;
6916                 dom_info.out.info = &info;
6917
6918                 /* Check number of users returned is correct */
6919                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &dom_info),
6920                         "QueryDomainInfo failed");
6921                 if (!NT_STATUS_IS_OK(dom_info.out.result)) {
6922                         torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u failed - %s\n",
6923                                r.in.level, nt_errstr(dom_info.out.result));
6924                         ret = false;
6925                         break;
6926                 }
6927                 switch (r.in.level) {
6928                 case 1:
6929                 case 4:
6930                         if (info->general.num_users < r.in.start_idx) {
6931                                 /* On AD deployments this numbers don't match
6932                                  * since QueryDisplayInfo returns universal and
6933                                  * global groups, QueryDomainInfo only global
6934                                  * ones. */
6935                                 if (torture_setting_bool(tctx, "samba3", false)) {
6936                                         torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
6937                                                r.in.start_idx, info->general.num_groups,
6938                                                info->general.domain_name.string);
6939                                         ret = false;
6940                                 }
6941                         }
6942                         if (!seen_testuser) {
6943                                 struct policy_handle user_handle;
6944                                 if (NT_STATUS_IS_OK(test_OpenUser_byname(b, tctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
6945                                         torture_result(tctx, TORTURE_FAIL, "Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
6946                                                info->general.domain_name.string);
6947                                         ret = false;
6948                                         test_samr_handle_Close(b, tctx, &user_handle);
6949                                 }
6950                         }
6951                         break;
6952                 case 3:
6953                 case 5:
6954                         if (info->general.num_groups != r.in.start_idx) {
6955                                 /* On AD deployments this numbers don't match
6956                                  * since QueryDisplayInfo returns universal and
6957                                  * global groups, QueryDomainInfo only global
6958                                  * ones. */
6959                                 if (torture_setting_bool(tctx, "samba3", false)) {
6960                                         torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
6961                                                r.in.start_idx, info->general.num_groups,
6962                                                info->general.domain_name.string);
6963                                         ret = false;
6964                                 }
6965                         }
6966
6967                         break;
6968                 }
6969
6970         }
6971
6972         return ret;
6973 }
6974
6975 static bool test_QueryDisplayInfo2(struct dcerpc_binding_handle *b,
6976                                    struct torture_context *tctx,
6977                                    struct policy_handle *handle)
6978 {
6979         struct samr_QueryDisplayInfo2 r;
6980         bool ret = true;
6981         uint16_t levels[] = {1, 2, 3, 4, 5};
6982         int i;
6983         uint32_t total_size;
6984         uint32_t returned_size;
6985         union samr_DispInfo info;
6986
6987         for (i=0;i<ARRAY_SIZE(levels);i++) {
6988                 torture_comment(tctx, "Testing QueryDisplayInfo2 level %u\n", levels[i]);
6989
6990                 r.in.domain_handle = handle;
6991                 r.in.level = levels[i];
6992                 r.in.start_idx = 0;
6993                 r.in.max_entries = 1000;
6994                 r.in.buf_size = (uint32_t)-1;
6995                 r.out.total_size = &total_size;
6996                 r.out.returned_size = &returned_size;
6997                 r.out.info = &info;
6998
6999                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo2_r(b, tctx, &r),
7000                         "QueryDisplayInfo2 failed");
7001                 if (!NT_STATUS_IS_OK(r.out.result)) {
7002                         torture_result(tctx, TORTURE_FAIL, "QueryDisplayInfo2 level %u failed - %s\n",
7003                                levels[i], nt_errstr(r.out.result));
7004                         ret = false;
7005                 }
7006         }
7007
7008         return ret;
7009 }
7010
7011 static bool test_QueryDisplayInfo3(struct dcerpc_binding_handle *b,
7012                                    struct torture_context *tctx,
7013                                    struct policy_handle *handle)
7014 {
7015         struct samr_QueryDisplayInfo3 r;
7016         bool ret = true;
7017         uint16_t levels[] = {1, 2, 3, 4, 5};
7018         int i;
7019         uint32_t total_size;
7020         uint32_t returned_size;
7021         union samr_DispInfo info;
7022
7023         for (i=0;i<ARRAY_SIZE(levels);i++) {
7024                 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
7025
7026                 r.in.domain_handle = handle;
7027                 r.in.level = levels[i];
7028                 r.in.start_idx = 0;
7029                 r.in.max_entries = 1000;
7030                 r.in.buf_size = (uint32_t)-1;
7031                 r.out.total_size = &total_size;
7032                 r.out.returned_size = &returned_size;
7033                 r.out.info = &info;
7034
7035                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo3_r(b, tctx, &r),
7036                         "QueryDisplayInfo3 failed");
7037                 if (!NT_STATUS_IS_OK(r.out.result)) {
7038                         torture_result(tctx, TORTURE_FAIL, "QueryDisplayInfo3 level %u failed - %s\n",
7039                                levels[i], nt_errstr(r.out.result));
7040                         ret = false;
7041                 }
7042         }
7043
7044         return ret;
7045 }
7046
7047
7048 static bool test_QueryDisplayInfo_continue(struct dcerpc_binding_handle *b,
7049                                            struct torture_context *tctx,
7050                                            struct policy_handle *handle)
7051 {
7052         struct samr_QueryDisplayInfo r;
7053         bool ret = true;
7054         uint32_t total_size;
7055         uint32_t returned_size;
7056         union samr_DispInfo info;
7057
7058         torture_comment(tctx, "Testing QueryDisplayInfo continuation\n");
7059
7060         r.in.domain_handle = handle;
7061         r.in.level = 1;
7062         r.in.start_idx = 0;
7063         r.in.max_entries = 1;
7064         r.in.buf_size = (uint32_t)-1;
7065         r.out.total_size = &total_size;
7066         r.out.returned_size = &returned_size;
7067         r.out.info = &info;
7068
7069         do {
7070                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
7071                         "QueryDisplayInfo failed");
7072                 if (NT_STATUS_IS_OK(r.out.result) && *r.out.returned_size != 0) {
7073                         if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
7074                                 torture_result(tctx, TORTURE_FAIL, "expected idx %d but got %d\n",
7075                                        r.in.start_idx + 1,
7076                                        r.out.info->info1.entries[0].idx);
7077                                 break;
7078                         }
7079                 }
7080                 if (!NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) &&
7081                     !NT_STATUS_IS_OK(r.out.result)) {
7082                         torture_result(tctx, TORTURE_FAIL, "QueryDisplayInfo level %u failed - %s\n",
7083                                r.in.level, nt_errstr(r.out.result));
7084                         ret = false;
7085                         break;
7086                 }
7087                 r.in.start_idx++;
7088         } while ((NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) ||
7089                   NT_STATUS_IS_OK(r.out.result)) &&
7090                  *r.out.returned_size != 0);
7091
7092         return ret;
7093 }
7094
7095 static bool test_QueryDomainInfo(struct dcerpc_pipe *p,
7096                                  struct torture_context *tctx,
7097                                  struct policy_handle *handle)
7098 {
7099         struct samr_QueryDomainInfo r;
7100         union samr_DomainInfo *info = NULL;
7101         struct samr_SetDomainInfo s;
7102         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
7103         uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1,  0,  1,  0};
7104         int i;
7105         bool ret = true;
7106         struct dcerpc_binding_handle *b = p->binding_handle;
7107         const char *domain_comment = talloc_asprintf(tctx,
7108                                   "Tortured by Samba4 RPC-SAMR: %s",
7109                                   timestring(tctx, time(NULL)));
7110
7111         s.in.domain_handle = handle;
7112         s.in.level = 4;
7113         s.in.info = talloc(tctx, union samr_DomainInfo);
7114
7115         s.in.info->oem.oem_information.string = domain_comment;
7116         torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
7117                 "SetDomainInfo failed");
7118         if (!NT_STATUS_IS_OK(s.out.result)) {
7119                 torture_result(tctx, TORTURE_FAIL, "SetDomainInfo level %u (set comment) failed - %s\n",
7120                        s.in.level, nt_errstr(s.out.result));
7121                 return false;
7122         }
7123
7124         for (i=0;i<ARRAY_SIZE(levels);i++) {
7125                 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
7126
7127                 r.in.domain_handle = handle;
7128                 r.in.level = levels[i];
7129                 r.out.info = &info;
7130
7131                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
7132                         "QueryDomainInfo failed");
7133                 if (!NT_STATUS_IS_OK(r.out.result)) {
7134                         torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u failed - %s\n",
7135                                r.in.level, nt_errstr(r.out.result));
7136                         ret = false;
7137                         continue;
7138                 }
7139
7140                 switch (levels[i]) {
7141                 case 2:
7142                         if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
7143                                 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
7144                                        levels[i], info->general.oem_information.string, domain_comment);
7145                                 if (!torture_setting_bool(tctx, "samba3", false)) {
7146                                         ret = false;
7147                                 }
7148                         }
7149                         if (!info->general.primary.string) {
7150                                 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u returned no PDC name\n",
7151                                        levels[i]);
7152                                 ret = false;
7153                         } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
7154                                 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
7155                                         if (torture_setting_bool(tctx, "samba3", false)) {
7156                                                 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
7157                                                        levels[i], info->general.primary.string, dcerpc_server_name(p));
7158                                         }
7159                                 }
7160                         }
7161                         break;
7162                 case 4:
7163                         if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
7164                                 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
7165                                        levels[i], info->oem.oem_information.string, domain_comment);
7166                                 if (!torture_setting_bool(tctx, "samba3", false)) {
7167                                         ret = false;
7168                                 }
7169                         }
7170                         break;
7171                 case 6:
7172                         if (!info->info6.primary.string) {
7173                                 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u returned no PDC name\n",
7174                                        levels[i]);
7175                                 ret = false;
7176                         }
7177                         break;
7178                 case 11:
7179                         if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
7180                                 torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
7181                                        levels[i], info->general2.general.oem_information.string, domain_comment);
7182                                 if (!torture_setting_bool(tctx, "samba3", false)) {
7183                                         ret = false;
7184                                 }
7185                         }
7186                         break;
7187                 }
7188
7189                 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
7190
7191                 s.in.domain_handle = handle;
7192                 s.in.level = levels[i];
7193                 s.in.info = info;
7194
7195                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetDomainInfo_r(b, tctx, &s),
7196                         "SetDomainInfo failed");
7197                 if (set_ok[i]) {
7198                         if (!NT_STATUS_IS_OK(s.out.result)) {
7199                                 torture_result(tctx, TORTURE_FAIL, "SetDomainInfo level %u failed - %s\n",
7200                                        r.in.level, nt_errstr(s.out.result));
7201                                 ret = false;
7202                                 continue;
7203                         }
7204                 } else {
7205                         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, s.out.result)) {
7206                                 torture_result(tctx, TORTURE_FAIL, "SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
7207                                        r.in.level, nt_errstr(s.out.result));
7208                                 ret = false;
7209                                 continue;
7210                         }
7211                 }
7212
7213                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo_r(b, tctx, &r),
7214                         "QueryDomainInfo failed");
7215                 if (!NT_STATUS_IS_OK(r.out.result)) {
7216                         torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo level %u failed - %s\n",
7217                                r.in.level, nt_errstr(r.out.result));
7218                         ret = false;
7219                         continue;
7220                 }
7221         }
7222
7223         return ret;
7224 }
7225
7226
7227 static bool test_QueryDomainInfo2(struct dcerpc_binding_handle *b,
7228                                   struct torture_context *tctx,
7229                                   struct policy_handle *handle)
7230 {
7231         struct samr_QueryDomainInfo2 r;
7232         union samr_DomainInfo *info = NULL;
7233         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
7234         int i;
7235         bool ret = true;
7236
7237         for (i=0;i<ARRAY_SIZE(levels);i++) {
7238                 torture_comment(tctx, "Testing QueryDomainInfo2 level %u\n", levels[i]);
7239
7240                 r.in.domain_handle = handle;
7241                 r.in.level = levels[i];
7242                 r.out.info = &info;
7243
7244                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
7245                         "QueryDomainInfo2 failed");
7246                 if (!NT_STATUS_IS_OK(r.out.result)) {
7247                         torture_result(tctx, TORTURE_FAIL, "QueryDomainInfo2 level %u failed - %s\n",
7248                                r.in.level, nt_errstr(r.out.result));
7249                         ret = false;
7250                         continue;
7251                 }
7252         }
7253
7254         return ret;
7255 }
7256
7257 /* Test whether querydispinfo level 5 and enumdomgroups return the same
7258    set of group names. */
7259 static bool test_GroupList(struct dcerpc_binding_handle *b,
7260                            struct torture_context *tctx,
7261                            struct dom_sid *domain_sid,
7262                            struct policy_handle *handle)
7263 {
7264         struct samr_EnumDomainGroups q1;
7265         struct samr_QueryDisplayInfo q2;
7266         NTSTATUS status;
7267         uint32_t resume_handle=0;
7268         struct samr_SamArray *sam = NULL;
7269         uint32_t num_entries = 0;
7270         int i;
7271         bool ret = true;
7272         uint32_t total_size;
7273         uint32_t returned_size;
7274         union samr_DispInfo info;
7275
7276         int num_names = 0;
7277         const char **names = NULL;
7278
7279         bool builtin_domain = dom_sid_compare(domain_sid,
7280                                               &global_sid_Builtin) == 0;
7281
7282         torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
7283
7284         q1.in.domain_handle = handle;
7285         q1.in.resume_handle = &resume_handle;
7286         q1.in.max_size = 5;
7287         q1.out.resume_handle = &resume_handle;
7288         q1.out.num_entries = &num_entries;
7289         q1.out.sam = &sam;
7290
7291         status = STATUS_MORE_ENTRIES;
7292         while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
7293                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &q1),
7294                         "EnumDomainGroups failed");
7295                 status = q1.out.result;
7296
7297                 if (!NT_STATUS_IS_OK(status) &&
7298                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
7299                         break;
7300
7301                 for (i=0; i<*q1.out.num_entries; i++) {
7302                         add_string_to_array(tctx,
7303                                             sam->entries[i].name.string,
7304                                             &names, &num_names);
7305                 }
7306         }
7307
7308         torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
7309
7310         torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
7311
7312         if (builtin_domain) {
7313                 torture_assert(tctx, num_names == 0,
7314                                "EnumDomainGroups shouldn't return any group in the builtin domain!");
7315         }
7316
7317         q2.in.domain_handle = handle;
7318         q2.in.level = 5;
7319         q2.in.start_idx = 0;
7320         q2.in.max_entries = 5;
7321         q2.in.buf_size = (uint32_t)-1;
7322         q2.out.total_size = &total_size;
7323         q2.out.returned_size = &returned_size;
7324         q2.out.info = &info;
7325
7326         status = STATUS_MORE_ENTRIES;
7327         while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
7328                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &q2),
7329                         "QueryDisplayInfo failed");
7330                 status = q2.out.result;
7331                 if (!NT_STATUS_IS_OK(status) &&
7332                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
7333                         break;
7334
7335                 for (i=0; i<q2.out.info->info5.count; i++) {
7336                         int j;
7337                         const char *name = q2.out.info->info5.entries[i].account_name.string;
7338                         bool found = false;
7339                         for (j=0; j<num_names; j++) {
7340                                 if (names[j] == NULL)
7341                                         continue;
7342                                 if (strequal(names[j], name)) {
7343                                         names[j] = NULL;
7344                                         found = true;
7345                                         break;
7346                                 }
7347                         }
7348
7349                         if ((!found) && (!builtin_domain)) {
7350                                 torture_result(tctx, TORTURE_FAIL, "QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
7351                                        name);
7352                                 ret = false;
7353                         }
7354                 }
7355                 q2.in.start_idx += q2.out.info->info5.count;
7356         }
7357
7358         if (!NT_STATUS_IS_OK(status)) {
7359                 torture_result(tctx, TORTURE_FAIL, "QueryDisplayInfo level 5 failed - %s\n",
7360                        nt_errstr(status));
7361                 ret = false;
7362         }
7363
7364         if (builtin_domain) {
7365                 torture_assert(tctx, q2.in.start_idx != 0,
7366                                "QueryDisplayInfo should return all domain groups also on the builtin domain handle!");
7367         }
7368
7369         for (i=0; i<num_names; i++) {
7370                 if (names[i] != NULL) {
7371                         torture_result(tctx, TORTURE_FAIL, "EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
7372                                names[i]);
7373                         ret = false;
7374                 }
7375         }
7376
7377         return ret;
7378 }
7379
7380 static bool test_DeleteDomainGroup(struct dcerpc_binding_handle *b,
7381                                    struct torture_context *tctx,
7382                                    struct policy_handle *group_handle)
7383 {
7384         struct samr_DeleteDomainGroup d;
7385
7386         torture_comment(tctx, "Testing DeleteDomainGroup\n");
7387
7388         d.in.group_handle = group_handle;
7389         d.out.group_handle = group_handle;
7390
7391         torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteDomainGroup_r(b, tctx, &d),
7392                 "DeleteDomainGroup failed");
7393         torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteDomainGroup");
7394
7395         return true;
7396 }
7397
7398 static bool test_TestPrivateFunctionsDomain(struct dcerpc_binding_handle *b,
7399                                             struct torture_context *tctx,
7400                                             struct policy_handle *domain_handle)
7401 {
7402         struct samr_TestPrivateFunctionsDomain r;
7403         bool ret = true;
7404
7405         torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
7406
7407         r.in.domain_handle = domain_handle;
7408
7409         torture_assert_ntstatus_ok(tctx, dcerpc_samr_TestPrivateFunctionsDomain_r(b, tctx, &r),
7410                 "TestPrivateFunctionsDomain failed");
7411         torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsDomain");
7412
7413         return ret;
7414 }
7415
7416 static bool test_RidToSid(struct dcerpc_binding_handle *b,
7417                           struct torture_context *tctx,
7418                           struct dom_sid *domain_sid,
7419                           struct policy_handle *domain_handle)
7420 {
7421         struct samr_RidToSid r;
7422         bool ret = true;
7423         struct dom_sid *calc_sid, *out_sid;
7424         int rids[] = { 0, 42, 512, 10200 };
7425         int i;
7426
7427         for (i=0;i<ARRAY_SIZE(rids);i++) {
7428                 torture_comment(tctx, "Testing RidToSid\n");
7429
7430                 calc_sid = dom_sid_dup(tctx, domain_sid);
7431                 r.in.domain_handle = domain_handle;
7432                 r.in.rid = rids[i];
7433                 r.out.sid = &out_sid;
7434
7435                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_RidToSid_r(b, tctx, &r),
7436                         "RidToSid failed");
7437                 if (!NT_STATUS_IS_OK(r.out.result)) {
7438                         torture_result(tctx, TORTURE_FAIL, "RidToSid for %d failed - %s\n", rids[i], nt_errstr(r.out.result));
7439                         ret = false;
7440                 } else {
7441                         calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
7442
7443                         if (!dom_sid_equal(calc_sid, out_sid)) {
7444                                 torture_result(tctx, TORTURE_FAIL, "RidToSid for %d failed - got %s, expected %s\n", rids[i],
7445                                        dom_sid_string(tctx, out_sid),
7446                                        dom_sid_string(tctx, calc_sid));
7447                                 ret = false;
7448                         }
7449                 }
7450         }
7451
7452         return ret;
7453 }
7454
7455 static bool test_GetBootKeyInformation(struct dcerpc_binding_handle *b,
7456                                        struct torture_context *tctx,
7457                                        struct policy_handle *domain_handle)
7458 {
7459         struct samr_GetBootKeyInformation r;
7460         bool ret = true;
7461         uint32_t unknown = 0;
7462         NTSTATUS status;
7463
7464         torture_comment(tctx, "Testing GetBootKeyInformation\n");
7465
7466         r.in.domain_handle = domain_handle;
7467         r.out.unknown = &unknown;
7468
7469         status = dcerpc_samr_GetBootKeyInformation_r(b, tctx, &r);
7470         if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(r.out.result)) {
7471                 status = r.out.result;
7472         }
7473         if (!NT_STATUS_IS_OK(status)) {
7474                 /* w2k3 seems to fail this sometimes and pass it sometimes */
7475                 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
7476         }
7477
7478         return ret;
7479 }
7480
7481 static bool test_AddGroupMember(struct dcerpc_binding_handle *b,
7482                                 struct torture_context *tctx,
7483                                 struct policy_handle *domain_handle,
7484                                 struct policy_handle *group_handle)
7485 {
7486         NTSTATUS status;
7487         struct samr_AddGroupMember r;
7488         struct samr_DeleteGroupMember d;
7489         struct samr_QueryGroupMember q;
7490         struct samr_RidAttrArray *rids = NULL;
7491         struct samr_SetMemberAttributesOfGroup s;
7492         uint32_t rid;
7493         bool found_member = false;
7494         int i;
7495
7496         status = test_LookupName(b, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
7497         torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
7498
7499         r.in.group_handle = group_handle;
7500         r.in.rid = rid;
7501         r.in.flags = 0; /* ??? */
7502
7503         torture_comment(tctx, "Testing AddGroupMember, QueryGroupMember and DeleteGroupMember\n");
7504
7505         d.in.group_handle = group_handle;
7506         d.in.rid = rid;
7507
7508         torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteGroupMember_r(b, tctx, &d),
7509                 "DeleteGroupMember failed");
7510         torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, d.out.result, "DeleteGroupMember");
7511
7512         torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7513                 "AddGroupMember failed");
7514         torture_assert_ntstatus_ok(tctx, r.out.result, "AddGroupMember");
7515
7516         torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7517                 "AddGroupMember failed");
7518         torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, r.out.result, "AddGroupMember");
7519
7520         if (torture_setting_bool(tctx, "samba4", false) ||
7521             torture_setting_bool(tctx, "samba3", false)) {
7522                 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba\n");
7523         } else {
7524                 /* this one is quite strange. I am using random inputs in the
7525                    hope of triggering an error that might give us a clue */
7526
7527                 s.in.group_handle = group_handle;
7528                 s.in.unknown1 = random();
7529                 s.in.unknown2 = random();
7530
7531                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_SetMemberAttributesOfGroup_r(b, tctx, &s),
7532                         "SetMemberAttributesOfGroup failed");
7533                 torture_assert_ntstatus_ok(tctx, s.out.result, "SetMemberAttributesOfGroup");
7534         }
7535
7536         q.in.group_handle = group_handle;
7537         q.out.rids = &rids;
7538
7539         torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &q),
7540                 "QueryGroupMember failed");
7541         torture_assert_ntstatus_ok(tctx, q.out.result, "QueryGroupMember");
7542         torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
7543
7544         for (i=0; i < rids->count; i++) {
7545                 if (rids->rids[i] == rid) {
7546                         found_member = true;
7547                 }
7548         }
7549
7550         torture_assert(tctx, found_member, "QueryGroupMember did not list newly added member");
7551
7552         torture_assert_ntstatus_ok(tctx, dcerpc_samr_DeleteGroupMember_r(b, tctx, &d),
7553                 "DeleteGroupMember failed");
7554         torture_assert_ntstatus_ok(tctx, d.out.result, "DeleteGroupMember");
7555
7556         rids = NULL;
7557         found_member = false;
7558
7559         torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryGroupMember_r(b, tctx, &q),
7560                 "QueryGroupMember failed");
7561         torture_assert_ntstatus_ok(tctx, q.out.result, "QueryGroupMember");
7562         torture_assert(tctx, rids, "QueryGroupMember did not fill in rids structure");
7563
7564         for (i=0; i < rids->count; i++) {
7565                 if (rids->rids[i] == rid) {
7566                         found_member = true;
7567                 }
7568         }
7569
7570         torture_assert(tctx, !found_member, "QueryGroupMember does still list removed member");
7571
7572         torture_assert_ntstatus_ok(tctx, dcerpc_samr_AddGroupMember_r(b, tctx, &r),
7573                 "AddGroupMember failed");
7574         torture_assert_ntstatus_ok(tctx, r.out.result, "AddGroupMember");
7575
7576         return true;
7577 }
7578
7579
7580 static bool test_CreateDomainGroup(struct dcerpc_binding_handle *b,
7581                                    struct torture_context *tctx,
7582                                    struct policy_handle *domain_handle,
7583                                    const char *group_name,
7584                                    struct policy_handle *group_handle,
7585                                    struct dom_sid *domain_sid,
7586                                    bool test_group)
7587 {
7588         struct samr_CreateDomainGroup r;
7589         uint32_t rid;
7590         struct lsa_String name;
7591         bool ret = true;
7592
7593         init_lsa_String(&name, group_name);
7594
7595         r.in.domain_handle = domain_handle;
7596         r.in.name = &name;
7597         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
7598         r.out.group_handle = group_handle;
7599         r.out.rid = &rid;
7600
7601         torture_comment(tctx, "Testing CreateDomainGroup(%s)\n", r.in.name->string);
7602
7603         torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7604                 "CreateDomainGroup failed");
7605
7606         if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
7607                 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED)) {
7608                         torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
7609                         return true;
7610                 } else {
7611                         torture_result(tctx, TORTURE_FAIL, "Server should have refused create of '%s', got %s instead\n", r.in.name->string,
7612                                nt_errstr(r.out.result));
7613                         return false;
7614                 }
7615         }
7616
7617         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_GROUP_EXISTS)) {
7618                 if (!test_DeleteGroup_byname(b, tctx, domain_handle, r.in.name->string)) {
7619                         torture_result(tctx, TORTURE_FAIL, "CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
7620                                nt_errstr(r.out.result));
7621                         return false;
7622                 }
7623                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7624                         "CreateDomainGroup failed");
7625         }
7626         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
7627                 if (!test_DeleteUser_byname(b, tctx, domain_handle, r.in.name->string)) {
7628
7629                         torture_result(tctx, TORTURE_FAIL, "CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
7630                                nt_errstr(r.out.result));
7631                         return false;
7632                 }
7633                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_CreateDomainGroup_r(b, tctx, &r),
7634                         "CreateDomainGroup failed");
7635         }
7636         torture_assert_ntstatus_ok(tctx, r.out.result, "CreateDomainGroup");
7637
7638         if (!test_group) {
7639                 return ret;
7640         }
7641
7642         if (!test_AddGroupMember(b, tctx, domain_handle, group_handle)) {
7643                 torture_result(tctx, TORTURE_FAIL, "CreateDomainGroup failed - %s\n", nt_errstr(r.out.result));
7644                 ret = false;
7645         }
7646
7647         if (!test_SetGroupInfo(b, tctx, group_handle)) {
7648                 ret = false;
7649         }
7650
7651         return ret;
7652 }
7653
7654
7655 /*
7656   its not totally clear what this does. It seems to accept any sid you like.
7657 */
7658 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_binding_handle *b,
7659                                                struct torture_context *tctx,
7660                                                struct policy_handle *domain_handle)
7661 {
7662         struct samr_RemoveMemberFromForeignDomain r;
7663
7664         r.in.domain_handle = domain_handle;
7665         r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
7666
7667         torture_assert_ntstatus_ok(tctx, dcerpc_samr_RemoveMemberFromForeignDomain_r(b, tctx, &r),
7668                 "RemoveMemberFromForeignDomain failed");
7669         torture_assert_ntstatus_ok(tctx, r.out.result, "RemoveMemberFromForeignDomain");
7670
7671         return true;
7672 }
7673
7674 static bool test_EnumDomainUsers(struct dcerpc_binding_handle *b,
7675                                  struct torture_context *tctx,
7676                                  struct policy_handle *domain_handle,
7677                                  uint32_t *total_num_entries_p)
7678 {
7679         NTSTATUS status;
7680         struct samr_EnumDomainUsers r;
7681         uint32_t resume_handle = 0;
7682         uint32_t num_entries = 0;
7683         uint32_t total_num_entries = 0;
7684         struct samr_SamArray *sam;
7685
7686         r.in.domain_handle = domain_handle;
7687         r.in.acct_flags = 0;
7688         r.in.max_size = (uint32_t)-1;
7689         r.in.resume_handle = &resume_handle;
7690
7691         r.out.sam = &sam;
7692         r.out.num_entries = &num_entries;
7693         r.out.resume_handle = &resume_handle;
7694
7695         torture_comment(tctx, "Testing EnumDomainUsers\n");
7696
7697         do {
7698                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainUsers_r(b, tctx, &r),
7699                         "EnumDomainUsers failed");
7700                 if (NT_STATUS_IS_ERR(r.out.result)) {
7701                         torture_assert_ntstatus_ok(tctx, r.out.result,
7702                                 "failed to enumerate users");
7703                 }
7704                 status = r.out.result;
7705
7706                 total_num_entries += num_entries;
7707         } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7708
7709         if (total_num_entries_p) {
7710                 *total_num_entries_p = total_num_entries;
7711         }
7712
7713         return true;
7714 }
7715
7716 static bool test_EnumDomainGroups(struct dcerpc_binding_handle *b,
7717                                   struct torture_context *tctx,
7718                                   struct policy_handle *domain_handle,
7719                                   uint32_t *total_num_entries_p)
7720 {
7721         NTSTATUS status;
7722         struct samr_EnumDomainGroups r;
7723         uint32_t resume_handle = 0;
7724         uint32_t num_entries = 0;
7725         uint32_t total_num_entries = 0;
7726         struct samr_SamArray *sam;
7727
7728         r.in.domain_handle = domain_handle;
7729         r.in.max_size = (uint32_t)-1;
7730         r.in.resume_handle = &resume_handle;
7731
7732         r.out.sam = &sam;
7733         r.out.num_entries = &num_entries;
7734         r.out.resume_handle = &resume_handle;
7735
7736         torture_comment(tctx, "Testing EnumDomainGroups\n");
7737
7738         do {
7739                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainGroups_r(b, tctx, &r),
7740                         "EnumDomainGroups failed");
7741                 if (NT_STATUS_IS_ERR(r.out.result)) {
7742                         torture_assert_ntstatus_ok(tctx, r.out.result,
7743                                 "failed to enumerate groups");
7744                 }
7745                 status = r.out.result;
7746
7747                 total_num_entries += num_entries;
7748         } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7749
7750         if (total_num_entries_p) {
7751                 *total_num_entries_p = total_num_entries;
7752         }
7753
7754         return true;
7755 }
7756
7757 static bool test_EnumDomainAliases(struct dcerpc_binding_handle *b,
7758                                    struct torture_context *tctx,
7759                                    struct policy_handle *domain_handle,
7760                                    uint32_t *total_num_entries_p)
7761 {
7762         NTSTATUS status;
7763         struct samr_EnumDomainAliases r;
7764         uint32_t resume_handle = 0;
7765         uint32_t num_entries = 0;
7766         uint32_t total_num_entries = 0;
7767         struct samr_SamArray *sam;
7768
7769         r.in.domain_handle = domain_handle;
7770         r.in.max_size = (uint32_t)-1;
7771         r.in.resume_handle = &resume_handle;
7772
7773         r.out.sam = &sam;
7774         r.out.num_entries = &num_entries;
7775         r.out.resume_handle = &resume_handle;
7776
7777         torture_comment(tctx, "Testing EnumDomainAliases\n");
7778
7779         do {
7780                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomainAliases_r(b, tctx, &r),
7781                         "EnumDomainAliases failed");
7782                 if (NT_STATUS_IS_ERR(r.out.result)) {
7783                         torture_assert_ntstatus_ok(tctx, r.out.result,
7784                                 "failed to enumerate aliases");
7785                 }
7786                 status = r.out.result;
7787
7788                 total_num_entries += num_entries;
7789         } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7790
7791         if (total_num_entries_p) {
7792                 *total_num_entries_p = total_num_entries;
7793         }
7794
7795         return true;
7796 }
7797
7798 static bool test_QueryDisplayInfo_level(struct dcerpc_binding_handle *b,
7799                                         struct torture_context *tctx,
7800                                         struct policy_handle *handle,
7801                                         uint16_t level,
7802                                         uint32_t *total_num_entries_p)
7803 {
7804         NTSTATUS status;
7805         struct samr_QueryDisplayInfo r;
7806         uint32_t total_num_entries = 0;
7807
7808         r.in.domain_handle = handle;
7809         r.in.level = level;
7810         r.in.start_idx = 0;
7811         r.in.max_entries = (uint32_t)-1;
7812         r.in.buf_size = (uint32_t)-1;
7813
7814         torture_comment(tctx, "Testing QueryDisplayInfo\n");
7815
7816         do {
7817                 uint32_t total_size;
7818                 uint32_t returned_size;
7819                 union samr_DispInfo info;
7820
7821                 r.out.total_size = &total_size;
7822                 r.out.returned_size = &returned_size;
7823                 r.out.info = &info;
7824
7825                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDisplayInfo_r(b, tctx, &r),
7826                         "failed to query displayinfo");
7827                 if (NT_STATUS_IS_ERR(r.out.result)) {
7828                         torture_assert_ntstatus_ok(tctx, r.out.result,
7829                                 "failed to query displayinfo");
7830                 }
7831                 status = r.out.result;
7832
7833                 if (*r.out.returned_size == 0) {
7834                         break;
7835                 }
7836
7837                 switch (r.in.level) {
7838                 case 1:
7839                         total_num_entries += info.info1.count;
7840                         r.in.start_idx += info.info1.entries[info.info1.count - 1].idx + 1;
7841                         break;
7842                 case 2:
7843                         total_num_entries += info.info2.count;
7844                         r.in.start_idx += info.info2.entries[info.info2.count - 1].idx + 1;
7845                         break;
7846                 case 3:
7847                         total_num_entries += info.info3.count;
7848                         r.in.start_idx += info.info3.entries[info.info3.count - 1].idx + 1;
7849                         break;
7850                 case 4:
7851                         total_num_entries += info.info4.count;
7852                         r.in.start_idx += info.info4.entries[info.info4.count - 1].idx + 1;
7853                         break;
7854                 case 5:
7855                         total_num_entries += info.info5.count;
7856                         r.in.start_idx += info.info5.entries[info.info5.count - 1].idx + 1;
7857                         break;
7858                 default:
7859                         return false;
7860                 }
7861
7862         } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
7863
7864         if (total_num_entries_p) {
7865                 *total_num_entries_p = total_num_entries;
7866         }
7867
7868         return true;
7869 }
7870
7871 static bool test_ManyObjects(struct dcerpc_pipe *p,
7872                              struct torture_context *tctx,
7873                              struct policy_handle *domain_handle,
7874                              struct dom_sid *domain_sid,
7875                              struct torture_samr_context *ctx)
7876 {
7877         uint32_t num_total = ctx->num_objects_large_dc;
7878         uint32_t num_enum = 0;
7879         uint32_t num_disp = 0;
7880         uint32_t num_created = 0;
7881         uint32_t num_anounced = 0;
7882         uint32_t i;
7883         struct dcerpc_binding_handle *b = p->binding_handle;
7884
7885         struct policy_handle *handles = talloc_zero_array(tctx, struct policy_handle, num_total);
7886
7887         /* query */
7888
7889         {
7890                 struct samr_QueryDomainInfo2 r;
7891                 union samr_DomainInfo *info;
7892                 r.in.domain_handle = domain_handle;
7893                 r.in.level = 2;
7894                 r.out.info = &info;
7895
7896                 torture_assert_ntstatus_ok(tctx, dcerpc_samr_QueryDomainInfo2_r(b, tctx, &r),
7897                         "QueryDomainInfo2 failed");
7898                 torture_assert_ntstatus_ok(tctx, r.out.result,
7899                         "failed to query domain info");
7900
7901                 switch (ctx->choice) {
7902                 case TORTURE_SAMR_MANY_ACCOUNTS:
7903                         num_anounced = info->general.num_users;
7904                         break;
7905                 case TORTURE_SAMR_MANY_GROUPS:
7906                         num_anounced = info->general.num_groups;
7907                         break;
7908                 case TORTURE_SAMR_MANY_ALIASES:
7909                         num_anounced = info->general.num_aliases;
7910                         break;
7911                 default:
7912                         return false;
7913                 }
7914         }
7915
7916         /* create */
7917
7918         for (i=0; i < num_total; i++) {
7919
7920                 const char *name = NULL;
7921
7922                 switch (ctx->choice) {
7923                 case TORTURE_SAMR_MANY_ACCOUNTS:
7924                         name = talloc_asprintf(tctx, "%s%04d", TEST_ACCOUNT_NAME, i);
7925                         torture_assert(tctx,
7926                                 test_CreateUser(p, tctx, domain_handle, name, &handles[i], domain_sid, 0, NULL, false),
7927                                 "failed to create user");
7928                         break;
7929                 case TORTURE_SAMR_MANY_GROUPS:
7930                         name = talloc_asprintf(tctx, "%s%04d", TEST_GROUPNAME, i);
7931                         torture_assert(tctx,
7932                                 test_CreateDomainGroup(b, tctx, domain_handle, name, &handles[i], domain_sid, false),
7933                                 "failed to create group");
7934                         break;
7935                 case TORTURE_SAMR_MANY_ALIASES:
7936                         name = talloc_asprintf(tctx, "%s%04d", TEST_ALIASNAME, i);
7937                         torture_assert(tctx,
7938                                 test_CreateAlias(b, tctx, domain_handle, name, &handles[i], domain_sid, false),
7939                                 "failed to create alias");
7940                         break;
7941                 default:
7942                         return false;
7943                 }
7944                 if (!ndr_policy_handle_empty(&handles[i])) {
7945                         num_created++;
7946                 }
7947         }
7948
7949         /* enum */
7950
7951         switch (ctx->choice) {
7952         case TORTURE_SAMR_MANY_ACCOUNTS:
7953                 torture_assert(tctx,
7954                         test_EnumDomainUsers(b, tctx, domain_handle, &num_enum),
7955                         "failed to enum users");
7956                 break;
7957         case TORTURE_SAMR_MANY_GROUPS:
7958                 torture_assert(tctx,
7959                         test_EnumDomainGroups(b, tctx, domain_handle, &num_enum),
7960                         "failed to enum groups");
7961                 break;
7962         case TORTURE_SAMR_MANY_ALIASES:
7963                 torture_assert(tctx,
7964                         test_EnumDomainAliases(b, tctx, domain_handle, &num_enum),
7965                         "failed to enum aliases");
7966                 break;
7967         default:
7968                 return false;
7969         }
7970
7971         /* dispinfo */
7972
7973         switch (ctx->choice) {
7974         case TORTURE_SAMR_MANY_ACCOUNTS:
7975                 torture_assert(tctx,
7976                         test_QueryDisplayInfo_level(b, tctx, domain_handle, 1, &num_disp),
7977                         "failed to query display info");
7978                 break;
7979         case TORTURE_SAMR_MANY_GROUPS:
7980                 torture_assert(tctx,
7981                         test_QueryDisplayInfo_level(b, tctx, domain_handle, 3, &num_disp),
7982                         "failed to query display info");
7983                 break;
7984         case TORTURE_SAMR_MANY_ALIASES:
7985                 /* no aliases in dispinfo */
7986                 break;
7987         default:
7988                 return false;
7989         }
7990
7991         /* close or delete */
7992
7993         for (i=0; i < num_total; i++) {
7994
7995                 if (ndr_policy_handle_empty(&handles[i])) {
7996                         continue;
7997                 }
7998
7999                 if (torture_setting_bool(tctx, "samba3", false)) {
8000                         torture_assert(tctx,
8001                                 test_samr_handle_Close(b, tctx, &handles[i]),
8002                                 "failed to close handle");
8003                 } else {
8004                         switch (ctx->choice) {
8005                         case TORTURE_SAMR_MANY_ACCOUNTS:
8006                                 torture_assert(tctx,
8007                                         test_DeleteUser(b, tctx, &handles[i]),
8008                                         "failed to delete user");
8009                                 break;
8010                         case TORTURE_SAMR_MANY_GROUPS:
8011                                 torture_assert(tctx,
8012                                         test_DeleteDomainGroup(b, tctx, &handles[i]),
8013                                         "failed to delete group");
8014                                 break;
8015                         case TORTURE_SAMR_MANY_ALIASES:
8016                                 torture_assert(tctx,
8017                                         test_DeleteAlias(b, tctx, &handles[i]),
8018                                         "failed to delete alias");
8019                                 break;
8020                         default:
8021                                 return false;
8022                         }
8023                 }
8024         }
8025
8026         talloc_free(handles);
8027
8028         if (ctx->choice == TORTURE_SAMR_MANY_ACCOUNTS && num_enum != num_anounced + num_created) {
8029                 torture_comment(tctx,
8030                                 "unexpected number of results (%u) returned in enum call, expected %u\n",
8031                                 num_enum, num_anounced + num_created);
8032
8033                 torture_comment(tctx,
8034                                 "unexpected number of results (%u) returned in dispinfo, call, expected %u\n",
8035                                 num_disp, num_anounced + num_created);
8036         }
8037
8038         return true;
8039 }
8040
8041 static bool test_Connect(struct dcerpc_binding_handle *b,
8042                          struct torture_context *tctx,
8043                          struct policy_handle *handle);
8044
8045 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
8046                             struct torture_samr_context *ctx, struct dom_sid *sid)
8047 {
8048         struct samr_OpenDomain r;
8049         struct policy_handle domain_handle;
8050         struct policy_handle alias_handle;
8051         struct policy_handle user_handle;
8052         struct policy_handle group_handle;
8053         bool ret = true;
8054         struct dcerpc_binding_handle *b = p->binding_handle;
8055
8056         ZERO_STRUCT(alias_handle);
8057         ZERO_STRUCT(user_handle);
8058         ZERO_STRUCT(group_handle);
8059         ZERO_STRUCT(domain_handle);
8060
8061         torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
8062
8063         r.in.connect_handle = &ctx->handle;
8064         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
8065         r.in.sid = sid;
8066         r.out.domain_handle = &domain_handle;
8067
8068         torture_assert_ntstatus_ok(tctx, dcerpc_samr_OpenDomain_r(b, tctx, &r),
8069                 "OpenDomain failed");
8070         torture_assert_ntstatus_ok(tctx, r.out.result, "OpenDomain failed");
8071
8072         /* run the domain tests with the main handle closed - this tests
8073            the servers reference counting */
8074         torture_assert(tctx, test_samr_handle_Close(b, tctx, &ctx->handle), "Failed to close SAMR handle");
8075
8076         switch (ctx->choice) {
8077         case TORTURE_SAMR_PASSWORDS:
8078         case TORTURE_SAMR_USER_PRIVILEGES:
8079                 if (!torture_setting_bool(tctx, "samba3", false)) {
8080                         ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, NULL);
8081                 }
8082                 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
8083                 if (!ret) {
8084                         torture_result(tctx, TORTURE_FAIL, "Testing PASSWORDS or PRIVILEGES on domain %s failed!\n", dom_sid_string(tctx, sid));
8085                 }
8086                 break;
8087         case TORTURE_SAMR_USER_ATTRIBUTES:
8088                 if (!torture_setting_bool(tctx, "samba3", false)) {
8089                         ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, NULL);
8090                 }
8091                 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
8092                 /* This test needs 'complex' users to validate */
8093                 ret &= test_QueryDisplayInfo(b, tctx, &domain_handle);
8094                 if (!ret) {
8095                         torture_result(tctx, TORTURE_FAIL, "Testing ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
8096                 }
8097                 break;
8098         case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
8099         case TORTURE_SAMR_PASSWORDS_BADPWDCOUNT:
8100         case TORTURE_SAMR_PASSWORDS_LOCKOUT:
8101                 if (!torture_setting_bool(tctx, "samba3", false)) {
8102                         ret &= test_CreateUser2(p, tctx, &domain_handle, sid, ctx->choice, ctx->machine_credentials);
8103                 }
8104                 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, ctx->machine_credentials, true);
8105                 if (!ret) {
8106                         torture_result(tctx, TORTURE_FAIL, "Testing PASSWORDS PWDLASTSET or BADPWDCOUNT on domain %s failed!\n", dom_sid_string(tctx, sid));
8107                 }
8108                 break;
8109         case TORTURE_SAMR_MANY_ACCOUNTS:
8110         case TORTURE_SAMR_MANY_GROUPS:
8111         case TORTURE_SAMR_MANY_ALIASES:
8112                 ret &= test_ManyObjects(p, tctx, &domain_handle, sid, ctx);
8113                 if (!ret) {
8114                         torture_result(tctx, TORTURE_FAIL, "Testing MANY-{ACCOUNTS,GROUPS,ALIASES} on domain %s failed!\n", dom_sid_string(tctx, sid));
8115                 }
8116                 break;
8117         case TORTURE_SAMR_OTHER:
8118                 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, ctx->choice, NULL, true);
8119                 if (!ret) {
8120                         torture_result(tctx, TORTURE_FAIL, "Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
8121                 }
8122                 if (!torture_setting_bool(tctx, "samba3", false)) {
8123                         ret &= test_QuerySecurity(b, tctx, &domain_handle);
8124                 }
8125                 ret &= test_RemoveMemberFromForeignDomain(b, tctx, &domain_handle);
8126                 ret &= test_CreateAlias(b, tctx, &domain_handle, TEST_ALIASNAME, &alias_handle, sid, true);
8127                 ret &= test_CreateDomainGroup(b, tctx, &domain_handle, TEST_GROUPNAME, &group_handle, sid, true);
8128                 ret &= test_GetAliasMembership(b, tctx, &domain_handle);
8129                 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
8130                 ret &= test_QueryDomainInfo2(b, tctx, &domain_handle);
8131                 ret &= test_EnumDomainUsers_all(b, tctx, &domain_handle);
8132                 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
8133                 ret &= test_EnumDomainGroups_all(b, tctx, &domain_handle);
8134                 ret &= test_EnumDomainAliases_all(b, tctx, &domain_handle);
8135                 ret &= test_QueryDisplayInfo2(b, tctx, &domain_handle);
8136                 ret &= test_QueryDisplayInfo3(b, tctx, &domain_handle);
8137                 ret &= test_QueryDisplayInfo_continue(b, tctx, &domain_handle);
8138
8139                 if (torture_setting_bool(tctx, "samba4", false)) {
8140                         torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
8141                 } else {
8142                         ret &= test_GetDisplayEnumerationIndex(b, tctx, &domain_handle);
8143                         ret &= test_GetDisplayEnumerationIndex2(b, tctx, &domain_handle);
8144                 }
8145                 ret &= test_GroupList(b, tctx, sid, &domain_handle);
8146                 ret &= test_TestPrivateFunctionsDomain(b, tctx, &domain_handle);
8147                 ret &= test_RidToSid(b, tctx, sid, &domain_handle);
8148                 ret &= test_GetBootKeyInformation(b, tctx, &domain_handle);
8149                 if (!ret) {
8150                         torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
8151                 }
8152                 break;
8153         }
8154
8155         if (!ndr_policy_handle_empty(&user_handle) &&
8156             !test_DeleteUser(b, tctx, &user_handle)) {
8157                 ret = false;
8158         }
8159
8160         if (!ndr_policy_handle_empty(&alias_handle) &&
8161             !test_DeleteAlias(b, tctx, &alias_handle)) {
8162                 ret = false;
8163         }
8164
8165         if (!ndr_policy_handle_empty(&group_handle) &&
8166             !test_DeleteDomainGroup(b, tctx, &group_handle)) {
8167                 ret = false;
8168         }
8169
8170         torture_assert(tctx, test_samr_handle_Close(b, tctx, &domain_handle), "Failed to close SAMR domain handle");
8171
8172         torture_assert(tctx, test_Connect(b, tctx, &ctx->handle), "Faile to re-connect SAMR handle");
8173         /* reconnect the main handle */
8174
8175         if (!ret) {
8176                 torture_result(tctx, TORTURE_FAIL, "Testing domain %s failed!\n", dom_sid_string(tctx, sid));
8177         }
8178
8179         return ret;
8180 }
8181
8182 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
8183                               struct torture_samr_context *ctx, const char *domain)
8184 {
8185         struct samr_LookupDomain r;
8186         struct dom_sid2 *sid = NULL;
8187         struct lsa_String n1;
8188         struct lsa_String n2;
8189         bool ret = true;
8190         struct dcerpc_binding_handle *b = p->binding_handle;
8191
8192         torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
8193
8194         /* check for correct error codes */
8195         r.in.connect_handle = &ctx->handle;
8196         r.in.domain_name = &n2;
8197         r.out.sid = &sid;
8198         n2.string = NULL;
8199
8200         torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
8201                 "LookupDomain failed");
8202         torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, r.out.result, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
8203
8204         init_lsa_String(&n2, "xxNODOMAINxx");
8205
8206         torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
8207                 "LookupDomain failed");
8208         torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, r.out.result, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
8209
8210         r.in.connect_handle = &ctx->handle;
8211
8212         init_lsa_String(&n1, domain);
8213         r.in.domain_name = &n1;
8214
8215         torture_assert_ntstatus_ok(tctx, dcerpc_samr_LookupDomain_r(b, tctx, &r),
8216                 "LookupDomain failed");
8217         torture_assert_ntstatus_ok(tctx, r.out.result, "LookupDomain");
8218
8219         if (!test_GetDomPwInfo(p, tctx, &n1)) {
8220                 ret = false;
8221         }
8222
8223         if (!test_OpenDomain(p, tctx, ctx, *r.out.sid)) {
8224                 ret = false;
8225         }
8226
8227         return ret;
8228 }
8229
8230
8231 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
8232                              struct torture_samr_context *ctx)
8233 {
8234         struct samr_EnumDomains r;
8235         uint32_t resume_handle = 0;
8236         uint32_t num_entries = 0;
8237         struct samr_SamArray *sam = NULL;
8238         int i;
8239         bool ret = true;
8240         struct dcerpc_binding_handle *b = p->binding_handle;
8241
8242         r.in.connect_handle = &ctx->handle;
8243         r.in.resume_handle = &resume_handle;
8244         r.in.buf_size = (uint32_t)-1;
8245         r.out.resume_handle = &resume_handle;
8246         r.out.num_entries = &num_entries;
8247         r.out.sam = &sam;
8248
8249         torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomains_r(b, tctx, &r),
8250                 "EnumDomains failed");
8251         torture_assert_ntstatus_ok(tctx, r.out.result, "EnumDomains failed");
8252
8253         if (!*r.out.sam) {
8254                 return false;
8255         }
8256
8257         for (i=0;i<sam->count;i++) {
8258                 if (!test_LookupDomain(p, tctx, ctx,
8259                                        sam->entries[i].name.string)) {
8260                         ret = false;
8261                 }
8262         }
8263
8264         torture_assert_ntstatus_ok(tctx, dcerpc_samr_EnumDomains_r(b, tctx, &r),
8265                 "EnumDomains failed");
8266         torture_assert_ntstatus_ok(tctx, r.out.result, "EnumDomains failed");
8267
8268         return ret;
8269 }
8270
8271
8272 static bool test_Connect(struct dcerpc_binding_handle *b,
8273                          struct torture_context *tctx,
8274                          struct policy_handle *handle)
8275 {
8276         struct samr_Connect r;
8277         struct samr_Connect2 r2;
8278         struct samr_Connect3 r3;
8279         struct samr_Connect4 r4;
8280         struct samr_Connect5 r5;
8281         union samr_ConnectInfo info;
8282         struct policy_handle h;
8283         uint32_t level_out = 0;
8284         bool ret = true, got_handle = false;
8285
8286         torture_comment(tctx, "Testing samr_Connect\n");
8287
8288         r.in.system_name = NULL;
8289         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
8290         r.out.connect_handle = &h;
8291
8292         torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect_r(b, tctx, &r),
8293                 "Connect failed");
8294         if (!NT_STATUS_IS_OK(r.out.result)) {
8295                 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(r.out.result));
8296                 ret = false;
8297         } else {
8298                 got_handle = true;
8299                 *handle = h;
8300         }
8301
8302         torture_comment(tctx, "Testing samr_Connect2\n");
8303
8304         r2.in.system_name = NULL;
8305         r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
8306         r2.out.connect_handle = &h;
8307
8308         torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect2_r(b, tctx, &r2),
8309                 "Connect2 failed");
8310         if (!NT_STATUS_IS_OK(r2.out.result)) {
8311                 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(r2.out.result));
8312                 ret = false;
8313         } else {
8314                 if (got_handle) {
8315                         test_samr_handle_Close(b, tctx, handle);
8316                 }
8317                 got_handle = true;
8318                 *handle = h;
8319         }
8320
8321         torture_comment(tctx, "Testing samr_Connect3\n");
8322
8323         r3.in.system_name = NULL;
8324         r3.in.unknown = 0;
8325         r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
8326         r3.out.connect_handle = &h;
8327
8328         torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect3_r(b, tctx, &r3),
8329                 "Connect3 failed");
8330         if (!NT_STATUS_IS_OK(r3.out.result)) {
8331                 torture_result(tctx, TORTURE_FAIL, "Connect3 failed - %s\n", nt_errstr(r3.out.result));
8332                 ret = false;
8333         } else {
8334                 if (got_handle) {
8335                         test_samr_handle_Close(b, tctx, handle);
8336                 }
8337                 got_handle = true;
8338                 *handle = h;
8339         }
8340
8341         torture_comment(tctx, "Testing samr_Connect4\n");
8342
8343         r4.in.system_name = "";
8344         r4.in.client_version = 0;
8345         r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
8346         r4.out.connect_handle = &h;
8347
8348         torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect4_r(b, tctx, &r4),
8349                 "Connect4 failed");
8350         if (!NT_STATUS_IS_OK(r4.out.result)) {
8351                 torture_result(tctx, TORTURE_FAIL, "Connect4 failed - %s\n", nt_errstr(r4.out.result));
8352                 ret = false;
8353         } else {
8354                 if (got_handle) {
8355                         test_samr_handle_Close(b, tctx, handle);
8356                 }
8357                 got_handle = true;
8358                 *handle = h;
8359         }
8360
8361         torture_comment(tctx, "Testing samr_Connect5\n");
8362
8363         info.info1.client_version = 0;
8364         info.info1.unknown2 = 0;
8365
8366         r5.in.system_name = "";
8367         r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
8368         r5.in.level_in = 1;
8369         r5.out.level_out = &level_out;
8370         r5.in.info_in = &info;
8371         r5.out.info_out = &info;
8372         r5.out.connect_handle = &h;
8373
8374         torture_assert_ntstatus_ok(tctx, dcerpc_samr_Connect5_r(b, tctx, &r5),
8375                 "Connect5 failed");
8376         if (!NT_STATUS_IS_OK(r5.out.result)) {
8377                 torture_result(tctx, TORTURE_FAIL, "Connect5 failed - %s\n", nt_errstr(r5.out.result));
8378                 ret = false;
8379         } else {
8380                 if (got_handle) {
8381                         test_samr_handle_Close(b, tctx, handle);
8382                 }
8383                 got_handle = true;
8384                 *handle = h;
8385         }
8386
8387         return ret;
8388 }
8389
8390
8391 static bool test_samr_ValidatePassword(struct torture_context *tctx,
8392                                        struct dcerpc_pipe *p)
8393 {
8394         struct samr_ValidatePassword r;
8395         union samr_ValidatePasswordReq req;
8396         union samr_ValidatePasswordRep *repp = NULL;
8397         NTSTATUS status;
8398         const char *passwords[] = { "penguin", "p@ssw0rd", "p@ssw0rd123$", NULL };
8399         int i;
8400         struct dcerpc_binding_handle *b = p->binding_handle;
8401
8402         torture_comment(tctx, "Testing samr_ValidatePassword\n");
8403
8404         if (p->conn->transport.transport != NCACN_IP_TCP) {
8405                 torture_comment(tctx, "samr_ValidatePassword only should succeed over NCACN_IP_TCP!\n");
8406         }
8407
8408         ZERO_STRUCT(r);
8409         r.in.level = NetValidatePasswordReset;
8410         r.in.req = &req;
8411         r.out.rep = &repp;
8412
8413         ZERO_STRUCT(req);
8414         req.req3.account.string = "non-existent-account-aklsdji";
8415
8416         for (i=0; passwords[i]; i++) {
8417                 req.req3.password.string = passwords[i];
8418
8419                 status = dcerpc_samr_ValidatePassword_r(b, tctx, &r);
8420                 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
8421                         torture_skip(tctx, "ValidatePassword not supported by server\n");
8422                 }
8423                 torture_assert_ntstatus_ok(tctx, status,
8424                                            "samr_ValidatePassword failed");
8425                 torture_assert_ntstatus_ok(tctx, r.out.result,
8426                                            "samr_ValidatePassword failed");
8427                 torture_comment(tctx, "Server %s password '%s' with code %i\n",
8428                                 repp->ctr3.status==SAMR_VALIDATION_STATUS_SUCCESS?"allowed":"refused",
8429                                 req.req3.password.string, repp->ctr3.status);
8430         }
8431
8432         return true;
8433 }
8434
8435 bool torture_rpc_samr(struct torture_context *torture)
8436 {
8437         NTSTATUS status;
8438         struct dcerpc_pipe *p;
8439         bool ret = true;
8440         struct torture_samr_context *ctx;
8441         struct dcerpc_binding_handle *b;
8442
8443         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8444         if (!NT_STATUS_IS_OK(status)) {
8445                 return false;
8446         }
8447         b = p->binding_handle;
8448
8449         ctx = talloc_zero(torture, struct torture_samr_context);
8450
8451         ctx->choice = TORTURE_SAMR_OTHER;
8452
8453         ret &= test_Connect(b, torture, &ctx->handle);
8454
8455         if (!torture_setting_bool(torture, "samba3", false)) {
8456                 ret &= test_QuerySecurity(b, torture, &ctx->handle);
8457         }
8458
8459         ret &= test_EnumDomains(p, torture, ctx);
8460
8461         ret &= test_SetDsrmPassword(b, torture, &ctx->handle);
8462
8463         ret &= test_Shutdown(b, torture, &ctx->handle);
8464
8465         ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8466
8467         return ret;
8468 }
8469
8470
8471 bool torture_rpc_samr_users(struct torture_context *torture)
8472 {
8473         NTSTATUS status;
8474         struct dcerpc_pipe *p;
8475         bool ret = true;
8476         struct torture_samr_context *ctx;
8477         struct dcerpc_binding_handle *b;
8478
8479         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8480         if (!NT_STATUS_IS_OK(status)) {
8481                 return false;
8482         }
8483         b = p->binding_handle;
8484
8485         ctx = talloc_zero(torture, struct torture_samr_context);
8486
8487         ctx->choice = TORTURE_SAMR_USER_ATTRIBUTES;
8488
8489         ret &= test_Connect(b, torture, &ctx->handle);
8490
8491         if (!torture_setting_bool(torture, "samba3", false)) {
8492                 ret &= test_QuerySecurity(b, torture, &ctx->handle);
8493         }
8494
8495         ret &= test_EnumDomains(p, torture, ctx);
8496
8497         ret &= test_SetDsrmPassword(b, torture, &ctx->handle);
8498
8499         ret &= test_Shutdown(b, torture, &ctx->handle);
8500
8501         ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8502
8503         return ret;
8504 }
8505
8506
8507 bool torture_rpc_samr_passwords(struct torture_context *torture)
8508 {
8509         NTSTATUS status;
8510         struct dcerpc_pipe *p;
8511         bool ret = true;
8512         struct torture_samr_context *ctx;
8513         struct dcerpc_binding_handle *b;
8514
8515         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8516         if (!NT_STATUS_IS_OK(status)) {
8517                 return false;
8518         }
8519         b = p->binding_handle;
8520
8521         ctx = talloc_zero(torture, struct torture_samr_context);
8522
8523         ctx->choice = TORTURE_SAMR_PASSWORDS;
8524
8525         ret &= test_Connect(b, torture, &ctx->handle);
8526
8527         ret &= test_EnumDomains(p, torture, ctx);
8528
8529         ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8530
8531         return ret;
8532 }
8533
8534 static bool torture_rpc_samr_pwdlastset(struct torture_context *torture,
8535                                         struct dcerpc_pipe *p2,
8536                                         struct cli_credentials *machine_credentials)
8537 {
8538         NTSTATUS status;
8539         struct dcerpc_pipe *p;
8540         bool ret = true;
8541         struct torture_samr_context *ctx;
8542         struct dcerpc_binding_handle *b;
8543
8544         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8545         if (!NT_STATUS_IS_OK(status)) {
8546                 return false;
8547         }
8548         b = p->binding_handle;
8549
8550         ctx = talloc_zero(torture, struct torture_samr_context);
8551
8552         ctx->choice = TORTURE_SAMR_PASSWORDS_PWDLASTSET;
8553         ctx->machine_credentials = machine_credentials;
8554
8555         ret &= test_Connect(b, torture, &ctx->handle);
8556
8557         ret &= test_EnumDomains(p, torture, ctx);
8558
8559         ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8560
8561         return ret;
8562 }
8563
8564 struct torture_suite *torture_rpc_samr_passwords_pwdlastset(TALLOC_CTX *mem_ctx)
8565 {
8566         struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.pwdlastset");
8567         struct torture_rpc_tcase *tcase;
8568
8569         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8570                                                           &ndr_table_samr,
8571                                                           TEST_ACCOUNT_NAME_PWD);
8572
8573         torture_rpc_tcase_add_test_creds(tcase, "pwdLastSet",
8574                                          torture_rpc_samr_pwdlastset);
8575
8576         return suite;
8577 }
8578
8579 static bool torture_rpc_samr_users_privileges_delete_user(struct torture_context *torture,
8580                                                           struct dcerpc_pipe *p2,
8581                                                           struct cli_credentials *machine_credentials)
8582 {
8583         NTSTATUS status;
8584         struct dcerpc_pipe *p;
8585         bool ret = true;
8586         struct torture_samr_context *ctx;
8587         struct dcerpc_binding_handle *b;
8588
8589         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8590         if (!NT_STATUS_IS_OK(status)) {
8591                 return false;
8592         }
8593         b = p->binding_handle;
8594
8595         ctx = talloc_zero(torture, struct torture_samr_context);
8596
8597         ctx->choice = TORTURE_SAMR_USER_PRIVILEGES;
8598         ctx->machine_credentials = machine_credentials;
8599
8600         ret &= test_Connect(b, torture, &ctx->handle);
8601
8602         ret &= test_EnumDomains(p, torture, ctx);
8603
8604         ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8605
8606         return ret;
8607 }
8608
8609 struct torture_suite *torture_rpc_samr_user_privileges(TALLOC_CTX *mem_ctx)
8610 {
8611         struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.users.privileges");
8612         struct torture_rpc_tcase *tcase;
8613
8614         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8615                                                           &ndr_table_samr,
8616                                                           TEST_ACCOUNT_NAME_PWD);
8617
8618         torture_rpc_tcase_add_test_creds(tcase, "delete_privileged_user",
8619                                          torture_rpc_samr_users_privileges_delete_user);
8620
8621         return suite;
8622 }
8623
8624 static bool torture_rpc_samr_many_accounts(struct torture_context *torture,
8625                                            struct dcerpc_pipe *p2,
8626                                            void *data)
8627 {
8628         NTSTATUS status;
8629         struct dcerpc_pipe *p;
8630         bool ret = true;
8631         struct torture_samr_context *ctx =
8632                 talloc_get_type_abort(data, struct torture_samr_context);
8633         struct dcerpc_binding_handle *b;
8634
8635         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8636         if (!NT_STATUS_IS_OK(status)) {
8637                 return false;
8638         }
8639         b = p->binding_handle;
8640
8641         ctx->choice = TORTURE_SAMR_MANY_ACCOUNTS;
8642         ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8643                                                         ctx->num_objects_large_dc);
8644
8645         ret &= test_Connect(b, torture, &ctx->handle);
8646
8647         ret &= test_EnumDomains(p, torture, ctx);
8648
8649         ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8650
8651         return ret;
8652 }
8653
8654 static bool torture_rpc_samr_many_groups(struct torture_context *torture,
8655                                          struct dcerpc_pipe *p2,
8656                                          void *data)
8657 {
8658         NTSTATUS status;
8659         struct dcerpc_pipe *p;
8660         bool ret = true;
8661         struct torture_samr_context *ctx =
8662                 talloc_get_type_abort(data, struct torture_samr_context);
8663         struct dcerpc_binding_handle *b;
8664
8665         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8666         if (!NT_STATUS_IS_OK(status)) {
8667                 return false;
8668         }
8669         b = p->binding_handle;
8670
8671         ctx->choice = TORTURE_SAMR_MANY_GROUPS;
8672         ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8673                                                         ctx->num_objects_large_dc);
8674
8675         ret &= test_Connect(b, torture, &ctx->handle);
8676
8677         ret &= test_EnumDomains(p, torture, ctx);
8678
8679         ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8680
8681         return ret;
8682 }
8683
8684 static bool torture_rpc_samr_many_aliases(struct torture_context *torture,
8685                                           struct dcerpc_pipe *p2,
8686                                           void *data)
8687 {
8688         NTSTATUS status;
8689         struct dcerpc_pipe *p;
8690         bool ret = true;
8691         struct torture_samr_context *ctx =
8692                 talloc_get_type_abort(data, struct torture_samr_context);
8693         struct dcerpc_binding_handle *b;
8694
8695         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8696         if (!NT_STATUS_IS_OK(status)) {
8697                 return false;
8698         }
8699         b = p->binding_handle;
8700
8701         ctx->choice = TORTURE_SAMR_MANY_ALIASES;
8702         ctx->num_objects_large_dc = torture_setting_int(torture, "large_dc",
8703                                                         ctx->num_objects_large_dc);
8704
8705         ret &= test_Connect(b, torture, &ctx->handle);
8706
8707         ret &= test_EnumDomains(p, torture, ctx);
8708
8709         ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8710
8711         return ret;
8712 }
8713
8714 struct torture_suite *torture_rpc_samr_large_dc(TALLOC_CTX *mem_ctx)
8715 {
8716         struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.large-dc");
8717         struct torture_rpc_tcase *tcase;
8718         struct torture_samr_context *ctx;
8719
8720         tcase = torture_suite_add_rpc_iface_tcase(suite, "samr", &ndr_table_samr);
8721
8722         ctx = talloc_zero(suite, struct torture_samr_context);
8723         ctx->num_objects_large_dc = 150;
8724
8725         torture_rpc_tcase_add_test_ex(tcase, "many_aliases",
8726                                       torture_rpc_samr_many_aliases, ctx);
8727         torture_rpc_tcase_add_test_ex(tcase, "many_groups",
8728                                       torture_rpc_samr_many_groups, ctx);
8729         torture_rpc_tcase_add_test_ex(tcase, "many_accounts",
8730                                       torture_rpc_samr_many_accounts, ctx);
8731
8732         return suite;
8733 }
8734
8735 static bool torture_rpc_samr_badpwdcount(struct torture_context *torture,
8736                                          struct dcerpc_pipe *p2,
8737                                          struct cli_credentials *machine_credentials)
8738 {
8739         NTSTATUS status;
8740         struct dcerpc_pipe *p;
8741         bool ret = true;
8742         struct torture_samr_context *ctx;
8743         struct dcerpc_binding_handle *b;
8744
8745         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8746         if (!NT_STATUS_IS_OK(status)) {
8747                 return false;
8748         }
8749         b = p->binding_handle;
8750
8751         ctx = talloc_zero(torture, struct torture_samr_context);
8752
8753         ctx->choice = TORTURE_SAMR_PASSWORDS_BADPWDCOUNT;
8754         ctx->machine_credentials = machine_credentials;
8755
8756         ret &= test_Connect(b, torture, &ctx->handle);
8757
8758         ret &= test_EnumDomains(p, torture, ctx);
8759
8760         ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8761
8762         return ret;
8763 }
8764
8765 struct torture_suite *torture_rpc_samr_passwords_badpwdcount(TALLOC_CTX *mem_ctx)
8766 {
8767         struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.badpwdcount");
8768         struct torture_rpc_tcase *tcase;
8769
8770         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8771                                                           &ndr_table_samr,
8772                                                           TEST_ACCOUNT_NAME_PWD);
8773
8774         torture_rpc_tcase_add_test_creds(tcase, "badPwdCount",
8775                                          torture_rpc_samr_badpwdcount);
8776
8777         return suite;
8778 }
8779
8780 static bool torture_rpc_samr_lockout(struct torture_context *torture,
8781                                      struct dcerpc_pipe *p2,
8782                                      struct cli_credentials *machine_credentials)
8783 {
8784         NTSTATUS status;
8785         struct dcerpc_pipe *p;
8786         bool ret = true;
8787         struct torture_samr_context *ctx;
8788         struct dcerpc_binding_handle *b;
8789
8790         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
8791         if (!NT_STATUS_IS_OK(status)) {
8792                 return false;
8793         }
8794         b = p->binding_handle;
8795
8796         ctx = talloc_zero(torture, struct torture_samr_context);
8797
8798         ctx->choice = TORTURE_SAMR_PASSWORDS_LOCKOUT;
8799         ctx->machine_credentials = machine_credentials;
8800
8801         ret &= test_Connect(b, torture, &ctx->handle);
8802
8803         ret &= test_EnumDomains(p, torture, ctx);
8804
8805         ret &= test_samr_handle_Close(b, torture, &ctx->handle);
8806
8807         return ret;
8808 }
8809
8810 struct torture_suite *torture_rpc_samr_passwords_lockout(TALLOC_CTX *mem_ctx)
8811 {
8812         struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.lockout");
8813         struct torture_rpc_tcase *tcase;
8814
8815         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "samr",
8816                                                           &ndr_table_samr,
8817                                                           TEST_ACCOUNT_NAME_PWD);
8818
8819         torture_rpc_tcase_add_test_creds(tcase, "lockout",
8820                                          torture_rpc_samr_lockout);
8821
8822         return suite;
8823 }
8824
8825 struct torture_suite *torture_rpc_samr_passwords_validate(TALLOC_CTX *mem_ctx)
8826 {
8827         struct torture_suite *suite = torture_suite_create(mem_ctx, "samr.passwords.validate");
8828         struct torture_rpc_tcase *tcase;
8829
8830         tcase = torture_suite_add_rpc_iface_tcase(suite, "samr",
8831                                                   &ndr_table_samr);
8832         torture_rpc_tcase_add_test(tcase, "validate",
8833                                    test_samr_ValidatePassword);
8834
8835         return suite;
8836 }