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