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