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