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