s3-printing: eliminate another non sec_initial_uid using security check.
[ira/wip.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) Guenther Deschner 2008,2009
8
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.
21 */
22
23 #include "includes.h"
24 #include "torture/torture.h"
25 #include "system/time.h"
26 #include "librpc/gen_ndr/lsa.h"
27 #include "librpc/gen_ndr/ndr_netlogon.h"
28 #include "librpc/gen_ndr/ndr_netlogon_c.h"
29 #include "librpc/gen_ndr/ndr_samr_c.h"
30 #include "librpc/gen_ndr/ndr_lsa_c.h"
31 #include "../lib/crypto/crypto.h"
32 #include "libcli/auth/libcli_auth.h"
33 #include "libcli/security/security.h"
34 #include "torture/rpc/rpc.h"
35 #include "param/param.h"
36
37 #include <unistd.h>
38
39 #define TEST_ACCOUNT_NAME "samrtorturetest"
40 #define TEST_ACCOUNT_NAME_PWD "samrpwdlastset"
41 #define TEST_ALIASNAME "samrtorturetestalias"
42 #define TEST_GROUPNAME "samrtorturetestgroup"
43 #define TEST_MACHINENAME "samrtestmach$"
44 #define TEST_DOMAINNAME "samrtestdom$"
45
46 enum torture_samr_choice {
47         TORTURE_SAMR_PASSWORDS,
48         TORTURE_SAMR_PASSWORDS_PWDLASTSET,
49         TORTURE_SAMR_USER_ATTRIBUTES,
50         TORTURE_SAMR_USER_PRIVILEGES,
51         TORTURE_SAMR_OTHER,
52         TORTURE_SAMR_MANY_ACCOUNTS,
53         TORTURE_SAMR_MANY_GROUPS,
54         TORTURE_SAMR_MANY_ALIASES
55 };
56
57 static bool test_QueryUserInfo(struct dcerpc_pipe *p,
58                                struct torture_context *tctx,
59                                struct policy_handle *handle);
60
61 static bool test_QueryUserInfo2(struct dcerpc_pipe *p,
62                                 struct torture_context *tctx,
63                                 struct policy_handle *handle);
64
65 static bool test_QueryAliasInfo(struct dcerpc_pipe *p,
66                                 struct torture_context *tctx,
67                                 struct policy_handle *handle);
68
69 static bool test_ChangePassword(struct dcerpc_pipe *p,
70                                 struct torture_context *tctx,
71                                 const char *acct_name,
72                                 struct policy_handle *domain_handle, char **password);
73
74 static void init_lsa_String(struct lsa_String *string, const char *s)
75 {
76         string->string = s;
77 }
78
79 static void init_lsa_StringLarge(struct lsa_StringLarge *string, const char *s)
80 {
81         string->string = s;
82 }
83
84 static void init_lsa_BinaryString(struct lsa_BinaryString *string, const char *s, uint32_t length)
85 {
86         string->length = length;
87         string->size = length;
88         string->array = (uint16_t *)discard_const(s);
89 }
90
91 bool test_samr_handle_Close(struct dcerpc_pipe *p, struct torture_context *tctx,
92                                    struct policy_handle *handle)
93 {
94         NTSTATUS status;
95         struct samr_Close r;
96
97         r.in.handle = handle;
98         r.out.handle = handle;
99
100         status = dcerpc_samr_Close(p, tctx, &r);
101         torture_assert_ntstatus_ok(tctx, status, "Close");
102
103         return true;
104 }
105
106 static bool test_Shutdown(struct dcerpc_pipe *p, struct torture_context *tctx,
107                        struct policy_handle *handle)
108 {
109         NTSTATUS status;
110         struct samr_Shutdown r;
111
112         if (!torture_setting_bool(tctx, "dangerous", false)) {
113                 torture_skip(tctx, "samr_Shutdown disabled - enable dangerous tests to use\n");
114                 return true;
115         }
116
117         r.in.connect_handle = handle;
118
119         torture_comment(tctx, "testing samr_Shutdown\n");
120
121         status = dcerpc_samr_Shutdown(p, tctx, &r);
122         torture_assert_ntstatus_ok(tctx, status, "samr_Shutdown");
123
124         return true;
125 }
126
127 static bool test_SetDsrmPassword(struct dcerpc_pipe *p, struct torture_context *tctx,
128                                  struct policy_handle *handle)
129 {
130         NTSTATUS status;
131         struct samr_SetDsrmPassword r;
132         struct lsa_String string;
133         struct samr_Password hash;
134
135         if (!torture_setting_bool(tctx, "dangerous", false)) {
136                 torture_skip(tctx, "samr_SetDsrmPassword disabled - enable dangerous tests to use");
137         }
138
139         E_md4hash("TeSTDSRM123", hash.hash);
140
141         init_lsa_String(&string, "Administrator");
142
143         r.in.name = &string;
144         r.in.unknown = 0;
145         r.in.hash = &hash;
146
147         torture_comment(tctx, "testing samr_SetDsrmPassword\n");
148
149         status = dcerpc_samr_SetDsrmPassword(p, tctx, &r);
150         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_SUPPORTED, "samr_SetDsrmPassword");
151
152         return true;
153 }
154
155
156 static bool test_QuerySecurity(struct dcerpc_pipe *p,
157                                struct torture_context *tctx,
158                                struct policy_handle *handle)
159 {
160         NTSTATUS status;
161         struct samr_QuerySecurity r;
162         struct samr_SetSecurity s;
163         struct sec_desc_buf *sdbuf = NULL;
164
165         r.in.handle = handle;
166         r.in.sec_info = 7;
167         r.out.sdbuf = &sdbuf;
168
169         status = dcerpc_samr_QuerySecurity(p, tctx, &r);
170         torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
171
172         torture_assert(tctx, sdbuf != NULL, "sdbuf is NULL");
173
174         s.in.handle = handle;
175         s.in.sec_info = 7;
176         s.in.sdbuf = sdbuf;
177
178         if (torture_setting_bool(tctx, "samba4", false)) {
179                 torture_skip(tctx, "skipping SetSecurity test against Samba4\n");
180         }
181
182         status = dcerpc_samr_SetSecurity(p, tctx, &s);
183         torture_assert_ntstatus_ok(tctx, status, "SetSecurity");
184
185         status = dcerpc_samr_QuerySecurity(p, tctx, &r);
186         torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
187
188         return true;
189 }
190
191
192 static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
193                              struct policy_handle *handle, uint32_t base_acct_flags,
194                              const char *base_account_name)
195 {
196         NTSTATUS status;
197         struct samr_SetUserInfo s;
198         struct samr_SetUserInfo2 s2;
199         struct samr_QueryUserInfo q;
200         struct samr_QueryUserInfo q0;
201         union samr_UserInfo u;
202         union samr_UserInfo *info;
203         bool ret = true;
204         const char *test_account_name;
205
206         uint32_t user_extra_flags = 0;
207
208         if (!torture_setting_bool(tctx, "samba3", false)) {
209                 if (base_acct_flags == ACB_NORMAL) {
210                         /* When created, accounts are expired by default */
211                         user_extra_flags = ACB_PW_EXPIRED;
212                 }
213         }
214
215         s.in.user_handle = handle;
216         s.in.info = &u;
217
218         s2.in.user_handle = handle;
219         s2.in.info = &u;
220
221         q.in.user_handle = handle;
222         q.out.info = &info;
223         q0 = q;
224
225 #define TESTCALL(call, r) \
226                 status = dcerpc_samr_ ##call(p, tctx, &r); \
227                 if (!NT_STATUS_IS_OK(status)) { \
228                         torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
229                                r.in.level, nt_errstr(status), __location__); \
230                         ret = false; \
231                         break; \
232                 }
233
234 #define STRING_EQUAL(s1, s2, field) \
235                 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
236                         torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
237                                #field, s2, __location__); \
238                         ret = false; \
239                         break; \
240                 }
241
242 #define MEM_EQUAL(s1, s2, length, field) \
243                 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
244                         torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
245                                #field, (const char *)s2, __location__); \
246                         ret = false; \
247                         break; \
248                 }
249
250 #define INT_EQUAL(i1, i2, field) \
251                 if (i1 != i2) { \
252                         torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
253                                #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
254                         ret = false; \
255                         break; \
256                 }
257
258 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
259                 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
260                 q.in.level = lvl1; \
261                 TESTCALL(QueryUserInfo, q) \
262                 s.in.level = lvl1; \
263                 s2.in.level = lvl1; \
264                 u = *info; \
265                 if (lvl1 == 21) { \
266                         ZERO_STRUCT(u.info21); \
267                         u.info21.fields_present = fpval; \
268                 } \
269                 init_lsa_String(&u.info ## lvl1.field1, value); \
270                 TESTCALL(SetUserInfo, s) \
271                 TESTCALL(SetUserInfo2, s2) \
272                 init_lsa_String(&u.info ## lvl1.field1, ""); \
273                 TESTCALL(QueryUserInfo, q); \
274                 u = *info; \
275                 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
276                 q.in.level = lvl2; \
277                 TESTCALL(QueryUserInfo, q) \
278                 u = *info; \
279                 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
280         } while (0)
281
282 #define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
283                 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
284                 q.in.level = lvl1; \
285                 TESTCALL(QueryUserInfo, q) \
286                 s.in.level = lvl1; \
287                 s2.in.level = lvl1; \
288                 u = *info; \
289                 if (lvl1 == 21) { \
290                         ZERO_STRUCT(u.info21); \
291                         u.info21.fields_present = fpval; \
292                 } \
293                 init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
294                 TESTCALL(SetUserInfo, s) \
295                 TESTCALL(SetUserInfo2, s2) \
296                 init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
297                 TESTCALL(QueryUserInfo, q); \
298                 u = *info; \
299                 MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
300                 q.in.level = lvl2; \
301                 TESTCALL(QueryUserInfo, q) \
302                 u = *info; \
303                 MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
304         } while (0)
305
306 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
307                 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
308                 q.in.level = lvl1; \
309                 TESTCALL(QueryUserInfo, q) \
310                 s.in.level = lvl1; \
311                 s2.in.level = lvl1; \
312                 u = *info; \
313                 if (lvl1 == 21) { \
314                         uint8_t *bits = u.info21.logon_hours.bits; \
315                         ZERO_STRUCT(u.info21); \
316                         if (fpval == SAMR_FIELD_LOGON_HOURS) { \
317                                 u.info21.logon_hours.units_per_week = 168; \
318                                 u.info21.logon_hours.bits = bits; \
319                         } \
320                         u.info21.fields_present = fpval; \
321                 } \
322                 u.info ## lvl1.field1 = value; \
323                 TESTCALL(SetUserInfo, s) \
324                 TESTCALL(SetUserInfo2, s2) \
325                 u.info ## lvl1.field1 = 0; \
326                 TESTCALL(QueryUserInfo, q); \
327                 u = *info; \
328                 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
329                 q.in.level = lvl2; \
330                 TESTCALL(QueryUserInfo, q) \
331                 u = *info; \
332                 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
333         } while (0)
334
335 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
336         TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
337         } while (0)
338
339         q0.in.level = 12;
340         do { TESTCALL(QueryUserInfo, q0) } while (0);
341
342         /* Samba 3 cannot store comment fields atm. - gd */
343         if (!torture_setting_bool(tctx, "samba3", false)) {
344                 TEST_USERINFO_STRING(2, comment,  1, comment, "xx2-1 comment", 0);
345                 TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
346                 TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment",
347                                    SAMR_FIELD_COMMENT);
348         }
349
350         test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
351         TEST_USERINFO_STRING(7, account_name,  1, account_name, base_account_name, 0);
352         test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
353         TEST_USERINFO_STRING(7, account_name,  3, account_name, base_account_name, 0);
354         test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
355         TEST_USERINFO_STRING(7, account_name,  5, account_name, base_account_name, 0);
356         test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
357         TEST_USERINFO_STRING(7, account_name,  6, account_name, base_account_name, 0);
358         test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
359         TEST_USERINFO_STRING(7, account_name,  7, account_name, base_account_name, 0);
360         test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
361         TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
362         test_account_name = base_account_name;
363         TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name,
364                            SAMR_FIELD_ACCOUNT_NAME);
365
366         TEST_USERINFO_STRING(6, full_name,  1, full_name, "xx6-1 full_name", 0);
367         TEST_USERINFO_STRING(6, full_name,  3, full_name, "xx6-3 full_name", 0);
368         TEST_USERINFO_STRING(6, full_name,  5, full_name, "xx6-5 full_name", 0);
369         TEST_USERINFO_STRING(6, full_name,  6, full_name, "xx6-6 full_name", 0);
370         TEST_USERINFO_STRING(6, full_name,  8, full_name, "xx6-8 full_name", 0);
371         TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
372         TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
373         TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name",
374                            SAMR_FIELD_FULL_NAME);
375
376         TEST_USERINFO_STRING(6, full_name,  1, full_name, "", 0);
377         TEST_USERINFO_STRING(6, full_name,  3, full_name, "", 0);
378         TEST_USERINFO_STRING(6, full_name,  5, full_name, "", 0);
379         TEST_USERINFO_STRING(6, full_name,  6, full_name, "", 0);
380         TEST_USERINFO_STRING(6, full_name,  8, full_name, "", 0);
381         TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
382         TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
383         TEST_USERINFO_STRING(21, full_name, 21, full_name, "",
384                            SAMR_FIELD_FULL_NAME);
385
386         TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
387         TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
388         TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
389         TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script",
390                            SAMR_FIELD_LOGON_SCRIPT);
391
392         TEST_USERINFO_STRING(12, profile_path,  3, profile_path, "xx12-3 profile_path", 0);
393         TEST_USERINFO_STRING(12, profile_path,  5, profile_path, "xx12-5 profile_path", 0);
394         TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
395         TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path",
396                            SAMR_FIELD_PROFILE_PATH);
397
398         TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
399         TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
400         TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
401         TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
402                              SAMR_FIELD_HOME_DIRECTORY);
403         TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
404                              SAMR_FIELD_HOME_DIRECTORY);
405
406         TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
407         TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
408         TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
409         TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
410                              SAMR_FIELD_HOME_DRIVE);
411         TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
412                              SAMR_FIELD_HOME_DRIVE);
413
414         TEST_USERINFO_STRING(13, description,  1, description, "xx13-1 description", 0);
415         TEST_USERINFO_STRING(13, description,  5, description, "xx13-5 description", 0);
416         TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
417         TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description",
418                            SAMR_FIELD_DESCRIPTION);
419
420         TEST_USERINFO_STRING(14, workstations,  3, workstations, "14workstation3", 0);
421         TEST_USERINFO_STRING(14, workstations,  5, workstations, "14workstation4", 0);
422         TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
423         TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21",
424                            SAMR_FIELD_WORKSTATIONS);
425         TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3",
426                            SAMR_FIELD_WORKSTATIONS);
427         TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5",
428                            SAMR_FIELD_WORKSTATIONS);
429         TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
430                            SAMR_FIELD_WORKSTATIONS);
431
432         TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
433         TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
434                            SAMR_FIELD_PARAMETERS);
435         TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
436                            SAMR_FIELD_PARAMETERS);
437         /* also empty user parameters are allowed */
438         TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "", 0);
439         TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "",
440                            SAMR_FIELD_PARAMETERS);
441         TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "",
442                            SAMR_FIELD_PARAMETERS);
443
444         /* Samba 3 cannot store country_code and copy_page atm. - gd */
445         if (!torture_setting_bool(tctx, "samba3", false)) {
446                 TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
447                 TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
448                 TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__,
449                                   SAMR_FIELD_COUNTRY_CODE);
450                 TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__,
451                                   SAMR_FIELD_COUNTRY_CODE);
452
453                 TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
454                 TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__,
455                                   SAMR_FIELD_CODE_PAGE);
456                 TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__,
457                                   SAMR_FIELD_CODE_PAGE);
458         }
459
460         if (!torture_setting_bool(tctx, "samba3", false)) {
461                 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
462                 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
463                 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__,
464                                   SAMR_FIELD_ACCT_EXPIRY);
465                 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__,
466                                   SAMR_FIELD_ACCT_EXPIRY);
467                 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__,
468                                   SAMR_FIELD_ACCT_EXPIRY);
469         } else {
470                 /* Samba 3 can only store seconds / time_t in passdb - gd */
471                 NTTIME nt;
472                 unix_to_nt_time(&nt, time(NULL) + __LINE__);
473                 TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, nt, 0);
474                 unix_to_nt_time(&nt, time(NULL) + __LINE__);
475                 TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, nt, 0);
476                 unix_to_nt_time(&nt, time(NULL) + __LINE__);
477                 TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
478                 unix_to_nt_time(&nt, time(NULL) + __LINE__);
479                 TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
480                 unix_to_nt_time(&nt, time(NULL) + __LINE__);
481                 TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, nt, SAMR_FIELD_ACCT_EXPIRY);
482         }
483
484         TEST_USERINFO_INT(4, logon_hours.bits[3],  3, logon_hours.bits[3], 1, 0);
485         TEST_USERINFO_INT(4, logon_hours.bits[3],  5, logon_hours.bits[3], 2, 0);
486         TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
487         TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4,
488                           SAMR_FIELD_LOGON_HOURS);
489
490         TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
491                               (base_acct_flags  | ACB_DISABLED | ACB_HOMDIRREQ),
492                               (base_acct_flags  | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
493                               0);
494         TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
495                               (base_acct_flags  | ACB_DISABLED),
496                               (base_acct_flags  | ACB_DISABLED | user_extra_flags),
497                               0);
498
499         /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
500         TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags,
501                               (base_acct_flags  | ACB_DISABLED | ACB_PWNOEXP),
502                               (base_acct_flags  | ACB_DISABLED | ACB_PWNOEXP),
503                               0);
504         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
505                               (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ),
506                               (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags),
507                               0);
508
509
510         /* The 'autolock' flag doesn't stick - check this */
511         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
512                               (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK),
513                               (base_acct_flags | ACB_DISABLED | user_extra_flags),
514                               0);
515 #if 0
516         /* Removing the 'disabled' flag doesn't stick - check this */
517         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
518                               (base_acct_flags),
519                               (base_acct_flags | ACB_DISABLED | user_extra_flags),
520                               0);
521 #endif
522
523         /* Samba3 cannot store these atm */
524         if (!torture_setting_bool(tctx, "samba3", false)) {
525         /* The 'store plaintext' flag does stick */
526         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
527                               (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED),
528                               (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags),
529                               0);
530         /* The 'use DES' flag does stick */
531         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
532                               (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY),
533                               (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags),
534                               0);
535         /* The 'don't require kerberos pre-authentication flag does stick */
536         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
537                               (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH),
538                               (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags),
539                               0);
540         /* The 'no kerberos PAC required' flag sticks */
541         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags,
542                               (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD),
543                               (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags),
544                               0);
545         }
546         TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags,
547                               (base_acct_flags | ACB_DISABLED),
548                               (base_acct_flags | ACB_DISABLED | user_extra_flags),
549                               SAMR_FIELD_ACCT_FLAGS);
550
551 #if 0
552         /* these fail with win2003 - it appears you can't set the primary gid?
553            the set succeeds, but the gid isn't changed. Very weird! */
554         TEST_USERINFO_INT(9, primary_gid,  1, primary_gid, 513);
555         TEST_USERINFO_INT(9, primary_gid,  3, primary_gid, 513);
556         TEST_USERINFO_INT(9, primary_gid,  5, primary_gid, 513);
557         TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
558 #endif
559
560         return ret;
561 }
562
563 /*
564   generate a random password for password change tests
565 */
566 static char *samr_rand_pass_silent(TALLOC_CTX *mem_ctx, int min_len)
567 {
568         size_t len = MAX(8, min_len) + (random() % 6);
569         char *s = generate_random_str(mem_ctx, len);
570         return s;
571 }
572
573 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
574 {
575         char *s = samr_rand_pass_silent(mem_ctx, min_len);
576         printf("Generated password '%s'\n", s);
577         return s;
578
579 }
580
581 /*
582   generate a random password for password change tests
583 */
584 static DATA_BLOB samr_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
585 {
586         int i;
587         DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
588         generate_random_buffer(password.data, password.length);
589
590         for (i=0; i < len; i++) {
591                 if (((uint16_t *)password.data)[i] == 0) {
592                         ((uint16_t *)password.data)[i] = 1;
593                 }
594         }
595
596         return password;
597 }
598
599 /*
600   generate a random password for password change tests (fixed length)
601 */
602 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
603 {
604         char *s = generate_random_str(mem_ctx, len);
605         printf("Generated password '%s'\n", s);
606         return s;
607 }
608
609 static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx,
610                              struct policy_handle *handle, char **password)
611 {
612         NTSTATUS status;
613         struct samr_SetUserInfo s;
614         union samr_UserInfo u;
615         bool ret = true;
616         DATA_BLOB session_key;
617         char *newpass;
618         struct samr_GetUserPwInfo pwp;
619         struct samr_PwInfo info;
620         int policy_min_pw_len = 0;
621         pwp.in.user_handle = handle;
622         pwp.out.info = &info;
623
624         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
625         if (NT_STATUS_IS_OK(status)) {
626                 policy_min_pw_len = pwp.out.info->min_password_length;
627         }
628         newpass = samr_rand_pass(tctx, policy_min_pw_len);
629
630         s.in.user_handle = handle;
631         s.in.info = &u;
632         s.in.level = 24;
633
634         encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
635         u.info24.password_expired = 0;
636
637         status = dcerpc_fetch_session_key(p, &session_key);
638         if (!NT_STATUS_IS_OK(status)) {
639                 printf("SetUserInfo level %u - no session key - %s\n",
640                        s.in.level, nt_errstr(status));
641                 return false;
642         }
643
644         arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
645
646         torture_comment(tctx, "Testing SetUserInfo level 24 (set password)\n");
647
648         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
649         if (!NT_STATUS_IS_OK(status)) {
650                 printf("SetUserInfo level %u failed - %s\n",
651                        s.in.level, nt_errstr(status));
652                 ret = false;
653         } else {
654                 *password = newpass;
655         }
656
657         return ret;
658 }
659
660
661 static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *tctx,
662                                 struct policy_handle *handle, uint32_t fields_present,
663                                 char **password)
664 {
665         NTSTATUS status;
666         struct samr_SetUserInfo s;
667         union samr_UserInfo u;
668         bool ret = true;
669         DATA_BLOB session_key;
670         char *newpass;
671         struct samr_GetUserPwInfo pwp;
672         struct samr_PwInfo info;
673         int policy_min_pw_len = 0;
674         pwp.in.user_handle = handle;
675         pwp.out.info = &info;
676
677         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
678         if (NT_STATUS_IS_OK(status)) {
679                 policy_min_pw_len = pwp.out.info->min_password_length;
680         }
681         newpass = samr_rand_pass(tctx, policy_min_pw_len);
682
683         s.in.user_handle = handle;
684         s.in.info = &u;
685         s.in.level = 23;
686
687         ZERO_STRUCT(u);
688
689         u.info23.info.fields_present = fields_present;
690
691         encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
692
693         status = dcerpc_fetch_session_key(p, &session_key);
694         if (!NT_STATUS_IS_OK(status)) {
695                 printf("SetUserInfo level %u - no session key - %s\n",
696                        s.in.level, nt_errstr(status));
697                 return false;
698         }
699
700         arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
701
702         torture_comment(tctx, "Testing SetUserInfo level 23 (set password)\n");
703
704         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
705         if (!NT_STATUS_IS_OK(status)) {
706                 printf("SetUserInfo level %u failed - %s\n",
707                        s.in.level, nt_errstr(status));
708                 ret = false;
709         } else {
710                 *password = newpass;
711         }
712
713         encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
714
715         status = dcerpc_fetch_session_key(p, &session_key);
716         if (!NT_STATUS_IS_OK(status)) {
717                 printf("SetUserInfo level %u - no session key - %s\n",
718                        s.in.level, nt_errstr(status));
719                 return false;
720         }
721
722         /* This should break the key nicely */
723         session_key.length--;
724         arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
725
726         torture_comment(tctx, "Testing SetUserInfo level 23 (set password) with wrong password\n");
727
728         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
729         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
730                 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
731                        s.in.level, nt_errstr(status));
732                 ret = false;
733         }
734
735         return ret;
736 }
737
738
739 static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tctx,
740                                struct policy_handle *handle, bool makeshort,
741                                char **password)
742 {
743         NTSTATUS status;
744         struct samr_SetUserInfo s;
745         union samr_UserInfo u;
746         bool ret = true;
747         DATA_BLOB session_key;
748         DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
749         uint8_t confounder[16];
750         char *newpass;
751         struct MD5Context ctx;
752         struct samr_GetUserPwInfo pwp;
753         struct samr_PwInfo info;
754         int policy_min_pw_len = 0;
755         pwp.in.user_handle = handle;
756         pwp.out.info = &info;
757
758         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
759         if (NT_STATUS_IS_OK(status)) {
760                 policy_min_pw_len = pwp.out.info->min_password_length;
761         }
762         if (makeshort && policy_min_pw_len) {
763                 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
764         } else {
765                 newpass = samr_rand_pass(tctx, policy_min_pw_len);
766         }
767
768         s.in.user_handle = handle;
769         s.in.info = &u;
770         s.in.level = 26;
771
772         encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
773         u.info26.password_expired = 0;
774
775         status = dcerpc_fetch_session_key(p, &session_key);
776         if (!NT_STATUS_IS_OK(status)) {
777                 printf("SetUserInfo level %u - no session key - %s\n",
778                        s.in.level, nt_errstr(status));
779                 return false;
780         }
781
782         generate_random_buffer((uint8_t *)confounder, 16);
783
784         MD5Init(&ctx);
785         MD5Update(&ctx, confounder, 16);
786         MD5Update(&ctx, session_key.data, session_key.length);
787         MD5Final(confounded_session_key.data, &ctx);
788
789         arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
790         memcpy(&u.info26.password.data[516], confounder, 16);
791
792         torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex)\n");
793
794         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
795         if (!NT_STATUS_IS_OK(status)) {
796                 printf("SetUserInfo level %u failed - %s\n",
797                        s.in.level, nt_errstr(status));
798                 ret = false;
799         } else {
800                 *password = newpass;
801         }
802
803         /* This should break the key nicely */
804         confounded_session_key.data[0]++;
805
806         arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
807         memcpy(&u.info26.password.data[516], confounder, 16);
808
809         torture_comment(tctx, "Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
810
811         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
812         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
813                 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
814                        s.in.level, nt_errstr(status));
815                 ret = false;
816         } else {
817                 *password = newpass;
818         }
819
820         return ret;
821 }
822
823 static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *tctx,
824                                 struct policy_handle *handle, uint32_t fields_present,
825                                 char **password)
826 {
827         NTSTATUS status;
828         struct samr_SetUserInfo s;
829         union samr_UserInfo u;
830         bool ret = true;
831         DATA_BLOB session_key;
832         DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
833         struct MD5Context ctx;
834         uint8_t confounder[16];
835         char *newpass;
836         struct samr_GetUserPwInfo pwp;
837         struct samr_PwInfo info;
838         int policy_min_pw_len = 0;
839         pwp.in.user_handle = handle;
840         pwp.out.info = &info;
841
842         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
843         if (NT_STATUS_IS_OK(status)) {
844                 policy_min_pw_len = pwp.out.info->min_password_length;
845         }
846         newpass = samr_rand_pass(tctx, policy_min_pw_len);
847
848         s.in.user_handle = handle;
849         s.in.info = &u;
850         s.in.level = 25;
851
852         ZERO_STRUCT(u);
853
854         u.info25.info.fields_present = fields_present;
855
856         encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
857
858         status = dcerpc_fetch_session_key(p, &session_key);
859         if (!NT_STATUS_IS_OK(status)) {
860                 printf("SetUserInfo level %u - no session key - %s\n",
861                        s.in.level, nt_errstr(status));
862                 return false;
863         }
864
865         generate_random_buffer((uint8_t *)confounder, 16);
866
867         MD5Init(&ctx);
868         MD5Update(&ctx, confounder, 16);
869         MD5Update(&ctx, session_key.data, session_key.length);
870         MD5Final(confounded_session_key.data, &ctx);
871
872         arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
873         memcpy(&u.info25.password.data[516], confounder, 16);
874
875         torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex)\n");
876
877         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
878         if (!NT_STATUS_IS_OK(status)) {
879                 printf("SetUserInfo level %u failed - %s\n",
880                        s.in.level, nt_errstr(status));
881                 ret = false;
882         } else {
883                 *password = newpass;
884         }
885
886         /* This should break the key nicely */
887         confounded_session_key.data[0]++;
888
889         arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
890         memcpy(&u.info25.password.data[516], confounder, 16);
891
892         torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
893
894         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
895         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
896                 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
897                        s.in.level, nt_errstr(status));
898                 ret = false;
899         }
900
901         return ret;
902 }
903
904 static bool test_SetUserPass_18(struct dcerpc_pipe *p, struct torture_context *tctx,
905                                 struct policy_handle *handle, char **password)
906 {
907         NTSTATUS status;
908         struct samr_SetUserInfo s;
909         union samr_UserInfo u;
910         bool ret = true;
911         DATA_BLOB session_key;
912         char *newpass;
913         struct samr_GetUserPwInfo pwp;
914         struct samr_PwInfo info;
915         int policy_min_pw_len = 0;
916         uint8_t lm_hash[16], nt_hash[16];
917
918         pwp.in.user_handle = handle;
919         pwp.out.info = &info;
920
921         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
922         if (NT_STATUS_IS_OK(status)) {
923                 policy_min_pw_len = pwp.out.info->min_password_length;
924         }
925         newpass = samr_rand_pass(tctx, policy_min_pw_len);
926
927         s.in.user_handle = handle;
928         s.in.info = &u;
929         s.in.level = 18;
930
931         ZERO_STRUCT(u);
932
933         u.info18.nt_pwd_active = true;
934         u.info18.lm_pwd_active = true;
935
936         E_md4hash(newpass, nt_hash);
937         E_deshash(newpass, lm_hash);
938
939         status = dcerpc_fetch_session_key(p, &session_key);
940         if (!NT_STATUS_IS_OK(status)) {
941                 printf("SetUserInfo level %u - no session key - %s\n",
942                        s.in.level, nt_errstr(status));
943                 return false;
944         }
945
946         {
947                 DATA_BLOB in,out;
948                 in = data_blob_const(nt_hash, 16);
949                 out = data_blob_talloc_zero(tctx, 16);
950                 sess_crypt_blob(&out, &in, &session_key, true);
951                 memcpy(u.info18.nt_pwd.hash, out.data, out.length);
952         }
953         {
954                 DATA_BLOB in,out;
955                 in = data_blob_const(lm_hash, 16);
956                 out = data_blob_talloc_zero(tctx, 16);
957                 sess_crypt_blob(&out, &in, &session_key, true);
958                 memcpy(u.info18.lm_pwd.hash, out.data, out.length);
959         }
960
961         torture_comment(tctx, "Testing SetUserInfo level 18 (set password hash)\n");
962
963         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
964         if (!NT_STATUS_IS_OK(status)) {
965                 printf("SetUserInfo level %u failed - %s\n",
966                        s.in.level, nt_errstr(status));
967                 ret = false;
968         } else {
969                 *password = newpass;
970         }
971
972         return ret;
973 }
974
975 static bool test_SetUserPass_21(struct dcerpc_pipe *p, struct torture_context *tctx,
976                                 struct policy_handle *handle, uint32_t fields_present,
977                                 char **password)
978 {
979         NTSTATUS status;
980         struct samr_SetUserInfo s;
981         union samr_UserInfo u;
982         bool ret = true;
983         DATA_BLOB session_key;
984         char *newpass;
985         struct samr_GetUserPwInfo pwp;
986         struct samr_PwInfo info;
987         int policy_min_pw_len = 0;
988         uint8_t lm_hash[16], nt_hash[16];
989
990         pwp.in.user_handle = handle;
991         pwp.out.info = &info;
992
993         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
994         if (NT_STATUS_IS_OK(status)) {
995                 policy_min_pw_len = pwp.out.info->min_password_length;
996         }
997         newpass = samr_rand_pass(tctx, policy_min_pw_len);
998
999         s.in.user_handle = handle;
1000         s.in.info = &u;
1001         s.in.level = 21;
1002
1003         E_md4hash(newpass, nt_hash);
1004         E_deshash(newpass, lm_hash);
1005
1006         ZERO_STRUCT(u);
1007
1008         u.info21.fields_present = fields_present;
1009
1010         if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1011                 u.info21.lm_owf_password.length = 16;
1012                 u.info21.lm_owf_password.size = 16;
1013                 u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1014                 u.info21.lm_password_set = true;
1015         }
1016
1017         if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1018                 u.info21.nt_owf_password.length = 16;
1019                 u.info21.nt_owf_password.size = 16;
1020                 u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1021                 u.info21.nt_password_set = true;
1022         }
1023
1024         status = dcerpc_fetch_session_key(p, &session_key);
1025         if (!NT_STATUS_IS_OK(status)) {
1026                 printf("SetUserInfo level %u - no session key - %s\n",
1027                        s.in.level, nt_errstr(status));
1028                 return false;
1029         }
1030
1031         if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1032                 DATA_BLOB in,out;
1033                 in = data_blob_const(u.info21.lm_owf_password.array,
1034                                      u.info21.lm_owf_password.length);
1035                 out = data_blob_talloc_zero(tctx, 16);
1036                 sess_crypt_blob(&out, &in, &session_key, true);
1037                 u.info21.lm_owf_password.array = (uint16_t *)out.data;
1038         }
1039
1040         if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1041                 DATA_BLOB in,out;
1042                 in = data_blob_const(u.info21.nt_owf_password.array,
1043                                      u.info21.nt_owf_password.length);
1044                 out = data_blob_talloc_zero(tctx, 16);
1045                 sess_crypt_blob(&out, &in, &session_key, true);
1046                 u.info21.nt_owf_password.array = (uint16_t *)out.data;
1047         }
1048
1049         torture_comment(tctx, "Testing SetUserInfo level 21 (set password hash)\n");
1050
1051         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1052         if (!NT_STATUS_IS_OK(status)) {
1053                 printf("SetUserInfo level %u failed - %s\n",
1054                        s.in.level, nt_errstr(status));
1055                 ret = false;
1056         } else {
1057                 *password = newpass;
1058         }
1059
1060         /* try invalid length */
1061         if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1062
1063                 u.info21.nt_owf_password.length++;
1064
1065                 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1066
1067                 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1068                         printf("SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1069                                s.in.level, nt_errstr(status));
1070                         ret = false;
1071                 }
1072         }
1073
1074         if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1075
1076                 u.info21.lm_owf_password.length++;
1077
1078                 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1079
1080                 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1081                         printf("SetUserInfo level %u should have failed with NT_STATUS_INVALID_PARAMETER - %s\n",
1082                                s.in.level, nt_errstr(status));
1083                         ret = false;
1084                 }
1085         }
1086
1087         return ret;
1088 }
1089
1090 static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p,
1091                                       struct torture_context *tctx,
1092                                       struct policy_handle *handle,
1093                                       uint16_t level,
1094                                       uint32_t fields_present,
1095                                       char **password, uint8_t password_expired,
1096                                       bool use_setinfo2,
1097                                       bool *matched_expected_error)
1098 {
1099         NTSTATUS status;
1100         NTSTATUS expected_error = NT_STATUS_OK;
1101         struct samr_SetUserInfo s;
1102         struct samr_SetUserInfo2 s2;
1103         union samr_UserInfo u;
1104         bool ret = true;
1105         DATA_BLOB session_key;
1106         DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
1107         struct MD5Context ctx;
1108         uint8_t confounder[16];
1109         char *newpass;
1110         struct samr_GetUserPwInfo pwp;
1111         struct samr_PwInfo info;
1112         int policy_min_pw_len = 0;
1113         const char *comment = NULL;
1114         uint8_t lm_hash[16], nt_hash[16];
1115
1116         pwp.in.user_handle = handle;
1117         pwp.out.info = &info;
1118
1119         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1120         if (NT_STATUS_IS_OK(status)) {
1121                 policy_min_pw_len = pwp.out.info->min_password_length;
1122         }
1123         newpass = samr_rand_pass_silent(tctx, policy_min_pw_len);
1124
1125         if (use_setinfo2) {
1126                 s2.in.user_handle = handle;
1127                 s2.in.info = &u;
1128                 s2.in.level = level;
1129         } else {
1130                 s.in.user_handle = handle;
1131                 s.in.info = &u;
1132                 s.in.level = level;
1133         }
1134
1135         if (fields_present & SAMR_FIELD_COMMENT) {
1136                 comment = talloc_asprintf(tctx, "comment: %ld\n", time(NULL));
1137         }
1138
1139         ZERO_STRUCT(u);
1140
1141         switch (level) {
1142         case 18:
1143                 E_md4hash(newpass, nt_hash);
1144                 E_deshash(newpass, lm_hash);
1145
1146                 u.info18.nt_pwd_active = true;
1147                 u.info18.lm_pwd_active = true;
1148                 u.info18.password_expired = password_expired;
1149
1150                 memcpy(u.info18.lm_pwd.hash, lm_hash, 16);
1151                 memcpy(u.info18.nt_pwd.hash, nt_hash, 16);
1152
1153                 break;
1154         case 21:
1155                 E_md4hash(newpass, nt_hash);
1156                 E_deshash(newpass, lm_hash);
1157
1158                 u.info21.fields_present = fields_present;
1159                 u.info21.password_expired = password_expired;
1160                 u.info21.comment.string = comment;
1161
1162                 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1163                         u.info21.lm_owf_password.length = 16;
1164                         u.info21.lm_owf_password.size = 16;
1165                         u.info21.lm_owf_password.array = (uint16_t *)lm_hash;
1166                         u.info21.lm_password_set = true;
1167                 }
1168
1169                 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1170                         u.info21.nt_owf_password.length = 16;
1171                         u.info21.nt_owf_password.size = 16;
1172                         u.info21.nt_owf_password.array = (uint16_t *)nt_hash;
1173                         u.info21.nt_password_set = true;
1174                 }
1175
1176                 break;
1177         case 23:
1178                 u.info23.info.fields_present = fields_present;
1179                 u.info23.info.password_expired = password_expired;
1180                 u.info23.info.comment.string = comment;
1181
1182                 encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
1183
1184                 break;
1185         case 24:
1186                 u.info24.password_expired = password_expired;
1187
1188                 encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
1189
1190                 break;
1191         case 25:
1192                 u.info25.info.fields_present = fields_present;
1193                 u.info25.info.password_expired = password_expired;
1194                 u.info25.info.comment.string = comment;
1195
1196                 encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
1197
1198                 break;
1199         case 26:
1200                 u.info26.password_expired = password_expired;
1201
1202                 encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
1203
1204                 break;
1205         }
1206
1207         status = dcerpc_fetch_session_key(p, &session_key);
1208         if (!NT_STATUS_IS_OK(status)) {
1209                 printf("SetUserInfo level %u - no session key - %s\n",
1210                        s.in.level, nt_errstr(status));
1211                 return false;
1212         }
1213
1214         generate_random_buffer((uint8_t *)confounder, 16);
1215
1216         MD5Init(&ctx);
1217         MD5Update(&ctx, confounder, 16);
1218         MD5Update(&ctx, session_key.data, session_key.length);
1219         MD5Final(confounded_session_key.data, &ctx);
1220
1221         switch (level) {
1222         case 18:
1223                 {
1224                         DATA_BLOB in,out;
1225                         in = data_blob_const(u.info18.nt_pwd.hash, 16);
1226                         out = data_blob_talloc_zero(tctx, 16);
1227                         sess_crypt_blob(&out, &in, &session_key, true);
1228                         memcpy(u.info18.nt_pwd.hash, out.data, out.length);
1229                 }
1230                 {
1231                         DATA_BLOB in,out;
1232                         in = data_blob_const(u.info18.lm_pwd.hash, 16);
1233                         out = data_blob_talloc_zero(tctx, 16);
1234                         sess_crypt_blob(&out, &in, &session_key, true);
1235                         memcpy(u.info18.lm_pwd.hash, out.data, out.length);
1236                 }
1237
1238                 break;
1239         case 21:
1240                 if (fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT) {
1241                         DATA_BLOB in,out;
1242                         in = data_blob_const(u.info21.lm_owf_password.array,
1243                                              u.info21.lm_owf_password.length);
1244                         out = data_blob_talloc_zero(tctx, 16);
1245                         sess_crypt_blob(&out, &in, &session_key, true);
1246                         u.info21.lm_owf_password.array = (uint16_t *)out.data;
1247                 }
1248                 if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
1249                         DATA_BLOB in,out;
1250                         in = data_blob_const(u.info21.nt_owf_password.array,
1251                                              u.info21.nt_owf_password.length);
1252                         out = data_blob_talloc_zero(tctx, 16);
1253                         sess_crypt_blob(&out, &in, &session_key, true);
1254                         u.info21.nt_owf_password.array = (uint16_t *)out.data;
1255                 }
1256                 break;
1257         case 23:
1258                 arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
1259                 break;
1260         case 24:
1261                 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
1262                 break;
1263         case 25:
1264                 arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
1265                 memcpy(&u.info25.password.data[516], confounder, 16);
1266                 break;
1267         case 26:
1268                 arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
1269                 memcpy(&u.info26.password.data[516], confounder, 16);
1270                 break;
1271         }
1272
1273         if (use_setinfo2) {
1274                 status = dcerpc_samr_SetUserInfo2(p, tctx, &s2);
1275         } else {
1276                 status = dcerpc_samr_SetUserInfo(p, tctx, &s);
1277         }
1278
1279         if (!NT_STATUS_IS_OK(status)) {
1280                 if (fields_present == 0) {
1281                         expected_error = NT_STATUS_INVALID_PARAMETER;
1282                 }
1283                 if (fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
1284                         expected_error = NT_STATUS_ACCESS_DENIED;
1285                 }
1286         }
1287
1288         if (!NT_STATUS_IS_OK(expected_error)) {
1289                 if (use_setinfo2) {
1290                         torture_assert_ntstatus_equal(tctx,
1291                                 s2.out.result,
1292                                 expected_error, "SetUserInfo2 failed");
1293                 } else {
1294                         torture_assert_ntstatus_equal(tctx,
1295                                 s.out.result,
1296                                 expected_error, "SetUserInfo failed");
1297                 }
1298                 *matched_expected_error = true;
1299                 return true;
1300         }
1301
1302         if (!NT_STATUS_IS_OK(status)) {
1303                 printf("SetUserInfo%s level %u failed - %s\n",
1304                        use_setinfo2 ? "2":"", level, nt_errstr(status));
1305                 ret = false;
1306         } else {
1307                 *password = newpass;
1308         }
1309
1310         return ret;
1311 }
1312
1313 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1314                                struct policy_handle *handle)
1315 {
1316         NTSTATUS status;
1317         struct samr_SetAliasInfo r;
1318         struct samr_QueryAliasInfo q;
1319         union samr_AliasInfo *info;
1320         uint16_t levels[] = {2, 3};
1321         int i;
1322         bool ret = true;
1323
1324         /* Ignoring switch level 1, as that includes the number of members for the alias
1325          * and setting this to a wrong value might have negative consequences
1326          */
1327
1328         for (i=0;i<ARRAY_SIZE(levels);i++) {
1329                 torture_comment(tctx, "Testing SetAliasInfo level %u\n", levels[i]);
1330
1331                 r.in.alias_handle = handle;
1332                 r.in.level = levels[i];
1333                 r.in.info  = talloc(tctx, union samr_AliasInfo);
1334                 switch (r.in.level) {
1335                     case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
1336                     case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
1337                                 "Test Description, should test I18N as well"); break;
1338                     case ALIASINFOALL: printf("ALIASINFOALL ignored\n"); break;
1339                 }
1340
1341                 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
1342                 if (!NT_STATUS_IS_OK(status)) {
1343                         printf("SetAliasInfo level %u failed - %s\n",
1344                                levels[i], nt_errstr(status));
1345                         ret = false;
1346                 }
1347
1348                 q.in.alias_handle = handle;
1349                 q.in.level = levels[i];
1350                 q.out.info = &info;
1351
1352                 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
1353                 if (!NT_STATUS_IS_OK(status)) {
1354                         printf("QueryAliasInfo level %u failed - %s\n",
1355                                levels[i], nt_errstr(status));
1356                         ret = false;
1357                 }
1358         }
1359
1360         return ret;
1361 }
1362
1363 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1364                                   struct policy_handle *user_handle)
1365 {
1366         struct samr_GetGroupsForUser r;
1367         struct samr_RidWithAttributeArray *rids = NULL;
1368         NTSTATUS status;
1369
1370         torture_comment(tctx, "testing GetGroupsForUser\n");
1371
1372         r.in.user_handle = user_handle;
1373         r.out.rids = &rids;
1374
1375         status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
1376         torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
1377
1378         return true;
1379
1380 }
1381
1382 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1383                               struct lsa_String *domain_name)
1384 {
1385         NTSTATUS status;
1386         struct samr_GetDomPwInfo r;
1387         struct samr_PwInfo info;
1388
1389         r.in.domain_name = domain_name;
1390         r.out.info = &info;
1391
1392         torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1393
1394         status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1395         torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1396
1397         r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1398         torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1399
1400         status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1401         torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1402
1403         r.in.domain_name->string = "\\\\__NONAME__";
1404         torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1405
1406         status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1407         torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1408
1409         r.in.domain_name->string = "\\\\Builtin";
1410         torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
1411
1412         status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
1413         torture_assert_ntstatus_ok(tctx, status, "GetDomPwInfo");
1414
1415         return true;
1416 }
1417
1418 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
1419                                struct policy_handle *handle)
1420 {
1421         NTSTATUS status;
1422         struct samr_GetUserPwInfo r;
1423         struct samr_PwInfo info;
1424
1425         torture_comment(tctx, "Testing GetUserPwInfo\n");
1426
1427         r.in.user_handle = handle;
1428         r.out.info = &info;
1429
1430         status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
1431         torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
1432
1433         return true;
1434 }
1435
1436 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
1437                                 struct policy_handle *domain_handle, const char *name,
1438                                 uint32_t *rid)
1439 {
1440         NTSTATUS status;
1441         struct samr_LookupNames n;
1442         struct lsa_String sname[2];
1443         struct samr_Ids rids, types;
1444
1445         init_lsa_String(&sname[0], name);
1446
1447         n.in.domain_handle = domain_handle;
1448         n.in.num_names = 1;
1449         n.in.names = sname;
1450         n.out.rids = &rids;
1451         n.out.types = &types;
1452         status = dcerpc_samr_LookupNames(p, tctx, &n);
1453         if (NT_STATUS_IS_OK(status)) {
1454                 *rid = n.out.rids->ids[0];
1455         } else {
1456                 return status;
1457         }
1458
1459         init_lsa_String(&sname[1], "xxNONAMExx");
1460         n.in.num_names = 2;
1461         status = dcerpc_samr_LookupNames(p, tctx, &n);
1462         if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
1463                 printf("LookupNames[2] failed - %s\n", nt_errstr(status));
1464                 if (NT_STATUS_IS_OK(status)) {
1465                         return NT_STATUS_UNSUCCESSFUL;
1466                 }
1467                 return status;
1468         }
1469
1470         n.in.num_names = 0;
1471         status = dcerpc_samr_LookupNames(p, tctx, &n);
1472         if (!NT_STATUS_IS_OK(status)) {
1473                 printf("LookupNames[0] failed - %s\n", nt_errstr(status));
1474                 return status;
1475         }
1476
1477         init_lsa_String(&sname[0], "xxNONAMExx");
1478         n.in.num_names = 1;
1479         status = dcerpc_samr_LookupNames(p, tctx, &n);
1480         if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1481                 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));
1482                 if (NT_STATUS_IS_OK(status)) {
1483                         return NT_STATUS_UNSUCCESSFUL;
1484                 }
1485                 return status;
1486         }
1487
1488         init_lsa_String(&sname[0], "xxNONAMExx");
1489         init_lsa_String(&sname[1], "xxNONAME2xx");
1490         n.in.num_names = 2;
1491         status = dcerpc_samr_LookupNames(p, tctx, &n);
1492         if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
1493                 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));
1494                 if (NT_STATUS_IS_OK(status)) {
1495                         return NT_STATUS_UNSUCCESSFUL;
1496                 }
1497                 return status;
1498         }
1499
1500         return NT_STATUS_OK;
1501 }
1502
1503 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p,
1504                                      struct torture_context *tctx,
1505                                      struct policy_handle *domain_handle,
1506                                      const char *name, struct policy_handle *user_handle)
1507 {
1508         NTSTATUS status;
1509         struct samr_OpenUser r;
1510         uint32_t rid;
1511
1512         status = test_LookupName(p, tctx, domain_handle, name, &rid);
1513         if (!NT_STATUS_IS_OK(status)) {
1514                 return status;
1515         }
1516
1517         r.in.domain_handle = domain_handle;
1518         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1519         r.in.rid = rid;
1520         r.out.user_handle = user_handle;
1521         status = dcerpc_samr_OpenUser(p, tctx, &r);
1522         if (!NT_STATUS_IS_OK(status)) {
1523                 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1524         }
1525
1526         return status;
1527 }
1528
1529 #if 0
1530 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p,
1531                                    struct torture_context *tctx,
1532                                    struct policy_handle *handle)
1533 {
1534         NTSTATUS status;
1535         struct samr_ChangePasswordUser r;
1536         bool ret = true;
1537         struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1538         struct policy_handle user_handle;
1539         char *oldpass = "test";
1540         char *newpass = "test2";
1541         uint8_t old_nt_hash[16], new_nt_hash[16];
1542         uint8_t old_lm_hash[16], new_lm_hash[16];
1543
1544         status = test_OpenUser_byname(p, tctx, handle, "testuser", &user_handle);
1545         if (!NT_STATUS_IS_OK(status)) {
1546                 return false;
1547         }
1548
1549         printf("Testing ChangePasswordUser for user 'testuser'\n");
1550
1551         printf("old password: %s\n", oldpass);
1552         printf("new password: %s\n", newpass);
1553
1554         E_md4hash(oldpass, old_nt_hash);
1555         E_md4hash(newpass, new_nt_hash);
1556         E_deshash(oldpass, old_lm_hash);
1557         E_deshash(newpass, new_lm_hash);
1558
1559         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1560         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1561         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1562         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1563         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1564         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1565
1566         r.in.handle = &user_handle;
1567         r.in.lm_present = 1;
1568         r.in.old_lm_crypted = &hash1;
1569         r.in.new_lm_crypted = &hash2;
1570         r.in.nt_present = 1;
1571         r.in.old_nt_crypted = &hash3;
1572         r.in.new_nt_crypted = &hash4;
1573         r.in.cross1_present = 1;
1574         r.in.nt_cross = &hash5;
1575         r.in.cross2_present = 1;
1576         r.in.lm_cross = &hash6;
1577
1578         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1579         if (!NT_STATUS_IS_OK(status)) {
1580                 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1581                 ret = false;
1582         }
1583
1584         if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1585                 ret = false;
1586         }
1587
1588         return ret;
1589 }
1590 #endif
1591
1592 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_context *tctx,
1593                                     const char *acct_name,
1594                                     struct policy_handle *handle, char **password)
1595 {
1596         NTSTATUS status;
1597         struct samr_ChangePasswordUser r;
1598         bool ret = true;
1599         struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1600         struct policy_handle user_handle;
1601         char *oldpass;
1602         uint8_t old_nt_hash[16], new_nt_hash[16];
1603         uint8_t old_lm_hash[16], new_lm_hash[16];
1604         bool changed = true;
1605
1606         char *newpass;
1607         struct samr_GetUserPwInfo pwp;
1608         struct samr_PwInfo info;
1609         int policy_min_pw_len = 0;
1610
1611         status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle);
1612         if (!NT_STATUS_IS_OK(status)) {
1613                 return false;
1614         }
1615         pwp.in.user_handle = &user_handle;
1616         pwp.out.info = &info;
1617
1618         status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
1619         if (NT_STATUS_IS_OK(status)) {
1620                 policy_min_pw_len = pwp.out.info->min_password_length;
1621         }
1622         newpass = samr_rand_pass(tctx, policy_min_pw_len);
1623
1624         torture_comment(tctx, "Testing ChangePasswordUser\n");
1625
1626         torture_assert(tctx, *password != NULL,
1627                                    "Failing ChangePasswordUser as old password was NULL.  Previous test failed?");
1628
1629         oldpass = *password;
1630
1631         E_md4hash(oldpass, old_nt_hash);
1632         E_md4hash(newpass, new_nt_hash);
1633         E_deshash(oldpass, old_lm_hash);
1634         E_deshash(newpass, new_lm_hash);
1635
1636         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1637         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1638         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1639         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1640         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1641         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1642
1643         r.in.user_handle = &user_handle;
1644         r.in.lm_present = 1;
1645         /* Break the LM hash */
1646         hash1.hash[0]++;
1647         r.in.old_lm_crypted = &hash1;
1648         r.in.new_lm_crypted = &hash2;
1649         r.in.nt_present = 1;
1650         r.in.old_nt_crypted = &hash3;
1651         r.in.new_nt_crypted = &hash4;
1652         r.in.cross1_present = 1;
1653         r.in.nt_cross = &hash5;
1654         r.in.cross2_present = 1;
1655         r.in.lm_cross = &hash6;
1656
1657         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1658         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1659                 "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
1660
1661         /* Unbreak the LM hash */
1662         hash1.hash[0]--;
1663
1664         r.in.user_handle = &user_handle;
1665         r.in.lm_present = 1;
1666         r.in.old_lm_crypted = &hash1;
1667         r.in.new_lm_crypted = &hash2;
1668         /* Break the NT hash */
1669         hash3.hash[0]--;
1670         r.in.nt_present = 1;
1671         r.in.old_nt_crypted = &hash3;
1672         r.in.new_nt_crypted = &hash4;
1673         r.in.cross1_present = 1;
1674         r.in.nt_cross = &hash5;
1675         r.in.cross2_present = 1;
1676         r.in.lm_cross = &hash6;
1677
1678         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1679         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_WRONG_PASSWORD,
1680                 "expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash");
1681
1682         /* Unbreak the NT hash */
1683         hash3.hash[0]--;
1684
1685         r.in.user_handle = &user_handle;
1686         r.in.lm_present = 1;
1687         r.in.old_lm_crypted = &hash1;
1688         r.in.new_lm_crypted = &hash2;
1689         r.in.nt_present = 1;
1690         r.in.old_nt_crypted = &hash3;
1691         r.in.new_nt_crypted = &hash4;
1692         r.in.cross1_present = 1;
1693         r.in.nt_cross = &hash5;
1694         r.in.cross2_present = 1;
1695         /* Break the LM cross */
1696         hash6.hash[0]++;
1697         r.in.lm_cross = &hash6;
1698
1699         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1700         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1701                 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1702                 ret = false;
1703         }
1704
1705         /* Unbreak the LM cross */
1706         hash6.hash[0]--;
1707
1708         r.in.user_handle = &user_handle;
1709         r.in.lm_present = 1;
1710         r.in.old_lm_crypted = &hash1;
1711         r.in.new_lm_crypted = &hash2;
1712         r.in.nt_present = 1;
1713         r.in.old_nt_crypted = &hash3;
1714         r.in.new_nt_crypted = &hash4;
1715         r.in.cross1_present = 1;
1716         /* Break the NT cross */
1717         hash5.hash[0]++;
1718         r.in.nt_cross = &hash5;
1719         r.in.cross2_present = 1;
1720         r.in.lm_cross = &hash6;
1721
1722         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1723         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1724                 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1725                 ret = false;
1726         }
1727
1728         /* Unbreak the NT cross */
1729         hash5.hash[0]--;
1730
1731
1732         /* Reset the hashes to not broken values */
1733         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1734         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1735         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1736         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1737         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1738         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1739
1740         r.in.user_handle = &user_handle;
1741         r.in.lm_present = 1;
1742         r.in.old_lm_crypted = &hash1;
1743         r.in.new_lm_crypted = &hash2;
1744         r.in.nt_present = 1;
1745         r.in.old_nt_crypted = &hash3;
1746         r.in.new_nt_crypted = &hash4;
1747         r.in.cross1_present = 1;
1748         r.in.nt_cross = &hash5;
1749         r.in.cross2_present = 0;
1750         r.in.lm_cross = NULL;
1751
1752         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1753         if (NT_STATUS_IS_OK(status)) {
1754                 changed = true;
1755                 *password = newpass;
1756         } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1757                 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1758                 ret = false;
1759         }
1760
1761         oldpass = newpass;
1762         newpass = samr_rand_pass(tctx, policy_min_pw_len);
1763
1764         E_md4hash(oldpass, old_nt_hash);
1765         E_md4hash(newpass, new_nt_hash);
1766         E_deshash(oldpass, old_lm_hash);
1767         E_deshash(newpass, new_lm_hash);
1768
1769
1770         /* Reset the hashes to not broken values */
1771         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1772         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1773         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1774         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1775         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1776         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1777
1778         r.in.user_handle = &user_handle;
1779         r.in.lm_present = 1;
1780         r.in.old_lm_crypted = &hash1;
1781         r.in.new_lm_crypted = &hash2;
1782         r.in.nt_present = 1;
1783         r.in.old_nt_crypted = &hash3;
1784         r.in.new_nt_crypted = &hash4;
1785         r.in.cross1_present = 0;
1786         r.in.nt_cross = NULL;
1787         r.in.cross2_present = 1;
1788         r.in.lm_cross = &hash6;
1789
1790         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1791         if (NT_STATUS_IS_OK(status)) {
1792                 changed = true;
1793                 *password = newpass;
1794         } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1795                 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1796                 ret = false;
1797         }
1798
1799         oldpass = newpass;
1800         newpass = samr_rand_pass(tctx, policy_min_pw_len);
1801
1802         E_md4hash(oldpass, old_nt_hash);
1803         E_md4hash(newpass, new_nt_hash);
1804         E_deshash(oldpass, old_lm_hash);
1805         E_deshash(newpass, new_lm_hash);
1806
1807
1808         /* Reset the hashes to not broken values */
1809         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1810         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1811         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1812         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1813         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1814         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1815
1816         r.in.user_handle = &user_handle;
1817         r.in.lm_present = 1;
1818         r.in.old_lm_crypted = &hash1;
1819         r.in.new_lm_crypted = &hash2;
1820         r.in.nt_present = 1;
1821         r.in.old_nt_crypted = &hash3;
1822         r.in.new_nt_crypted = &hash4;
1823         r.in.cross1_present = 1;
1824         r.in.nt_cross = &hash5;
1825         r.in.cross2_present = 1;
1826         r.in.lm_cross = &hash6;
1827
1828         status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1829         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1830                 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1831         } else  if (!NT_STATUS_IS_OK(status)) {
1832                 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1833                 ret = false;
1834         } else {
1835                 changed = true;
1836                 *password = newpass;
1837         }
1838
1839         r.in.user_handle = &user_handle;
1840         r.in.lm_present = 1;
1841         r.in.old_lm_crypted = &hash1;
1842         r.in.new_lm_crypted = &hash2;
1843         r.in.nt_present = 1;
1844         r.in.old_nt_crypted = &hash3;
1845         r.in.new_nt_crypted = &hash4;
1846         r.in.cross1_present = 1;
1847         r.in.nt_cross = &hash5;
1848         r.in.cross2_present = 1;
1849         r.in.lm_cross = &hash6;
1850
1851         if (changed) {
1852                 status = dcerpc_samr_ChangePasswordUser(p, tctx, &r);
1853                 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1854                         printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1855                 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1856                         printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1857                         ret = false;
1858                 }
1859         }
1860
1861
1862         if (!test_samr_handle_Close(p, tctx, &user_handle)) {
1863                 ret = false;
1864         }
1865
1866         return ret;
1867 }
1868
1869
1870 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
1871                                         const char *acct_name,
1872                                         struct policy_handle *handle, char **password)
1873 {
1874         NTSTATUS status;
1875         struct samr_OemChangePasswordUser2 r;
1876         bool ret = true;
1877         struct samr_Password lm_verifier;
1878         struct samr_CryptPassword lm_pass;
1879         struct lsa_AsciiString server, account, account_bad;
1880         char *oldpass;
1881         char *newpass;
1882         uint8_t old_lm_hash[16], new_lm_hash[16];
1883
1884         struct samr_GetDomPwInfo dom_pw_info;
1885         struct samr_PwInfo info;
1886         int policy_min_pw_len = 0;
1887
1888         struct lsa_String domain_name;
1889
1890         domain_name.string = "";
1891         dom_pw_info.in.domain_name = &domain_name;
1892         dom_pw_info.out.info = &info;
1893
1894         torture_comment(tctx, "Testing OemChangePasswordUser2\n");
1895
1896         torture_assert(tctx, *password != NULL,
1897                                    "Failing OemChangePasswordUser2 as old password was NULL.  Previous test failed?");
1898
1899         oldpass = *password;
1900
1901         status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
1902         if (NT_STATUS_IS_OK(status)) {
1903                 policy_min_pw_len = dom_pw_info.out.info->min_password_length;
1904         }
1905
1906         newpass = samr_rand_pass(tctx, policy_min_pw_len);
1907
1908         server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1909         account.string = acct_name;
1910
1911         E_deshash(oldpass, old_lm_hash);
1912         E_deshash(newpass, new_lm_hash);
1913
1914         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1915         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1916         E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1917
1918         r.in.server = &server;
1919         r.in.account = &account;
1920         r.in.password = &lm_pass;
1921         r.in.hash = &lm_verifier;
1922
1923         /* Break the verification */
1924         lm_verifier.hash[0]++;
1925
1926         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1927
1928         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1929             && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1930                 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1931                         nt_errstr(status));
1932                 ret = false;
1933         }
1934
1935         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1936         /* Break the old password */
1937         old_lm_hash[0]++;
1938         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1939         /* unbreak it for the next operation */
1940         old_lm_hash[0]--;
1941         E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1942
1943         r.in.server = &server;
1944         r.in.account = &account;
1945         r.in.password = &lm_pass;
1946         r.in.hash = &lm_verifier;
1947
1948         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1949
1950         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1951             && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1952                 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1953                         nt_errstr(status));
1954                 ret = false;
1955         }
1956
1957         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1958         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1959
1960         r.in.server = &server;
1961         r.in.account = &account;
1962         r.in.password = &lm_pass;
1963         r.in.hash = NULL;
1964
1965         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1966
1967         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1968             && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1969                 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1970                         nt_errstr(status));
1971                 ret = false;
1972         }
1973
1974         /* This shouldn't be a valid name */
1975         account_bad.string = TEST_ACCOUNT_NAME "XX";
1976         r.in.account = &account_bad;
1977
1978         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1979
1980         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1981                 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1982                         nt_errstr(status));
1983                 ret = false;
1984         }
1985
1986         /* This shouldn't be a valid name */
1987         account_bad.string = TEST_ACCOUNT_NAME "XX";
1988         r.in.account = &account_bad;
1989         r.in.password = &lm_pass;
1990         r.in.hash = &lm_verifier;
1991
1992         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
1993
1994         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1995                 printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1996                         nt_errstr(status));
1997                 ret = false;
1998         }
1999
2000         /* This shouldn't be a valid name */
2001         account_bad.string = TEST_ACCOUNT_NAME "XX";
2002         r.in.account = &account_bad;
2003         r.in.password = NULL;
2004         r.in.hash = &lm_verifier;
2005
2006         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
2007
2008         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
2009                 printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
2010                         nt_errstr(status));
2011                 ret = false;
2012         }
2013
2014         E_deshash(oldpass, old_lm_hash);
2015         E_deshash(newpass, new_lm_hash);
2016
2017         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
2018         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2019         E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
2020
2021         r.in.server = &server;
2022         r.in.account = &account;
2023         r.in.password = &lm_pass;
2024         r.in.hash = &lm_verifier;
2025
2026         status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r);
2027         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2028                 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
2029         } else if (!NT_STATUS_IS_OK(status)) {
2030                 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
2031                 ret = false;
2032         } else {
2033                 *password = newpass;
2034         }
2035
2036         return ret;
2037 }
2038
2039
2040 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
2041                                      const char *acct_name,
2042                                      char **password,
2043                                      char *newpass, bool allow_password_restriction)
2044 {
2045         NTSTATUS status;
2046         struct samr_ChangePasswordUser2 r;
2047         bool ret = true;
2048         struct lsa_String server, account;
2049         struct samr_CryptPassword nt_pass, lm_pass;
2050         struct samr_Password nt_verifier, lm_verifier;
2051         char *oldpass;
2052         uint8_t old_nt_hash[16], new_nt_hash[16];
2053         uint8_t old_lm_hash[16], new_lm_hash[16];
2054
2055         struct samr_GetDomPwInfo dom_pw_info;
2056         struct samr_PwInfo info;
2057
2058         struct lsa_String domain_name;
2059
2060         domain_name.string = "";
2061         dom_pw_info.in.domain_name = &domain_name;
2062         dom_pw_info.out.info = &info;
2063
2064         torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
2065
2066         torture_assert(tctx, *password != NULL,
2067                                    "Failing ChangePasswordUser2 as old password was NULL.  Previous test failed?");
2068         oldpass = *password;
2069
2070         if (!newpass) {
2071                 int policy_min_pw_len = 0;
2072                 status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
2073                 if (NT_STATUS_IS_OK(status)) {
2074                         policy_min_pw_len = dom_pw_info.out.info->min_password_length;
2075                 }
2076
2077                 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2078         }
2079
2080         server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2081         init_lsa_String(&account, acct_name);
2082
2083         E_md4hash(oldpass, old_nt_hash);
2084         E_md4hash(newpass, new_nt_hash);
2085
2086         E_deshash(oldpass, old_lm_hash);
2087         E_deshash(newpass, new_lm_hash);
2088
2089         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
2090         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
2091         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2092
2093         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2094         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2095         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2096
2097         r.in.server = &server;
2098         r.in.account = &account;
2099         r.in.nt_password = &nt_pass;
2100         r.in.nt_verifier = &nt_verifier;
2101         r.in.lm_change = 1;
2102         r.in.lm_password = &lm_pass;
2103         r.in.lm_verifier = &lm_verifier;
2104
2105         status = dcerpc_samr_ChangePasswordUser2(p, tctx, &r);
2106         if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2107                 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
2108         } else if (!NT_STATUS_IS_OK(status)) {
2109                 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
2110                 ret = false;
2111         } else {
2112                 *password = newpass;
2113         }
2114
2115         return ret;
2116 }
2117
2118
2119 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tctx,
2120                               const char *account_string,
2121                               int policy_min_pw_len,
2122                               char **password,
2123                               const char *newpass,
2124                               NTTIME last_password_change,
2125                               bool handle_reject_reason)
2126 {
2127         NTSTATUS status;
2128         struct samr_ChangePasswordUser3 r;
2129         bool ret = true;
2130         struct lsa_String server, account, account_bad;
2131         struct samr_CryptPassword nt_pass, lm_pass;
2132         struct samr_Password nt_verifier, lm_verifier;
2133         char *oldpass;
2134         uint8_t old_nt_hash[16], new_nt_hash[16];
2135         uint8_t old_lm_hash[16], new_lm_hash[16];
2136         NTTIME t;
2137         struct samr_DomInfo1 *dominfo = NULL;
2138         struct samr_ChangeReject *reject = NULL;
2139
2140         torture_comment(tctx, "Testing ChangePasswordUser3\n");
2141
2142         if (newpass == NULL) {
2143                 do {
2144                         if (policy_min_pw_len == 0) {
2145                                 newpass = samr_rand_pass(tctx, policy_min_pw_len);
2146                         } else {
2147                                 newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len);
2148                         }
2149                 } while (check_password_quality(newpass) == false);
2150         } else {
2151                 torture_comment(tctx, "Using password '%s'\n", newpass);
2152         }
2153
2154         torture_assert(tctx, *password != NULL,
2155                                    "Failing ChangePasswordUser3 as old password was NULL.  Previous test failed?");
2156
2157         oldpass = *password;
2158         server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2159         init_lsa_String(&account, account_string);
2160
2161         E_md4hash(oldpass, old_nt_hash);
2162         E_md4hash(newpass, new_nt_hash);
2163
2164         E_deshash(oldpass, old_lm_hash);
2165         E_deshash(newpass, new_lm_hash);
2166
2167         encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2168         arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2169         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2170
2171         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2172         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2173         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2174
2175         /* Break the verification */
2176         nt_verifier.hash[0]++;
2177
2178         r.in.server = &server;
2179         r.in.account = &account;
2180         r.in.nt_password = &nt_pass;
2181         r.in.nt_verifier = &nt_verifier;
2182         r.in.lm_change = 1;
2183         r.in.lm_password = &lm_pass;
2184         r.in.lm_verifier = &lm_verifier;
2185         r.in.password3 = NULL;
2186         r.out.dominfo = &dominfo;
2187         r.out.reject = &reject;
2188
2189         status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2190         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2191             (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2192                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
2193                         nt_errstr(status));
2194                 ret = false;
2195         }
2196
2197         encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2198         arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2199         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2200
2201         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2202         /* Break the NT hash */
2203         old_nt_hash[0]++;
2204         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2205         /* Unbreak it again */
2206         old_nt_hash[0]--;
2207         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2208
2209         r.in.server = &server;
2210         r.in.account = &account;
2211         r.in.nt_password = &nt_pass;
2212         r.in.nt_verifier = &nt_verifier;
2213         r.in.lm_change = 1;
2214         r.in.lm_password = &lm_pass;
2215         r.in.lm_verifier = &lm_verifier;
2216         r.in.password3 = NULL;
2217         r.out.dominfo = &dominfo;
2218         r.out.reject = &reject;
2219
2220         status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2221         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
2222             (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
2223                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
2224                         nt_errstr(status));
2225                 ret = false;
2226         }
2227
2228         /* This shouldn't be a valid name */
2229         init_lsa_String(&account_bad, talloc_asprintf(tctx, "%sXX", account_string));
2230
2231         r.in.account = &account_bad;
2232         status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2233         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
2234                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
2235                         nt_errstr(status));
2236                 ret = false;
2237         }
2238
2239         E_md4hash(oldpass, old_nt_hash);
2240         E_md4hash(newpass, new_nt_hash);
2241
2242         E_deshash(oldpass, old_lm_hash);
2243         E_deshash(newpass, new_lm_hash);
2244
2245         encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
2246         arcfour_crypt(lm_pass.data, old_nt_hash, 516);
2247         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
2248
2249         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2250         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2251         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2252
2253         r.in.server = &server;
2254         r.in.account = &account;
2255         r.in.nt_password = &nt_pass;
2256         r.in.nt_verifier = &nt_verifier;
2257         r.in.lm_change = 1;
2258         r.in.lm_password = &lm_pass;
2259         r.in.lm_verifier = &lm_verifier;
2260         r.in.password3 = NULL;
2261         r.out.dominfo = &dominfo;
2262         r.out.reject = &reject;
2263
2264         unix_to_nt_time(&t, time(NULL));
2265
2266         status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2267
2268         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
2269             && dominfo
2270             && reject
2271             && handle_reject_reason
2272             && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
2273                 if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
2274
2275                         if (reject && (reject->reason != SAMR_REJECT_OTHER)) {
2276                                 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2277                                         SAMR_REJECT_OTHER, reject->reason);
2278                                 return false;
2279                         }
2280                 }
2281
2282                 /* We tested the order of precendence which is as follows:
2283
2284                 * pwd min_age
2285                 * pwd length
2286                 * pwd complexity
2287                 * pwd history
2288
2289                 Guenther */
2290
2291                 if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
2292                            (last_password_change + dominfo->min_password_age > t)) {
2293
2294                         if (reject->reason != SAMR_REJECT_OTHER) {
2295                                 printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2296                                         SAMR_REJECT_OTHER, reject->reason);
2297                                 return false;
2298                         }
2299
2300                 } else if ((dominfo->min_password_length > 0) &&
2301                            (strlen(newpass) < dominfo->min_password_length)) {
2302
2303                         if (reject->reason != SAMR_REJECT_TOO_SHORT) {
2304                                 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
2305                                         SAMR_REJECT_TOO_SHORT, reject->reason);
2306                                 return false;
2307                         }
2308
2309                 } else if ((dominfo->password_history_length > 0) &&
2310                             strequal(oldpass, newpass)) {
2311
2312                         if (reject->reason != SAMR_REJECT_IN_HISTORY) {
2313                                 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
2314                                         SAMR_REJECT_IN_HISTORY, reject->reason);
2315                                 return false;
2316                         }
2317                 } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
2318
2319                         if (reject->reason != SAMR_REJECT_COMPLEXITY) {
2320                                 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
2321                                         SAMR_REJECT_COMPLEXITY, reject->reason);
2322                                 return false;
2323                         }
2324
2325                 }
2326
2327                 if (reject->reason == SAMR_REJECT_TOO_SHORT) {
2328                         /* retry with adjusted size */
2329                         return test_ChangePasswordUser3(p, tctx, account_string,
2330                                                         dominfo->min_password_length,
2331                                                         password, NULL, 0, false);
2332
2333                 }
2334
2335         } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2336                 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2337                         printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2338                                SAMR_REJECT_OTHER, reject->reason);
2339                         return false;
2340                 }
2341                 /* Perhaps the server has a 'min password age' set? */
2342
2343         } else {
2344                 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3");
2345                 *password = talloc_strdup(tctx, newpass);
2346         }
2347
2348         return ret;
2349 }
2350
2351 bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_context *tctx,
2352                                     const char *account_string,
2353                                     struct policy_handle *handle,
2354                                     char **password)
2355 {
2356         NTSTATUS status;
2357         struct samr_ChangePasswordUser3 r;
2358         struct samr_SetUserInfo s;
2359         union samr_UserInfo u;
2360         DATA_BLOB session_key;
2361         DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
2362         uint8_t confounder[16];
2363         struct MD5Context ctx;
2364
2365         bool ret = true;
2366         struct lsa_String server, account;
2367         struct samr_CryptPassword nt_pass;
2368         struct samr_Password nt_verifier;
2369         DATA_BLOB new_random_pass;
2370         char *newpass;
2371         char *oldpass;
2372         uint8_t old_nt_hash[16], new_nt_hash[16];
2373         NTTIME t;
2374         struct samr_DomInfo1 *dominfo = NULL;
2375         struct samr_ChangeReject *reject = NULL;
2376
2377         new_random_pass = samr_very_rand_pass(tctx, 128);
2378
2379         torture_assert(tctx, *password != NULL,
2380                                    "Failing ChangePasswordUser3 as old password was NULL.  Previous test failed?");
2381
2382         oldpass = *password;
2383         server.string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2384         init_lsa_String(&account, account_string);
2385
2386         s.in.user_handle = handle;
2387         s.in.info = &u;
2388         s.in.level = 25;
2389
2390         ZERO_STRUCT(u);
2391
2392         u.info25.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT;
2393
2394         set_pw_in_buffer(u.info25.password.data, &new_random_pass);
2395
2396         status = dcerpc_fetch_session_key(p, &session_key);
2397         if (!NT_STATUS_IS_OK(status)) {
2398                 printf("SetUserInfo level %u - no session key - %s\n",
2399                        s.in.level, nt_errstr(status));
2400                 return false;
2401         }
2402
2403         generate_random_buffer((uint8_t *)confounder, 16);
2404
2405         MD5Init(&ctx);
2406         MD5Update(&ctx, confounder, 16);
2407         MD5Update(&ctx, session_key.data, session_key.length);
2408         MD5Final(confounded_session_key.data, &ctx);
2409
2410         arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
2411         memcpy(&u.info25.password.data[516], confounder, 16);
2412
2413         torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
2414
2415         status = dcerpc_samr_SetUserInfo(p, tctx, &s);
2416         if (!NT_STATUS_IS_OK(status)) {
2417                 printf("SetUserInfo level %u failed - %s\n",
2418                        s.in.level, nt_errstr(status));
2419                 ret = false;
2420         }
2421
2422         torture_comment(tctx, "Testing ChangePasswordUser3 with a password made up of only random bytes\n");
2423
2424         mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2425
2426         new_random_pass = samr_very_rand_pass(tctx, 128);
2427
2428         mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
2429
2430         set_pw_in_buffer(nt_pass.data, &new_random_pass);
2431         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2432         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2433
2434         r.in.server = &server;
2435         r.in.account = &account;
2436         r.in.nt_password = &nt_pass;
2437         r.in.nt_verifier = &nt_verifier;
2438         r.in.lm_change = 0;
2439         r.in.lm_password = NULL;
2440         r.in.lm_verifier = NULL;
2441         r.in.password3 = NULL;
2442         r.out.dominfo = &dominfo;
2443         r.out.reject = &reject;
2444
2445         unix_to_nt_time(&t, time(NULL));
2446
2447         status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2448
2449         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2450                 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2451                         printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2452                                SAMR_REJECT_OTHER, reject->reason);
2453                         return false;
2454                 }
2455                 /* Perhaps the server has a 'min password age' set? */
2456
2457         } else if (!NT_STATUS_IS_OK(status)) {
2458                 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
2459                 ret = false;
2460         }
2461
2462         newpass = samr_rand_pass(tctx, 128);
2463
2464         mdfour(old_nt_hash, new_random_pass.data, new_random_pass.length);
2465
2466         E_md4hash(newpass, new_nt_hash);
2467
2468         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
2469         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
2470         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
2471
2472         r.in.server = &server;
2473         r.in.account = &account;
2474         r.in.nt_password = &nt_pass;
2475         r.in.nt_verifier = &nt_verifier;
2476         r.in.lm_change = 0;
2477         r.in.lm_password = NULL;
2478         r.in.lm_verifier = NULL;
2479         r.in.password3 = NULL;
2480         r.out.dominfo = &dominfo;
2481         r.out.reject = &reject;
2482
2483         unix_to_nt_time(&t, time(NULL));
2484
2485         status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
2486
2487         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
2488                 if (reject && reject->reason != SAMR_REJECT_OTHER) {
2489                         printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
2490                                SAMR_REJECT_OTHER, reject->reason);
2491                         return false;
2492                 }
2493                 /* Perhaps the server has a 'min password age' set? */
2494
2495         } else {
2496                 torture_assert_ntstatus_ok(tctx, status, "ChangePasswordUser3 (on second random password)");
2497                 *password = talloc_strdup(tctx, newpass);
2498         }
2499
2500         return ret;
2501 }
2502
2503
2504 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2505                                   struct policy_handle *alias_handle)
2506 {
2507         struct samr_GetMembersInAlias r;
2508         struct lsa_SidArray sids;
2509         NTSTATUS status;
2510
2511         torture_comment(tctx, "Testing GetMembersInAlias\n");
2512
2513         r.in.alias_handle = alias_handle;
2514         r.out.sids = &sids;
2515
2516         status = dcerpc_samr_GetMembersInAlias(p, tctx, &r);
2517         torture_assert_ntstatus_ok(tctx, status, "GetMembersInAlias");
2518
2519         return true;
2520 }
2521
2522 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2523                                   struct policy_handle *alias_handle,
2524                                   const struct dom_sid *domain_sid)
2525 {
2526         struct samr_AddAliasMember r;
2527         struct samr_DeleteAliasMember d;
2528         NTSTATUS status;
2529         struct dom_sid *sid;
2530
2531         sid = dom_sid_add_rid(tctx, domain_sid, 512);
2532
2533         torture_comment(tctx, "testing AddAliasMember\n");
2534         r.in.alias_handle = alias_handle;
2535         r.in.sid = sid;
2536
2537         status = dcerpc_samr_AddAliasMember(p, tctx, &r);
2538         torture_assert_ntstatus_ok(tctx, status, "AddAliasMember");
2539
2540         d.in.alias_handle = alias_handle;
2541         d.in.sid = sid;
2542
2543         status = dcerpc_samr_DeleteAliasMember(p, tctx, &d);
2544         torture_assert_ntstatus_ok(tctx, status, "DelAliasMember");
2545
2546         return true;
2547 }
2548
2549 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2550                                            struct policy_handle *alias_handle)
2551 {
2552         struct samr_AddMultipleMembersToAlias a;
2553         struct samr_RemoveMultipleMembersFromAlias r;
2554         NTSTATUS status;
2555         struct lsa_SidArray sids;
2556
2557         torture_comment(tctx, "testing AddMultipleMembersToAlias\n");
2558         a.in.alias_handle = alias_handle;
2559         a.in.sids = &sids;
2560
2561         sids.num_sids = 3;
2562         sids.sids = talloc_array(tctx, struct lsa_SidPtr, 3);
2563
2564         sids.sids[0].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-1");
2565         sids.sids[1].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-2");
2566         sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-3");
2567
2568         status = dcerpc_samr_AddMultipleMembersToAlias(p, tctx, &a);
2569         torture_assert_ntstatus_ok(tctx, status, "AddMultipleMembersToAlias");
2570
2571
2572         torture_comment(tctx, "testing RemoveMultipleMembersFromAlias\n");
2573         r.in.alias_handle = alias_handle;
2574         r.in.sids = &sids;
2575
2576         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2577         torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2578
2579         /* strange! removing twice doesn't give any error */
2580         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2581         torture_assert_ntstatus_ok(tctx, status, "RemoveMultipleMembersFromAlias");
2582
2583         /* but removing an alias that isn't there does */
2584         sids.sids[2].sid = dom_sid_parse_talloc(tctx, "S-1-5-32-1-2-3-4");
2585
2586         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, tctx, &r);
2587         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, "RemoveMultipleMembersFromAlias");
2588
2589         return true;
2590 }
2591
2592 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2593                                             struct policy_handle *user_handle)
2594 {
2595         struct samr_TestPrivateFunctionsUser r;
2596         NTSTATUS status;
2597
2598         torture_comment(tctx, "Testing TestPrivateFunctionsUser\n");
2599
2600         r.in.user_handle = user_handle;
2601
2602         status = dcerpc_samr_TestPrivateFunctionsUser(p, tctx, &r);
2603         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsUser");
2604
2605         return true;
2606 }
2607
2608 static bool test_QueryUserInfo_pwdlastset(struct dcerpc_pipe *p,
2609                                           struct torture_context *tctx,
2610                                           struct policy_handle *handle,
2611                                           bool use_info2,
2612                                           NTTIME *pwdlastset)
2613 {
2614         NTSTATUS status;
2615         uint16_t levels[] = { /* 3, */ 5, 21 };
2616         int i;
2617         NTTIME pwdlastset3 = 0;
2618         NTTIME pwdlastset5 = 0;
2619         NTTIME pwdlastset21 = 0;
2620
2621         torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
2622                         use_info2 ? "2":"");
2623
2624         for (i=0; i<ARRAY_SIZE(levels); i++) {
2625
2626                 struct samr_QueryUserInfo r;
2627                 struct samr_QueryUserInfo2 r2;
2628                 union samr_UserInfo *info;
2629
2630                 if (use_info2) {
2631                         r2.in.user_handle = handle;
2632                         r2.in.level = levels[i];
2633                         r2.out.info = &info;
2634                         status = dcerpc_samr_QueryUserInfo2(p, tctx, &r2);
2635
2636                 } else {
2637                         r.in.user_handle = handle;
2638                         r.in.level = levels[i];
2639                         r.out.info = &info;
2640                         status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
2641                 }
2642
2643                 if (!NT_STATUS_IS_OK(status) &&
2644                     !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2645                         printf("QueryUserInfo%s level %u failed - %s\n",
2646                                use_info2 ? "2":"", levels[i], nt_errstr(status));
2647                         return false;
2648                 }
2649
2650                 switch (levels[i]) {
2651                 case 3:
2652                         pwdlastset3 = info->info3.last_password_change;
2653                         break;
2654                 case 5:
2655                         pwdlastset5 = info->info5.last_password_change;
2656                         break;
2657                 case 21:
2658                         pwdlastset21 = info->info21.last_password_change;
2659                         break;
2660                 default:
2661                         return false;
2662                 }
2663         }
2664         /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
2665                                     "pwdlastset mixup"); */
2666         torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
2667                                  "pwdlastset mixup");
2668
2669         *pwdlastset = pwdlastset21;
2670
2671         torture_comment(tctx, "(pwdlastset: %lld)\n", *pwdlastset);
2672
2673         return true;
2674 }
2675
2676 static bool test_SamLogon(struct torture_context *tctx,
2677                           struct dcerpc_pipe *p,
2678                           struct cli_credentials *test_credentials,
2679                           NTSTATUS expected_result)
2680 {
2681         NTSTATUS status;
2682         struct netr_LogonSamLogonEx r;
2683         union netr_LogonLevel logon;
2684         union netr_Validation validation;
2685         uint8_t authoritative;
2686         struct netr_NetworkInfo ninfo;
2687         DATA_BLOB names_blob, chal, lm_resp, nt_resp;
2688         int flags = CLI_CRED_NTLM_AUTH;
2689         uint32_t samlogon_flags = 0;
2690
2691         if (lp_client_lanman_auth(tctx->lp_ctx)) {
2692                 flags |= CLI_CRED_LANMAN_AUTH;
2693         }
2694
2695         if (lp_client_ntlmv2_auth(tctx->lp_ctx)) {
2696                 flags |= CLI_CRED_NTLMv2_AUTH;
2697         }
2698
2699         cli_credentials_get_ntlm_username_domain(test_credentials, tctx,
2700                                                  &ninfo.identity_info.account_name.string,
2701                                                  &ninfo.identity_info.domain_name.string);
2702
2703         generate_random_buffer(ninfo.challenge,
2704                                sizeof(ninfo.challenge));
2705         chal = data_blob_const(ninfo.challenge,
2706                                sizeof(ninfo.challenge));
2707
2708         names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(test_credentials),
2709                                                 cli_credentials_get_domain(test_credentials));
2710
2711         status = cli_credentials_get_ntlm_response(test_credentials, tctx,
2712                                                    &flags,
2713                                                    chal,
2714                                                    names_blob,
2715                                                    &lm_resp, &nt_resp,
2716                                                    NULL, NULL);
2717         torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
2718
2719         ninfo.lm.data = lm_resp.data;
2720         ninfo.lm.length = lm_resp.length;
2721
2722         ninfo.nt.data = nt_resp.data;
2723         ninfo.nt.length = nt_resp.length;
2724
2725         ninfo.identity_info.parameter_control =
2726                 MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT |
2727                 MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
2728         ninfo.identity_info.logon_id_low = 0;
2729         ninfo.identity_info.logon_id_high = 0;
2730         ninfo.identity_info.workstation.string = cli_credentials_get_workstation(test_credentials);
2731
2732         logon.network = &ninfo;
2733
2734         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2735         r.in.computer_name = cli_credentials_get_workstation(test_credentials);
2736         r.in.logon_level = NetlogonNetworkInformation;
2737         r.in.logon = &logon;
2738         r.in.flags = &samlogon_flags;
2739         r.out.flags = &samlogon_flags;
2740         r.out.validation = &validation;
2741         r.out.authoritative = &authoritative;
2742
2743         d_printf("Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
2744
2745         r.in.validation_level = 6;
2746
2747         status = dcerpc_netr_LogonSamLogonEx(p, tctx, &r);
2748         if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2749                 r.in.validation_level = 3;
2750                 status = dcerpc_netr_LogonSamLogonEx(p, tctx, &r);
2751         }
2752         if (!NT_STATUS_IS_OK(status)) {
2753                 torture_assert_ntstatus_equal(tctx, status, expected_result, "LogonSamLogonEx failed");
2754                 return true;
2755         } else {
2756                 torture_assert_ntstatus_ok(tctx, status, "LogonSamLogonEx failed");
2757         }
2758
2759         return true;
2760 }
2761
2762 static bool test_SamLogon_with_creds(struct torture_context *tctx,
2763                                      struct dcerpc_pipe *p,
2764                                      struct cli_credentials *machine_creds,
2765                                      const char *acct_name,
2766                                      char *password,
2767                                      NTSTATUS expected_samlogon_result)
2768 {
2769         bool ret = true;
2770         struct cli_credentials *test_credentials;
2771
2772         test_credentials = cli_credentials_init(tctx);
2773
2774         cli_credentials_set_workstation(test_credentials,
2775                                         cli_credentials_get_workstation(machine_creds), CRED_SPECIFIED);
2776         cli_credentials_set_domain(test_credentials,
2777                                    cli_credentials_get_domain(machine_creds), CRED_SPECIFIED);
2778         cli_credentials_set_username(test_credentials,
2779                                      acct_name, CRED_SPECIFIED);
2780         cli_credentials_set_password(test_credentials,
2781                                      password, CRED_SPECIFIED);
2782
2783         printf("testing samlogon as %s password: %s\n",
2784                 acct_name, password);
2785
2786         if (!test_SamLogon(tctx, p, test_credentials,
2787                            expected_samlogon_result)) {
2788                 torture_warning(tctx, "new password did not work\n");
2789                 ret = false;
2790         }
2791
2792         return ret;
2793 }
2794
2795 static bool test_SetPassword_level(struct dcerpc_pipe *p,
2796                                    struct dcerpc_pipe *np,
2797                                    struct torture_context *tctx,
2798                                    struct policy_handle *handle,
2799                                    uint16_t level,
2800                                    uint32_t fields_present,
2801                                    uint8_t password_expired,
2802                                    bool *matched_expected_error,
2803                                    bool use_setinfo2,
2804                                    const char *acct_name,
2805                                    char **password,
2806                                    struct cli_credentials *machine_creds,
2807                                    bool use_queryinfo2,
2808                                    NTTIME *pwdlastset,
2809                                    NTSTATUS expected_samlogon_result)
2810 {
2811         const char *fields = NULL;
2812         bool ret = true;
2813
2814         switch (level) {
2815         case 21:
2816         case 23:
2817         case 25:
2818                 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
2819                                          fields_present);
2820                 break;
2821         default:
2822                 break;
2823         }
2824
2825         torture_comment(tctx, "Testing SetUserInfo%s level %d call "
2826                 "(password_expired: %d) %s\n",
2827                 use_setinfo2 ? "2":"", level, password_expired,
2828                 fields ? fields : "");
2829
2830         if (!test_SetUserPass_level_ex(p, tctx, handle, level,
2831                                        fields_present,
2832                                        password,
2833                                        password_expired,
2834                                        use_setinfo2,
2835                                        matched_expected_error)) {
2836                 ret = false;
2837         }
2838
2839         if (!test_QueryUserInfo_pwdlastset(p, tctx, handle,
2840                                            use_queryinfo2,
2841                                            pwdlastset)) {
2842                 ret = false;
2843         }
2844
2845         if (*matched_expected_error == true) {
2846                 return ret;
2847         }
2848
2849         if (!test_SamLogon_with_creds(tctx, np,
2850                                       machine_creds,
2851                                       acct_name,
2852                                       *password,
2853                                       expected_samlogon_result)) {
2854                 ret = false;
2855         }
2856
2857         return ret;
2858 }
2859
2860 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
2861                                         struct torture_context *tctx,
2862                                         uint32_t acct_flags,
2863                                         const char *acct_name,
2864                                         struct policy_handle *handle,
2865                                         char **password,
2866                                         struct cli_credentials *machine_credentials)
2867 {
2868         int s = 0, q = 0, f = 0, l = 0, z = 0;
2869         struct dcerpc_binding *b;
2870         bool ret = true;
2871         int delay = 50000;
2872         bool set_levels[] = { false, true };
2873         bool query_levels[] = { false, true };
2874         uint32_t levels[] = { 18, 21, 26, 23, 24, 25 }; /* Second half only used when TEST_ALL_LEVELS defined */
2875         uint32_t nonzeros[] = { 1, 24 };
2876         uint32_t fields_present[] = {
2877                 0,
2878                 SAMR_FIELD_EXPIRED_FLAG,
2879                 SAMR_FIELD_LAST_PWD_CHANGE,
2880                 SAMR_FIELD_EXPIRED_FLAG | SAMR_FIELD_LAST_PWD_CHANGE,
2881                 SAMR_FIELD_COMMENT,
2882                 SAMR_FIELD_NT_PASSWORD_PRESENT,
2883                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2884                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
2885                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2886                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2887                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2888                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE | SAMR_FIELD_EXPIRED_FLAG
2889         };
2890         NTSTATUS status;
2891         struct dcerpc_pipe *np = NULL;
2892
2893         if (torture_setting_bool(tctx, "samba3", false)) {
2894                 delay = 999999;
2895                 printf("Samba3 has second granularity, setting delay to: %d\n",
2896                         delay);
2897         }
2898
2899         status = torture_rpc_binding(tctx, &b);
2900         if (!NT_STATUS_IS_OK(status)) {
2901                 ret = false;
2902                 return ret;
2903         }
2904
2905         /* We have to use schannel, otherwise the SamLogonEx fails
2906          * with INTERNAL_ERROR */
2907
2908         b->flags &= ~DCERPC_AUTH_OPTIONS;
2909         b->flags |= DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_128;
2910
2911         status = dcerpc_pipe_connect_b(tctx, &np, b,
2912                                        &ndr_table_netlogon,
2913                                        machine_credentials, tctx->ev, tctx->lp_ctx);
2914
2915         if (!NT_STATUS_IS_OK(status)) {
2916                 d_printf("RPC pipe connect as domain member failed: %s\n", nt_errstr(status));
2917                 ret = false;
2918                 return ret;
2919         }
2920
2921         /* set to 1 to enable testing for all possible opcode
2922            (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
2923            combinations */
2924 #if 0
2925 #define TEST_ALL_LEVELS 1
2926 #define TEST_SET_LEVELS 1
2927 #define TEST_QUERY_LEVELS 1
2928 #endif
2929 #ifdef TEST_ALL_LEVELS
2930         for (l=0; l<ARRAY_SIZE(levels); l++) {
2931 #else
2932         for (l=0; l<(ARRAY_SIZE(levels))/2; l++) {
2933 #endif
2934         for (z=0; z<ARRAY_SIZE(nonzeros); z++) {
2935         for (f=0; f<ARRAY_SIZE(fields_present); f++) {
2936 #ifdef TEST_SET_LEVELS
2937         for (s=0; s<ARRAY_SIZE(set_levels); s++) {
2938 #endif
2939 #ifdef TEST_QUERY_LEVELS
2940         for (q=0; q<ARRAY_SIZE(query_levels); q++) {
2941 #endif
2942                 NTTIME pwdlastset_old = 0;
2943                 NTTIME pwdlastset_new = 0;
2944                 bool matched_expected_error = false;
2945                 NTSTATUS expected_samlogon_result = NT_STATUS_ACCOUNT_DISABLED;
2946
2947                 torture_comment(tctx, "------------------------------\n"
2948                                 "Testing pwdLastSet attribute for flags: 0x%08x "
2949                                 "(s: %d (l: %d), q: %d)\n",
2950                                 acct_flags, s, levels[l], q);
2951
2952                 switch (levels[l]) {
2953                 case 21:
2954                 case 23:
2955                 case 25:
2956                         if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2957                               (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT))) {
2958                                 expected_samlogon_result = NT_STATUS_WRONG_PASSWORD;
2959                         }
2960                         break;
2961                 }
2962
2963
2964                 /* set #1 */
2965
2966                 /* set a password and force password change (pwdlastset 0) by
2967                  * setting the password expired flag to a non-0 value */
2968
2969                 if (!test_SetPassword_level(p, np, tctx, handle,
2970                                             levels[l],
2971                                             fields_present[f],
2972                                             nonzeros[z],
2973                                             &matched_expected_error,
2974                                             set_levels[s],
2975                                             acct_name,
2976                                             password,
2977                                             machine_credentials,
2978                                             query_levels[q],
2979                                             &pwdlastset_old,
2980                                             expected_samlogon_result)) {
2981                         ret = false;
2982                 }
2983
2984                 if (matched_expected_error == true) {
2985                         /* skipping on expected failure */
2986                         continue;
2987                 }
2988
2989                 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
2990                  * set without the SAMR_FIELD_EXPIRED_FLAG */
2991
2992                 switch (levels[l]) {
2993                 case 21:
2994                 case 23:
2995                 case 25:
2996                         if ((pwdlastset_new != 0) &&
2997                             !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
2998                                 torture_comment(tctx, "not considering a non-0 "
2999                                         "pwdLastSet as a an error as the "
3000                                         "SAMR_FIELD_EXPIRED_FLAG has not "
3001                                         "been set\n");
3002                                 break;
3003                         }
3004                 default:
3005                         if (pwdlastset_new != 0) {
3006                                 torture_warning(tctx, "pwdLastSet test failed: "
3007                                         "expected pwdLastSet 0 but got %lld\n",
3008                                         pwdlastset_old);
3009                                 ret = false;
3010                         }
3011                         break;
3012                 }
3013
3014                 switch (levels[l]) {
3015                 case 21:
3016                 case 23:
3017                 case 25:
3018                         if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3019                              (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3020                              (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3021                              (pwdlastset_old >= pwdlastset_new)) {
3022                                 torture_warning(tctx, "pwdlastset not increasing\n");
3023                                 ret = false;
3024                         }
3025                         break;
3026                 default:
3027                         if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3028                             (pwdlastset_old >= pwdlastset_new)) {
3029                                 torture_warning(tctx, "pwdlastset not increasing\n");
3030                                 ret = false;
3031                         }
3032                         break;
3033                 }
3034
3035                 usleep(delay);
3036
3037                 /* set #2 */
3038
3039                 /* set a password, pwdlastset needs to get updated (increased
3040                  * value), password_expired value used here is 0 */
3041
3042                 if (!test_SetPassword_level(p, np, tctx, handle,
3043                                             levels[l],
3044                                             fields_present[f],
3045                                             0,
3046                                             &matched_expected_error,
3047                                             set_levels[s],
3048                                             acct_name,
3049                                             password,
3050                                             machine_credentials,
3051                                             query_levels[q],
3052                                             &pwdlastset_new,
3053                                             expected_samlogon_result)) {
3054                         ret = false;
3055                 }
3056
3057                 /* when a password has been changed, pwdlastset must not be 0 afterwards
3058                  * and must be larger then the old value */
3059
3060                 switch (levels[l]) {
3061                 case 21:
3062                 case 23:
3063                 case 25:
3064
3065                         /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3066                          * password has been changed, old and new pwdlastset
3067                          * need to be the same value */
3068
3069                         if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3070                             !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3071                               (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3072                         {
3073                                 torture_assert_int_equal(tctx, pwdlastset_old,
3074                                         pwdlastset_new, "pwdlastset must be equal");
3075                                 break;
3076                         }
3077                 default:
3078                         if (pwdlastset_old >= pwdlastset_new) {
3079                                 torture_warning(tctx, "pwdLastSet test failed: "
3080                                         "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3081                                         pwdlastset_old, pwdlastset_new);
3082                                 ret = false;
3083                         }
3084                         if (pwdlastset_new == 0) {
3085                                 torture_warning(tctx, "pwdLastSet test failed: "
3086                                         "expected non-0 pwdlastset, got: %lld\n",
3087                                         pwdlastset_new);
3088                                 ret = false;
3089                         }
3090                 }
3091
3092                 switch (levels[l]) {
3093                 case 21:
3094                 case 23:
3095                 case 25:
3096                         if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3097                              (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3098                              (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3099                              (pwdlastset_old >= pwdlastset_new)) {
3100                                 torture_warning(tctx, "pwdlastset not increasing\n");
3101                                 ret = false;
3102                         }
3103                         break;
3104                 default:
3105                         if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3106                             (pwdlastset_old >= pwdlastset_new)) {
3107                                 torture_warning(tctx, "pwdlastset not increasing\n");
3108                                 ret = false;
3109                         }
3110                         break;
3111                 }
3112
3113                 pwdlastset_old = pwdlastset_new;
3114
3115                 usleep(delay);
3116
3117                 /* set #2b */
3118
3119                 /* set a password, pwdlastset needs to get updated (increased
3120                  * value), password_expired value used here is 0 */
3121
3122                 if (!test_SetPassword_level(p, np, tctx, handle,
3123                                             levels[l],
3124                                             fields_present[f],
3125                                             0,
3126                                             &matched_expected_error,
3127                                             set_levels[s],
3128                                             acct_name,
3129                                             password,
3130                                             machine_credentials,
3131                                             query_levels[q],
3132                                             &pwdlastset_new,
3133                                             expected_samlogon_result)) {
3134                         ret = false;
3135                 }
3136
3137                 /* when a password has been changed, pwdlastset must not be 0 afterwards
3138                  * and must be larger then the old value */
3139
3140                 switch (levels[l]) {
3141                 case 21:
3142                 case 23:
3143                 case 25:
3144
3145                         /* if no password has been changed, old and new pwdlastset
3146                          * need to be the same value */
3147
3148                         if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3149                               (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3150                         {
3151                                 torture_assert_int_equal(tctx, pwdlastset_old,
3152                                         pwdlastset_new, "pwdlastset must be equal");
3153                                 break;
3154                         }
3155                 default:
3156                         if (pwdlastset_old >= pwdlastset_new) {
3157                                 torture_warning(tctx, "pwdLastSet test failed: "
3158                                         "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3159                                         pwdlastset_old, pwdlastset_new);
3160                                 ret = false;
3161                         }
3162                         if (pwdlastset_new == 0) {
3163                                 torture_warning(tctx, "pwdLastSet test failed: "
3164                                         "expected non-0 pwdlastset, got: %lld\n",
3165                                         pwdlastset_new);
3166                                 ret = false;
3167                         }
3168                 }
3169
3170                 /* set #3 */
3171
3172                 /* set a password and force password change (pwdlastset 0) by
3173                  * setting the password expired flag to a non-0 value */
3174
3175                 if (!test_SetPassword_level(p, np, tctx, handle,
3176                                             levels[l],
3177                                             fields_present[f],
3178                                             nonzeros[z],
3179                                             &matched_expected_error,
3180                                             set_levels[s],
3181                                             acct_name,
3182                                             password,
3183                                             machine_credentials,
3184                                             query_levels[q],
3185                                             &pwdlastset_new,
3186                                             expected_samlogon_result)) {
3187                         ret = false;
3188                 }
3189
3190                 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3191                  * set without the SAMR_FIELD_EXPIRED_FLAG */
3192
3193                 switch (levels[l]) {
3194                 case 21:
3195                 case 23:
3196                 case 25:
3197                         if ((pwdlastset_new != 0) &&
3198                             !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3199                                 torture_comment(tctx, "not considering a non-0 "
3200                                         "pwdLastSet as a an error as the "
3201                                         "SAMR_FIELD_EXPIRED_FLAG has not "
3202                                         "been set\n");
3203                                 break;
3204                         }
3205
3206                         /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3207                          * password has been changed, old and new pwdlastset
3208                          * need to be the same value */
3209
3210                         if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3211                             !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3212                               (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3213                         {
3214                                 torture_assert_int_equal(tctx, pwdlastset_old,
3215                                         pwdlastset_new, "pwdlastset must be equal");
3216                                 break;
3217                         }
3218                 default:
3219
3220                         if (pwdlastset_old == pwdlastset_new) {
3221                                 torture_warning(tctx, "pwdLastSet test failed: "
3222                                         "expected last pwdlastset (%lld) != new pwdlastset (%lld)\n",
3223                                         pwdlastset_old, pwdlastset_new);
3224                                 ret = false;
3225                         }
3226
3227                         if (pwdlastset_new != 0) {
3228                                 torture_warning(tctx, "pwdLastSet test failed: "
3229                                         "expected pwdLastSet 0, got %lld\n",
3230                                         pwdlastset_old);
3231                                 ret = false;
3232                         }
3233                         break;
3234                 }
3235
3236                 switch (levels[l]) {
3237                 case 21:
3238                 case 23:
3239                 case 25:
3240                         if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3241                              (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3242                              (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3243                              (pwdlastset_old >= pwdlastset_new)) {
3244                                 torture_warning(tctx, "pwdlastset not increasing\n");
3245                                 ret = false;
3246                         }
3247                         break;
3248                 default:
3249                         if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3250                             (pwdlastset_old >= pwdlastset_new)) {
3251                                 torture_warning(tctx, "pwdlastset not increasing\n");
3252                                 ret = false;
3253                         }
3254                         break;
3255                 }
3256
3257                 /* if the level we are testing does not have a fields_present
3258                  * field, skip all fields present tests by setting f to to
3259                  * arraysize */
3260                 switch (levels[l]) {
3261                 case 18:
3262                 case 24:
3263                 case 26:
3264                         f = ARRAY_SIZE(fields_present);
3265                         break;
3266                 }
3267
3268 #ifdef TEST_QUERY_LEVELS
3269         }
3270 #endif
3271 #ifdef TEST_SET_LEVELS
3272         }
3273 #endif
3274         } /* fields present */
3275         } /* nonzeros */
3276         } /* levels */
3277
3278 #undef TEST_SET_LEVELS
3279 #undef TEST_QUERY_LEVELS
3280
3281         return ret;
3282 }
3283
3284 static bool test_DeleteUser_with_privs(struct dcerpc_pipe *p,
3285                                        struct dcerpc_pipe *lp,
3286                                        struct torture_context *tctx,
3287                                        struct policy_handle *domain_handle,
3288                                        struct policy_handle *lsa_handle,
3289                                        struct policy_handle *user_handle,
3290                                        const struct dom_sid *domain_sid,
3291                                        uint32_t rid,
3292                                        struct cli_credentials *machine_credentials)
3293 {
3294         NTSTATUS status;
3295         bool ret = true;
3296
3297         struct policy_handle lsa_acct_handle;
3298         struct dom_sid *user_sid;
3299
3300         user_sid = dom_sid_add_rid(tctx, domain_sid, rid);
3301
3302         {
3303                 struct lsa_EnumAccountRights r;
3304                 struct lsa_RightSet rights;
3305
3306                 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
3307
3308                 r.in.handle = lsa_handle;
3309                 r.in.sid = user_sid;
3310                 r.out.rights = &rights;
3311
3312                 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3313                 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3314                         "Expected enum rights for account to fail");
3315         }
3316
3317         {
3318                 struct lsa_RightSet rights;
3319                 struct lsa_StringLarge names[2];
3320                 struct lsa_AddAccountRights r;
3321
3322                 torture_comment(tctx, "Testing LSA AddAccountRights\n");
3323
3324                 init_lsa_StringLarge(&names[0], "SeMachineAccountPrivilege");
3325                 init_lsa_StringLarge(&names[1], NULL);
3326
3327                 rights.count = 1;
3328                 rights.names = names;
3329
3330                 r.in.handle = lsa_handle;
3331                 r.in.sid = user_sid;
3332                 r.in.rights = &rights;
3333
3334                 status = dcerpc_lsa_AddAccountRights(lp, tctx, &r);
3335                 torture_assert_ntstatus_ok(tctx, status,
3336                         "Failed to add privileges");
3337         }
3338
3339         {
3340                 struct lsa_EnumAccounts r;
3341                 uint32_t resume_handle = 0;
3342                 struct lsa_SidArray lsa_sid_array;
3343                 int i;
3344                 bool found_sid = false;
3345
3346                 torture_comment(tctx, "Testing LSA EnumAccounts\n");
3347
3348                 r.in.handle = lsa_handle;
3349                 r.in.num_entries = 0x1000;
3350                 r.in.resume_handle = &resume_handle;
3351                 r.out.sids = &lsa_sid_array;
3352                 r.out.resume_handle = &resume_handle;
3353
3354                 status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
3355                 torture_assert_ntstatus_ok(tctx, status,
3356                         "Failed to enum accounts");
3357
3358                 for (i=0; i < lsa_sid_array.num_sids; i++) {
3359                         if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
3360                                 found_sid = true;
3361                         }
3362                 }
3363
3364                 torture_assert(tctx, found_sid,
3365                         "failed to list privileged account");
3366         }
3367
3368         {
3369                 struct lsa_EnumAccountRights r;
3370                 struct lsa_RightSet user_rights;
3371
3372                 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
3373
3374                 r.in.handle = lsa_handle;
3375                 r.in.sid = user_sid;
3376                 r.out.rights = &user_rights;
3377
3378                 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3379                 torture_assert_ntstatus_ok(tctx, status,
3380                         "Failed to enum rights for account");
3381
3382                 if (user_rights.count < 1) {
3383                         torture_warning(tctx, "failed to find newly added rights");
3384                         return false;
3385                 }
3386         }
3387
3388         {
3389                 struct lsa_OpenAccount r;
3390
3391                 torture_comment(tctx, "Testing LSA OpenAccount\n");
3392
3393                 r.in.handle = lsa_handle;
3394                 r.in.sid = user_sid;
3395                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3396                 r.out.acct_handle = &lsa_acct_handle;
3397
3398                 status = dcerpc_lsa_OpenAccount(lp, tctx, &r);
3399                 torture_assert_ntstatus_ok(tctx, status,
3400                         "Failed to open lsa account");
3401         }
3402
3403         {
3404                 struct lsa_GetSystemAccessAccount r;
3405                 uint32_t access_mask;
3406
3407                 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
3408
3409                 r.in.handle = &lsa_acct_handle;
3410                 r.out.access_mask = &access_mask;
3411
3412                 status = dcerpc_lsa_GetSystemAccessAccount(lp, tctx, &r);
3413                 torture_assert_ntstatus_ok(tctx, status,
3414                         "Failed to get lsa system access account");
3415         }
3416
3417         {
3418                 struct lsa_Close r;
3419
3420                 torture_comment(tctx, "Testing LSA Close\n");
3421
3422                 r.in.handle = &lsa_acct_handle;
3423                 r.out.handle = &lsa_acct_handle;
3424
3425                 status = dcerpc_lsa_Close(lp, tctx, &r);
3426                 torture_assert_ntstatus_ok(tctx, status,
3427                         "Failed to close lsa");
3428         }
3429
3430         {
3431                 struct samr_DeleteUser r;
3432
3433                 torture_comment(tctx, "Testing SAMR DeleteUser\n");
3434
3435                 r.in.user_handle = user_handle;
3436                 r.out.user_handle = user_handle;
3437
3438                 status = dcerpc_samr_DeleteUser(p, tctx, &r);
3439                 torture_assert_ntstatus_ok(tctx, status, "Delete User failed");
3440         }
3441
3442         {
3443                 struct lsa_EnumAccounts r;
3444                 uint32_t resume_handle = 0;
3445                 struct lsa_SidArray lsa_sid_array;
3446                 int i;
3447                 bool found_sid = false;
3448
3449                 torture_comment(tctx, "Testing LSA EnumAccounts\n");
3450
3451                 r.in.handle = lsa_handle;
3452                 r.in.num_entries = 0x1000;
3453                 r.in.resume_handle = &resume_handle;
3454                 r.out.sids = &lsa_sid_array;
3455                 r.out.resume_handle = &resume_handle;
3456
3457                 status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
3458                 torture_assert_ntstatus_ok(tctx, status,
3459                         "Failed to enum accounts");
3460
3461                 for (i=0; i < lsa_sid_array.num_sids; i++) {
3462                         if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
3463                                 found_sid = true;
3464                         }
3465                 }
3466
3467                 torture_assert(tctx, found_sid,
3468                         "failed to list privileged account");
3469         }
3470
3471         {
3472                 struct lsa_EnumAccountRights r;
3473                 struct lsa_RightSet user_rights;
3474
3475                 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
3476
3477                 r.in.handle = lsa_handle;
3478                 r.in.sid = user_sid;
3479                 r.out.rights = &user_rights;
3480
3481                 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3482                 torture_assert_ntstatus_ok(tctx, status,
3483                         "Failed to enum rights for account");
3484
3485                 if (user_rights.count < 1) {
3486                         torture_warning(tctx, "failed to find newly added rights");
3487                         return false;
3488                 }
3489         }
3490
3491         {
3492                 struct lsa_OpenAccount r;
3493
3494                 torture_comment(tctx, "Testing LSA OpenAccount\n");
3495
3496                 r.in.handle = lsa_handle;
3497                 r.in.sid = user_sid;
3498                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3499                 r.out.acct_handle = &lsa_acct_handle;
3500
3501                 status = dcerpc_lsa_OpenAccount(lp, tctx, &r);
3502                 torture_assert_ntstatus_ok(tctx, status,
3503                         "Failed to open lsa account");
3504         }
3505
3506         {
3507                 struct lsa_GetSystemAccessAccount r;
3508                 uint32_t access_mask;
3509
3510                 torture_comment(tctx, "Testing LSA GetSystemAccessAccount\n");
3511
3512                 r.in.handle = &lsa_acct_handle;
3513                 r.out.access_mask = &access_mask;
3514
3515                 status = dcerpc_lsa_GetSystemAccessAccount(lp, tctx, &r);
3516                 torture_assert_ntstatus_ok(tctx, status,
3517                         "Failed to get lsa system access account");
3518         }
3519
3520         {
3521                 struct lsa_DeleteObject r;
3522
3523                 torture_comment(tctx, "Testing LSA DeleteObject\n");
3524
3525                 r.in.handle = &lsa_acct_handle;
3526                 r.out.handle = &lsa_acct_handle;
3527
3528                 status = dcerpc_lsa_DeleteObject(lp, tctx, &r);
3529                 torture_assert_ntstatus_ok(tctx, status,
3530                         "Failed to delete object");
3531         }
3532
3533         {
3534                 struct lsa_EnumAccounts r;
3535                 uint32_t resume_handle = 0;
3536                 struct lsa_SidArray lsa_sid_array;
3537                 int i;
3538                 bool found_sid = false;
3539
3540                 torture_comment(tctx, "Testing LSA EnumAccounts\n");
3541
3542                 r.in.handle = lsa_handle;
3543                 r.in.num_entries = 0x1000;
3544                 r.in.resume_handle = &resume_handle;
3545                 r.out.sids = &lsa_sid_array;
3546                 r.out.resume_handle = &resume_handle;
3547
3548                 status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
3549                 torture_assert_ntstatus_ok(tctx, status,
3550                         "Failed to enum accounts");
3551
3552                 for (i=0; i < lsa_sid_array.num_sids; i++) {
3553                         if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
3554                                 found_sid = true;
3555                         }
3556                 }
3557
3558                 torture_assert(tctx, !found_sid,
3559                         "should not have listed privileged account");
3560         }
3561
3562         {
3563                 struct lsa_EnumAccountRights r;
3564                 struct lsa_RightSet user_rights;
3565
3566                 torture_comment(tctx, "Testing LSA EnumAccountRights\n");
3567
3568                 r.in.handle = lsa_handle;
3569                 r.in.sid = user_sid;
3570                 r.out.rights = &user_rights;
3571
3572                 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3573                 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3574                         "Failed to enum rights for account");
3575         }
3576
3577         return ret;
3578 }
3579
3580 static bool test_user_ops(struct dcerpc_pipe *p,
3581                           struct torture_context *tctx,
3582                           struct policy_handle *user_handle,
3583                           struct policy_handle *domain_handle,
3584                           const struct dom_sid *domain_sid,
3585                           uint32_t base_acct_flags,
3586                           const char *base_acct_name, enum torture_samr_choice which_ops,
3587                           struct cli_credentials *machine_credentials)
3588 {
3589         char *password = NULL;
3590         struct samr_QueryUserInfo q;
3591         union samr_UserInfo *info;
3592         NTSTATUS status;
3593
3594         bool ret = true;
3595         int i;
3596         uint32_t rid;
3597         const uint32_t password_fields[] = {
3598                 SAMR_FIELD_NT_PASSWORD_PRESENT,
3599                 SAMR_FIELD_LM_PASSWORD_PRESENT,
3600                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
3601                 0
3602         };
3603
3604         status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
3605         if (!NT_STATUS_IS_OK(status)) {
3606                 ret = false;
3607         }
3608
3609         switch (which_ops) {
3610         case TORTURE_SAMR_USER_ATTRIBUTES:
3611                 if (!test_QuerySecurity(p, tctx, user_handle)) {
3612                         ret = false;
3613                 }
3614
3615                 if (!test_QueryUserInfo(p, tctx, user_handle)) {
3616                         ret = false;
3617                 }
3618
3619                 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
3620                         ret = false;
3621                 }
3622
3623                 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
3624                                       base_acct_name)) {
3625                         ret = false;
3626                 }
3627
3628                 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
3629                         ret = false;
3630                 }
3631
3632                 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
3633                         ret = false;
3634                 }
3635
3636                 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
3637                         ret = false;
3638                 }
3639                 break;
3640         case TORTURE_SAMR_PASSWORDS:
3641                 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
3642                         char simple_pass[9];
3643                         char *v = generate_random_str(tctx, 1);
3644
3645                         ZERO_STRUCT(simple_pass);
3646                         memset(simple_pass, *v, sizeof(simple_pass) - 1);
3647
3648                         printf("Testing machine account password policy rules\n");
3649
3650                         /* Workstation trust accounts don't seem to need to honour password quality policy */
3651                         if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
3652                                 ret = false;
3653                         }
3654
3655                         if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
3656                                 ret = false;
3657                         }
3658
3659                         /* reset again, to allow another 'user' password change */
3660                         if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
3661                                 ret = false;
3662                         }
3663
3664                         /* Try a 'short' password */
3665                         if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
3666                                 ret = false;
3667                         }
3668
3669                         /* Try a compleatly random password */
3670                         if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
3671                                 ret = false;
3672                         }
3673                 }
3674
3675                 for (i = 0; password_fields[i]; i++) {
3676                         if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
3677                                 ret = false;
3678                         }
3679
3680                         /* check it was set right */
3681                         if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3682                                 ret = false;
3683                         }
3684                 }
3685
3686                 for (i = 0; password_fields[i]; i++) {
3687                         if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
3688                                 ret = false;
3689                         }
3690
3691                         /* check it was set right */
3692                         if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3693                                 ret = false;
3694                         }
3695                 }
3696
3697                 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
3698                         ret = false;
3699                 }
3700
3701                 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
3702                         ret = false;
3703                 }
3704
3705                 if (torture_setting_bool(tctx, "samba4", false)) {
3706                         printf("skipping Set Password level 18 and 21 against Samba4\n");
3707                 } else {
3708
3709                         if (!test_SetUserPass_18(p, tctx, user_handle, &password)) {
3710                                 ret = false;
3711                         }
3712
3713                         if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3714                                 ret = false;
3715                         }
3716
3717                         for (i = 0; password_fields[i]; i++) {
3718
3719                                 if (password_fields[i] == SAMR_FIELD_LM_PASSWORD_PRESENT) {
3720                                         /* we need to skip as that would break
3721                                          * the ChangePasswordUser3 verify */
3722                                         continue;
3723                                 }
3724
3725                                 if (!test_SetUserPass_21(p, tctx, user_handle, password_fields[i], &password)) {
3726                                         ret = false;
3727                                 }
3728
3729                                 /* check it was set right */
3730                                 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3731                                         ret = false;
3732                                 }
3733                         }
3734                 }
3735
3736                 q.in.user_handle = user_handle;
3737                 q.in.level = 5;
3738                 q.out.info = &info;
3739
3740                 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
3741                 if (!NT_STATUS_IS_OK(status)) {
3742                         printf("QueryUserInfo level %u failed - %s\n",
3743                                q.in.level, nt_errstr(status));
3744                         ret = false;
3745                 } else {
3746                         uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
3747                         if ((info->info5.acct_flags) != expected_flags) {
3748                                 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
3749                                        info->info5.acct_flags,
3750                                        expected_flags);
3751                                 /* FIXME: GD */
3752                                 if (!torture_setting_bool(tctx, "samba3", false)) {
3753                                         ret = false;
3754                                 }
3755                         }
3756                         if (info->info5.rid != rid) {
3757                                 printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
3758                                        info->info5.rid, rid);
3759
3760                         }
3761                 }
3762
3763                 break;
3764
3765         case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
3766
3767                 /* test last password change timestamp behaviour */
3768                 if (!test_SetPassword_pwdlastset(p, tctx, base_acct_flags,
3769                                                  base_acct_name,
3770                                                  user_handle, &password,
3771                                                  machine_credentials)) {
3772                         ret = false;
3773                 }
3774
3775                 if (ret == true) {
3776                         torture_comment(tctx, "pwdLastSet test succeeded\n");
3777                 } else {
3778                         torture_warning(tctx, "pwdLastSet test failed\n");
3779                 }
3780
3781                 break;
3782
3783         case TORTURE_SAMR_USER_PRIVILEGES: {
3784
3785                 struct dcerpc_pipe *lp;
3786                 struct policy_handle *lsa_handle;
3787
3788                 status = torture_rpc_connection(tctx, &lp, &ndr_table_lsarpc);
3789                 torture_assert_ntstatus_ok(tctx, status, "Failed to open LSA pipe");
3790
3791                 if (!test_lsa_OpenPolicy2(lp, tctx, &lsa_handle)) {
3792                         ret = false;
3793                 }
3794
3795                 if (!test_DeleteUser_with_privs(p, lp, tctx,
3796                                                 domain_handle, lsa_handle, user_handle,
3797                                                 domain_sid, rid,
3798                                                 machine_credentials)) {
3799                         ret = false;
3800                 }
3801
3802                 if (!test_lsa_Close(lp, tctx, lsa_handle)) {
3803                         ret = false;
3804                 }
3805
3806                 if (!ret) {
3807                         torture_warning(tctx, "privileged user delete test failed\n");
3808                 }
3809
3810                 break;
3811         }
3812         case TORTURE_SAMR_OTHER:
3813                 /* We just need the account to exist */
3814                 break;
3815         }
3816         return ret;
3817 }
3818
3819 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
3820                            struct policy_handle *alias_handle,
3821                            const struct dom_sid *domain_sid)
3822 {
3823         bool ret = true;
3824
3825         if (!torture_setting_bool(tctx, "samba3", false)) {
3826                 if (!test_QuerySecurity(p, tctx, alias_handle)) {
3827                         ret = false;
3828                 }
3829         }
3830
3831         if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
3832                 ret = false;
3833         }
3834
3835         if (!test_SetAliasInfo(p, tctx, alias_handle)) {
3836                 ret = false;
3837         }
3838
3839         if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
3840                 ret = false;
3841         }
3842
3843         if (torture_setting_bool(tctx, "samba3", false) ||
3844             torture_setting_bool(tctx, "samba4", false)) {
3845                 printf("skipping MultipleMembers Alias tests against Samba\n");
3846                 return ret;
3847         }
3848
3849         if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
3850                 ret = false;
3851         }
3852
3853         return ret;
3854 }
3855
3856
3857 static bool test_DeleteUser(struct dcerpc_pipe *p, struct torture_context *tctx,
3858                                      struct policy_handle *user_handle)
3859 {
3860         struct samr_DeleteUser d;
3861         NTSTATUS status;
3862         torture_comment(tctx, "Testing DeleteUser\n");
3863
3864         d.in.user_handle = user_handle;
3865         d.out.user_handle = user_handle;
3866
3867         status = dcerpc_samr_DeleteUser(p, tctx, &d);
3868         torture_assert_ntstatus_ok(tctx, status, "DeleteUser");
3869
3870         return true;
3871 }
3872
3873 bool test_DeleteUser_byname(struct dcerpc_pipe *p,
3874                             struct torture_context *tctx,
3875                             struct policy_handle *handle, const char *name)
3876 {
3877         NTSTATUS status;
3878         struct samr_DeleteUser d;
3879         struct policy_handle user_handle;
3880         uint32_t rid;
3881
3882         status = test_LookupName(p, tctx, handle, name, &rid);
3883         if (!NT_STATUS_IS_OK(status)) {
3884                 goto failed;
3885         }
3886
3887         status = test_OpenUser_byname(p, tctx, handle, name, &user_handle);
3888         if (!NT_STATUS_IS_OK(status)) {
3889                 goto failed;
3890         }
3891
3892         d.in.user_handle = &user_handle;
3893         d.out.user_handle = &user_handle;
3894         status = dcerpc_samr_DeleteUser(p, tctx, &d);
3895         if (!NT_STATUS_IS_OK(status)) {
3896                 goto failed;
3897         }
3898
3899         return true;
3900
3901 failed:
3902         printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
3903         return false;
3904 }
3905
3906
3907 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p,
3908                                     struct torture_context *tctx,
3909                                     struct policy_handle *handle, const char *name)
3910 {
3911         NTSTATUS status;
3912         struct samr_OpenGroup r;
3913         struct samr_DeleteDomainGroup d;
3914         struct policy_handle group_handle;
3915         uint32_t rid;
3916
3917         status = test_LookupName(p, tctx, handle, name, &rid);
3918         if (!NT_STATUS_IS_OK(status)) {
3919                 goto failed;
3920         }
3921
3922         r.in.domain_handle = handle;
3923         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3924         r.in.rid = rid;
3925         r.out.group_handle = &group_handle;
3926         status = dcerpc_samr_OpenGroup(p, tctx, &r);
3927         if (!NT_STATUS_IS_OK(status)) {
3928                 goto failed;
3929         }
3930
3931         d.in.group_handle = &group_handle;
3932         d.out.group_handle = &group_handle;
3933         status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
3934         if (!NT_STATUS_IS_OK(status)) {
3935                 goto failed;
3936         }
3937
3938         return true;
3939
3940 failed:
3941         printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
3942         return false;
3943 }
3944
3945
3946 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p,
3947                                     struct torture_context *tctx,
3948                                     struct policy_handle *domain_handle,
3949                                     const char *name)
3950 {
3951         NTSTATUS status;
3952         struct samr_OpenAlias r;
3953         struct samr_DeleteDomAlias d;
3954         struct policy_handle alias_handle;
3955         uint32_t rid;
3956
3957         printf("testing DeleteAlias_byname\n");
3958
3959         status = test_LookupName(p, tctx, domain_handle, name, &rid);
3960         if (!NT_STATUS_IS_OK(status)) {
3961                 goto failed;
3962         }
3963
3964         r.in.domain_handle = domain_handle;
3965         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3966         r.in.rid = rid;
3967         r.out.alias_handle = &alias_handle;
3968         status = dcerpc_samr_OpenAlias(p, tctx, &r);
3969         if (!NT_STATUS_IS_OK(status)) {
3970                 goto failed;
3971         }
3972
3973         d.in.alias_handle = &alias_handle;
3974         d.out.alias_handle = &alias_handle;
3975         status = dcerpc_samr_DeleteDomAlias(p, tctx, &d);
3976         if (!NT_STATUS_IS_OK(status)) {
3977                 goto failed;
3978         }
3979
3980         return true;
3981
3982 failed:
3983         printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
3984         return false;
3985 }
3986
3987 static bool test_DeleteAlias(struct dcerpc_pipe *p,
3988                              struct torture_context *tctx,
3989                              struct policy_handle *alias_handle)
3990 {
3991         struct samr_DeleteDomAlias d;
3992         NTSTATUS status;
3993         bool ret = true;
3994         printf("Testing DeleteAlias\n");
3995
3996         d.in.alias_handle = alias_handle;
3997         d.out.alias_handle = alias_handle;
3998
3999         status = dcerpc_samr_DeleteDomAlias(p, tctx, &d);
4000         if (!NT_STATUS_IS_OK(status)) {
4001                 printf("DeleteAlias failed - %s\n", nt_errstr(status));
4002                 ret = false;
4003         }
4004
4005         return ret;
4006 }
4007
4008 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
4009                              struct policy_handle *domain_handle,
4010                              const char *alias_name,
4011                              struct policy_handle *alias_handle,
4012                              const struct dom_sid *domain_sid,
4013                              bool test_alias)
4014 {
4015         NTSTATUS status;
4016         struct samr_CreateDomAlias r;
4017         struct lsa_String name;
4018         uint32_t rid;
4019         bool ret = true;
4020
4021         init_lsa_String(&name, alias_name);
4022         r.in.domain_handle = domain_handle;
4023         r.in.alias_name = &name;
4024         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4025         r.out.alias_handle = alias_handle;
4026         r.out.rid = &rid;
4027
4028         printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
4029
4030         status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
4031
4032         if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4033                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4034                         printf("Server correctly refused create of '%s'\n", r.in.alias_name->string);
4035                         return true;
4036                 } else {
4037                         printf("Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
4038                                nt_errstr(status));
4039                         return false;
4040                 }
4041         }
4042
4043         if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
4044                 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
4045                         return false;
4046                 }
4047                 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
4048         }
4049
4050         if (!NT_STATUS_IS_OK(status)) {
4051                 printf("CreateAlias failed - %s\n", nt_errstr(status));
4052                 return false;
4053         }
4054
4055         if (!test_alias) {
4056                 return ret;
4057         }
4058
4059         if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
4060                 ret = false;
4061         }
4062
4063         return ret;
4064 }
4065
4066 static bool test_ChangePassword(struct dcerpc_pipe *p,
4067                                 struct torture_context *tctx,
4068                                 const char *acct_name,
4069                                 struct policy_handle *domain_handle, char **password)
4070 {
4071         bool ret = true;
4072
4073         if (!*password) {
4074                 return false;
4075         }
4076
4077         if (!test_ChangePasswordUser(p, tctx, acct_name, domain_handle, password)) {
4078                 ret = false;
4079         }
4080
4081         if (!test_ChangePasswordUser2(p, tctx, acct_name, password, 0, true)) {
4082                 ret = false;
4083         }
4084
4085         if (!test_OemChangePasswordUser2(p, tctx, acct_name, domain_handle, password)) {
4086                 ret = false;
4087         }
4088
4089         /* test what happens when setting the old password again */
4090         if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, *password, 0, true)) {
4091                 ret = false;
4092         }
4093
4094         {
4095                 char simple_pass[9];
4096                 char *v = generate_random_str(tctx, 1);
4097
4098                 ZERO_STRUCT(simple_pass);
4099                 memset(simple_pass, *v, sizeof(simple_pass) - 1);
4100
4101                 /* test what happens when picking a simple password */
4102                 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, simple_pass, 0, true)) {
4103                         ret = false;
4104                 }
4105         }
4106
4107         /* set samr_SetDomainInfo level 1 with min_length 5 */
4108         {
4109                 struct samr_QueryDomainInfo r;
4110                 union samr_DomainInfo *info = NULL;
4111                 struct samr_SetDomainInfo s;
4112                 uint16_t len_old, len;
4113                 uint32_t pwd_prop_old;
4114                 int64_t min_pwd_age_old;
4115                 NTSTATUS status;
4116
4117                 len = 5;
4118
4119                 r.in.domain_handle = domain_handle;
4120                 r.in.level = 1;
4121                 r.out.info = &info;
4122
4123                 printf("testing samr_QueryDomainInfo level 1\n");
4124                 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
4125                 if (!NT_STATUS_IS_OK(status)) {
4126                         return false;
4127                 }
4128
4129                 s.in.domain_handle = domain_handle;
4130                 s.in.level = 1;
4131                 s.in.info = info;
4132
4133                 /* remember the old min length, so we can reset it */
4134                 len_old = s.in.info->info1.min_password_length;
4135                 s.in.info->info1.min_password_length = len;
4136                 pwd_prop_old = s.in.info->info1.password_properties;
4137                 /* turn off password complexity checks for this test */
4138                 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
4139
4140                 min_pwd_age_old = s.in.info->info1.min_password_age;
4141                 s.in.info->info1.min_password_age = 0;
4142
4143                 printf("testing samr_SetDomainInfo level 1\n");
4144                 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
4145                 if (!NT_STATUS_IS_OK(status)) {
4146                         return false;
4147                 }
4148
4149                 printf("calling test_ChangePasswordUser3 with too short password\n");
4150
4151                 if (!test_ChangePasswordUser3(p, tctx, acct_name, len - 1, password, NULL, 0, true)) {
4152                         ret = false;
4153                 }
4154
4155                 s.in.info->info1.min_password_length = len_old;
4156                 s.in.info->info1.password_properties = pwd_prop_old;
4157                 s.in.info->info1.min_password_age = min_pwd_age_old;
4158
4159                 printf("testing samr_SetDomainInfo level 1\n");
4160                 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
4161                 if (!NT_STATUS_IS_OK(status)) {
4162                         return false;
4163                 }
4164
4165         }
4166
4167         {
4168                 NTSTATUS status;
4169                 struct samr_OpenUser r;
4170                 struct samr_QueryUserInfo q;
4171                 union samr_UserInfo *info;
4172                 struct samr_LookupNames n;
4173                 struct policy_handle user_handle;
4174                 struct samr_Ids rids, types;
4175
4176                 n.in.domain_handle = domain_handle;
4177                 n.in.num_names = 1;
4178                 n.in.names = talloc_array(tctx, struct lsa_String, 1);
4179                 n.in.names[0].string = acct_name;
4180                 n.out.rids = &rids;
4181                 n.out.types = &types;
4182
4183                 status = dcerpc_samr_LookupNames(p, tctx, &n);
4184                 if (!NT_STATUS_IS_OK(status)) {
4185                         printf("LookupNames failed - %s\n", nt_errstr(status));
4186                         return false;
4187                 }
4188
4189                 r.in.domain_handle = domain_handle;
4190                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4191                 r.in.rid = n.out.rids->ids[0];
4192                 r.out.user_handle = &user_handle;
4193
4194                 status = dcerpc_samr_OpenUser(p, tctx, &r);
4195                 if (!NT_STATUS_IS_OK(status)) {
4196                         printf("OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(status));
4197                         return false;
4198                 }
4199
4200                 q.in.user_handle = &user_handle;
4201                 q.in.level = 5;
4202                 q.out.info = &info;
4203
4204                 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
4205                 if (!NT_STATUS_IS_OK(status)) {
4206                         printf("QueryUserInfo failed - %s\n", nt_errstr(status));
4207                         return false;
4208                 }
4209
4210                 printf("calling test_ChangePasswordUser3 with too early password change\n");
4211
4212                 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL,
4213                                               info->info5.last_password_change, true)) {
4214                         ret = false;
4215                 }
4216         }
4217
4218         /* we change passwords twice - this has the effect of verifying
4219            they were changed correctly for the final call */
4220         if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
4221                 ret = false;
4222         }
4223
4224         if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
4225                 ret = false;
4226         }
4227
4228         return ret;
4229 }
4230
4231 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
4232                             struct policy_handle *domain_handle,
4233                             const char *user_name,
4234                             struct policy_handle *user_handle_out,
4235                             struct dom_sid *domain_sid,
4236                             enum torture_samr_choice which_ops,
4237                             struct cli_credentials *machine_credentials,
4238                             bool test_user)
4239 {
4240
4241         TALLOC_CTX *user_ctx;
4242
4243         NTSTATUS status;
4244         struct samr_CreateUser r;
4245         struct samr_QueryUserInfo q;
4246         union samr_UserInfo *info;
4247         struct samr_DeleteUser d;
4248         uint32_t rid;
4249
4250         /* This call creates a 'normal' account - check that it really does */
4251         const uint32_t acct_flags = ACB_NORMAL;
4252         struct lsa_String name;
4253         bool ret = true;
4254
4255         struct policy_handle user_handle;
4256         user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
4257         init_lsa_String(&name, user_name);
4258
4259         r.in.domain_handle = domain_handle;
4260         r.in.account_name = &name;
4261         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4262         r.out.user_handle = &user_handle;
4263         r.out.rid = &rid;
4264
4265         printf("Testing CreateUser(%s)\n", r.in.account_name->string);
4266
4267         status = dcerpc_samr_CreateUser(p, user_ctx, &r);
4268
4269         if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4270                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
4271                         printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
4272                         return true;
4273                 } else {
4274                         printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
4275                                nt_errstr(status));
4276                         return false;
4277                 }
4278         }
4279
4280         if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4281                 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
4282                         talloc_free(user_ctx);
4283                         return false;
4284                 }
4285                 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
4286         }
4287
4288         if (!NT_STATUS_IS_OK(status)) {
4289                 talloc_free(user_ctx);
4290                 printf("CreateUser failed - %s\n", nt_errstr(status));
4291                 return false;
4292         }
4293
4294         if (!test_user) {
4295                 if (user_handle_out) {
4296                         *user_handle_out = user_handle;
4297                 }
4298                 return ret;
4299         }
4300
4301         {
4302                 q.in.user_handle = &user_handle;
4303                 q.in.level = 16;
4304                 q.out.info = &info;
4305
4306                 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
4307                 if (!NT_STATUS_IS_OK(status)) {
4308                         printf("QueryUserInfo level %u failed - %s\n",
4309                                q.in.level, nt_errstr(status));
4310                         ret = false;
4311                 } else {
4312                         if ((info->info16.acct_flags & acct_flags) != acct_flags) {
4313                                 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4314                                        info->info16.acct_flags,
4315                                        acct_flags);
4316                                 ret = false;
4317                         }
4318                 }
4319
4320                 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
4321                                    domain_sid, acct_flags, name.string, which_ops,
4322                                    machine_credentials)) {
4323                         ret = false;
4324                 }
4325
4326                 if (user_handle_out) {
4327                         *user_handle_out = user_handle;
4328                 } else {
4329                         printf("Testing DeleteUser (createuser test)\n");
4330
4331                         d.in.user_handle = &user_handle;
4332                         d.out.user_handle = &user_handle;
4333
4334                         status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
4335                         if (!NT_STATUS_IS_OK(status)) {
4336                                 printf("DeleteUser failed - %s\n", nt_errstr(status));
4337                                 ret = false;
4338                         }
4339                 }
4340
4341         }
4342
4343         talloc_free(user_ctx);
4344
4345         return ret;
4346 }
4347
4348
4349 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
4350                              struct policy_handle *domain_handle,
4351                              struct dom_sid *domain_sid,
4352                              enum torture_samr_choice which_ops,
4353                              struct cli_credentials *machine_credentials)
4354 {
4355         NTSTATUS status;
4356         struct samr_CreateUser2 r;
4357         struct samr_QueryUserInfo q;
4358         union samr_UserInfo *info;
4359         struct samr_DeleteUser d;
4360         struct policy_handle user_handle;
4361         uint32_t rid;
4362         struct lsa_String name;
4363         bool ret = true;
4364         int i;
4365
4366         struct {
4367                 uint32_t acct_flags;
4368                 const char *account_name;
4369                 NTSTATUS nt_status;
4370         } account_types[] = {
4371                 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
4372                 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4373                 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4374                 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
4375                 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4376                 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4377                 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
4378                 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4379                 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4380                 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_ACCESS_DENIED },
4381                 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
4382                 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
4383                 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4384                 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4385                 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
4386         };
4387
4388         for (i = 0; account_types[i].account_name; i++) {
4389                 TALLOC_CTX *user_ctx;
4390                 uint32_t acct_flags = account_types[i].acct_flags;
4391                 uint32_t access_granted;
4392                 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
4393                 init_lsa_String(&name, account_types[i].account_name);
4394
4395                 r.in.domain_handle = domain_handle;
4396                 r.in.account_name = &name;
4397                 r.in.acct_flags = acct_flags;
4398                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4399                 r.out.user_handle = &user_handle;
4400                 r.out.access_granted = &access_granted;
4401                 r.out.rid = &rid;
4402
4403                 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
4404
4405                 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
4406
4407                 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4408                         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
4409                                 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
4410                                 continue;
4411                         } else {
4412                                 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
4413                                        nt_errstr(status));
4414                                 ret = false;
4415                                 continue;
4416                         }
4417                 }
4418
4419                 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4420                         if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
4421                                 talloc_free(user_ctx);
4422                                 ret = false;
4423                                 continue;
4424                         }
4425                         status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
4426
4427                 }
4428                 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
4429                         printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
4430                                nt_errstr(status), nt_errstr(account_types[i].nt_status));
4431                         ret = false;
4432                 }
4433
4434                 if (NT_STATUS_IS_OK(status)) {
4435                         q.in.user_handle = &user_handle;
4436                         q.in.level = 5;
4437                         q.out.info = &info;
4438
4439                         status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
4440                         if (!NT_STATUS_IS_OK(status)) {
4441                                 printf("QueryUserInfo level %u failed - %s\n",
4442                                        q.in.level, nt_errstr(status));
4443                                 ret = false;
4444                         } else {
4445                                 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
4446                                 if (acct_flags == ACB_NORMAL) {
4447                                         expected_flags |= ACB_PW_EXPIRED;
4448                                 }
4449                                 if ((info->info5.acct_flags) != expected_flags) {
4450                                         printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4451                                                info->info5.acct_flags,
4452                                                expected_flags);
4453                                         ret = false;
4454                                 }
4455                                 switch (acct_flags) {
4456                                 case ACB_SVRTRUST:
4457                                         if (info->info5.primary_gid != DOMAIN_RID_DCS) {
4458                                                 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
4459                                                        DOMAIN_RID_DCS, info->info5.primary_gid);
4460                                                 ret = false;
4461                                         }
4462                                         break;
4463                                 case ACB_WSTRUST:
4464                                         if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
4465                                                 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
4466                                                        DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
4467                                                 ret = false;
4468                                         }
4469                                         break;
4470                                 case ACB_NORMAL:
4471                                         if (info->info5.primary_gid != DOMAIN_RID_USERS) {
4472                                                 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
4473                                                        DOMAIN_RID_USERS, info->info5.primary_gid);
4474                                                 ret = false;
4475                                         }
4476                                         break;
4477                                 }
4478                         }
4479
4480                         if (!test_user_ops(p, tctx, &user_handle, domain_handle,
4481                                            domain_sid, acct_flags, name.string, which_ops,
4482                                            machine_credentials)) {
4483                                 ret = false;
4484                         }
4485
4486                         if (!policy_handle_empty(&user_handle)) {
4487                                 printf("Testing DeleteUser (createuser2 test)\n");
4488
4489                                 d.in.user_handle = &user_handle;
4490                                 d.out.user_handle = &user_handle;
4491
4492                                 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
4493                                 if (!NT_STATUS_IS_OK(status)) {
4494                                         printf("DeleteUser failed - %s\n", nt_errstr(status));
4495                                         ret = false;
4496                                 }
4497                         }
4498                 }
4499                 talloc_free(user_ctx);
4500         }
4501
4502         return ret;
4503 }
4504
4505 static bool test_QueryAliasInfo(struct dcerpc_pipe *p,
4506                                 struct torture_context *tctx,
4507                                 struct policy_handle *handle)
4508 {
4509         NTSTATUS status;
4510         struct samr_QueryAliasInfo r;
4511         union samr_AliasInfo *info;
4512         uint16_t levels[] = {1, 2, 3};
4513         int i;
4514         bool ret = true;
4515
4516         for (i=0;i<ARRAY_SIZE(levels);i++) {
4517                 printf("Testing QueryAliasInfo level %u\n", levels[i]);
4518
4519                 r.in.alias_handle = handle;
4520                 r.in.level = levels[i];
4521                 r.out.info = &info;
4522
4523                 status = dcerpc_samr_QueryAliasInfo(p, tctx, &r);
4524                 if (!NT_STATUS_IS_OK(status)) {
4525                         printf("QueryAliasInfo level %u failed - %s\n",
4526                                levels[i], nt_errstr(status));
4527                         ret = false;
4528                 }
4529         }
4530
4531         return ret;
4532 }
4533
4534 static bool test_QueryGroupInfo(struct dcerpc_pipe *p,
4535                                 struct torture_context *tctx,
4536                                 struct policy_handle *handle)
4537 {
4538         NTSTATUS status;
4539         struct samr_QueryGroupInfo r;
4540         union samr_GroupInfo *info;
4541         uint16_t levels[] = {1, 2, 3, 4, 5};
4542         int i;
4543         bool ret = true;
4544
4545         for (i=0;i<ARRAY_SIZE(levels);i++) {
4546                 printf("Testing QueryGroupInfo level %u\n", levels[i]);
4547
4548                 r.in.group_handle = handle;
4549                 r.in.level = levels[i];
4550                 r.out.info = &info;
4551
4552                 status = dcerpc_samr_QueryGroupInfo(p, tctx, &r);
4553                 if (!NT_STATUS_IS_OK(status)) {
4554                         printf("QueryGroupInfo level %u failed - %s\n",
4555                                levels[i], nt_errstr(status));
4556                         ret = false;
4557                 }
4558         }
4559
4560         return ret;
4561 }
4562
4563 static bool test_QueryGroupMember(struct dcerpc_pipe *p,
4564                                   struct torture_context *tctx,
4565                                   struct policy_handle *handle)
4566 {
4567         NTSTATUS status;
4568         struct samr_QueryGroupMember r;
4569         struct samr_RidTypeArray *rids = NULL;
4570         bool ret = true;
4571
4572         printf("Testing QueryGroupMember\n");
4573
4574         r.in.group_handle = handle;
4575         r.out.rids = &rids;
4576
4577         status = dcerpc_samr_QueryGroupMember(p, tctx, &r);
4578         if (!NT_STATUS_IS_OK(status)) {
4579                 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
4580                 ret = false;
4581         }
4582
4583         return ret;
4584 }
4585
4586
4587 static bool test_SetGroupInfo(struct dcerpc_pipe *p,
4588                               struct torture_context *tctx,
4589                               struct policy_handle *handle)
4590 {
4591         NTSTATUS status;
4592         struct samr_QueryGroupInfo r;
4593         union samr_GroupInfo *info;
4594         struct samr_SetGroupInfo s;
4595         uint16_t levels[] = {1, 2, 3, 4};
4596         uint16_t set_ok[] = {0, 1, 1, 1};
4597         int i;
4598         bool ret = true;
4599
4600         for (i=0;i<ARRAY_SIZE(levels);i++) {
4601                 printf("Testing QueryGroupInfo level %u\n", levels[i]);
4602
4603                 r.in.group_handle = handle;
4604                 r.in.level = levels[i];
4605                 r.out.info = &info;
4606
4607                 status = dcerpc_samr_QueryGroupInfo(p, tctx, &r);
4608                 if (!NT_STATUS_IS_OK(status)) {
4609                         printf("QueryGroupInfo level %u failed - %s\n",
4610                                levels[i], nt_errstr(status));
4611                         ret = false;
4612                 }
4613
4614                 printf("Testing SetGroupInfo level %u\n", levels[i]);
4615
4616                 s.in.group_handle = handle;
4617                 s.in.level = levels[i];
4618                 s.in.info = *r.out.info;
4619
4620 #if 0
4621                 /* disabled this, as it changes the name only from the point of view of samr,
4622                    but leaves the name from the point of view of w2k3 internals (and ldap). This means
4623                    the name is still reserved, so creating the old name fails, but deleting by the old name
4624                    also fails */
4625                 if (s.in.level == 2) {
4626                         init_lsa_String(&s.in.info->string, "NewName");
4627                 }
4628 #endif
4629
4630                 if (s.in.level == 4) {
4631                         init_lsa_String(&s.in.info->description, "test description");
4632                 }
4633
4634                 status = dcerpc_samr_SetGroupInfo(p, tctx, &s);
4635                 if (set_ok[i]) {
4636                         if (!NT_STATUS_IS_OK(status)) {
4637                                 printf("SetGroupInfo level %u failed - %s\n",
4638                                        r.in.level, nt_errstr(status));
4639                                 ret = false;
4640                                 continue;
4641                         }
4642                 } else {
4643                         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
4644                                 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
4645                                        r.in.level, nt_errstr(status));
4646                                 ret = false;
4647                                 continue;
4648                         }
4649                 }
4650         }
4651
4652         return ret;
4653 }
4654
4655 static bool test_QueryUserInfo(struct dcerpc_pipe *p,
4656                                struct torture_context *tctx,
4657                                struct policy_handle *handle)
4658 {
4659         NTSTATUS status;
4660         struct samr_QueryUserInfo r;
4661         union samr_UserInfo *info;
4662         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4663                            11, 12, 13, 14, 16, 17, 20, 21};
4664         int i;
4665         bool ret = true;
4666
4667         for (i=0;i<ARRAY_SIZE(levels);i++) {
4668                 printf("Testing QueryUserInfo level %u\n", levels[i]);
4669
4670                 r.in.user_handle = handle;
4671                 r.in.level = levels[i];
4672                 r.out.info = &info;
4673
4674                 status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
4675                 if (!NT_STATUS_IS_OK(status)) {
4676                         printf("QueryUserInfo level %u failed - %s\n",
4677                                levels[i], nt_errstr(status));
4678                         ret = false;
4679                 }
4680         }
4681
4682         return ret;
4683 }
4684
4685 static bool test_QueryUserInfo2(struct dcerpc_pipe *p,
4686                                 struct torture_context *tctx,
4687                                 struct policy_handle *handle)
4688 {
4689         NTSTATUS status;
4690         struct samr_QueryUserInfo2 r;
4691         union samr_UserInfo *info;
4692         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4693                            11, 12, 13, 14, 16, 17, 20, 21};
4694         int i;
4695         bool ret = true;
4696
4697         for (i=0;i<ARRAY_SIZE(levels);i++) {
4698                 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
4699
4700                 r.in.user_handle = handle;
4701                 r.in.level = levels[i];
4702                 r.out.info = &info;
4703
4704                 status = dcerpc_samr_QueryUserInfo2(p, tctx, &r);
4705                 if (!NT_STATUS_IS_OK(status)) {
4706                         printf("QueryUserInfo2 level %u failed - %s\n",
4707                                levels[i], nt_errstr(status));
4708                         ret = false;
4709                 }
4710         }
4711
4712         return ret;
4713 }
4714
4715 static bool test_OpenUser(struct dcerpc_pipe *p,
4716                           struct torture_context *tctx,
4717                           struct policy_handle *handle, uint32_t rid)
4718 {
4719         NTSTATUS status;
4720         struct samr_OpenUser r;
4721         struct policy_handle user_handle;
4722         bool ret = true;
4723
4724         printf("Testing OpenUser(%u)\n", rid);
4725
4726         r.in.domain_handle = handle;
4727         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4728         r.in.rid = rid;
4729         r.out.user_handle = &user_handle;
4730
4731         status = dcerpc_samr_OpenUser(p, tctx, &r);
4732         if (!NT_STATUS_IS_OK(status)) {
4733                 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
4734                 return false;
4735         }
4736
4737         if (!test_QuerySecurity(p, tctx, &user_handle)) {
4738                 ret = false;
4739         }
4740
4741         if (!test_QueryUserInfo(p, tctx, &user_handle)) {
4742                 ret = false;
4743         }
4744
4745         if (!test_QueryUserInfo2(p, tctx, &user_handle)) {
4746                 ret = false;
4747         }
4748
4749         if (!test_GetUserPwInfo(p, tctx, &user_handle)) {
4750                 ret = false;
4751         }
4752
4753         if (!test_GetGroupsForUser(p,tctx, &user_handle)) {
4754                 ret = false;
4755         }
4756
4757         if (!test_samr_handle_Close(p, tctx, &user_handle)) {
4758                 ret = false;
4759         }
4760
4761         return ret;
4762 }
4763
4764 static bool test_OpenGroup(struct dcerpc_pipe *p,
4765                            struct torture_context *tctx,
4766                            struct policy_handle *handle, uint32_t rid)
4767 {
4768         NTSTATUS status;
4769         struct samr_OpenGroup r;
4770         struct policy_handle group_handle;
4771         bool ret = true;
4772
4773         printf("Testing OpenGroup(%u)\n", rid);
4774
4775         r.in.domain_handle = handle;
4776         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4777         r.in.rid = rid;
4778         r.out.group_handle = &group_handle;
4779
4780         status = dcerpc_samr_OpenGroup(p, tctx, &r);
4781         if (!NT_STATUS_IS_OK(status)) {
4782                 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
4783                 return false;
4784         }
4785
4786         if (!torture_setting_bool(tctx, "samba3", false)) {
4787                 if (!test_QuerySecurity(p, tctx, &group_handle)) {
4788                         ret = false;
4789                 }
4790         }
4791
4792         if (!test_QueryGroupInfo(p, tctx, &group_handle)) {
4793                 ret = false;
4794         }
4795
4796         if (!test_QueryGroupMember(p, tctx, &group_handle)) {
4797                 ret = false;
4798         }
4799
4800         if (!test_samr_handle_Close(p, tctx, &group_handle)) {
4801                 ret = false;
4802         }
4803
4804         return ret;
4805 }
4806
4807 static bool test_OpenAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
4808                            struct policy_handle *handle, uint32_t rid)
4809 {
4810         NTSTATUS status;
4811         struct samr_OpenAlias r;
4812         struct policy_handle alias_handle;
4813         bool ret = true;
4814
4815         torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
4816
4817         r.in.domain_handle = handle;
4818         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4819         r.in.rid = rid;
4820         r.out.alias_handle = &alias_handle;
4821
4822         status = dcerpc_samr_OpenAlias(p, tctx, &r);
4823         if (!NT_STATUS_IS_OK(status)) {
4824                 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
4825                 return false;
4826         }
4827
4828         if (!torture_setting_bool(tctx, "samba3", false)) {
4829                 if (!test_QuerySecurity(p, tctx, &alias_handle)) {
4830                         ret = false;
4831                 }
4832         }
4833
4834         if (!test_QueryAliasInfo(p, tctx, &alias_handle)) {
4835                 ret = false;
4836         }
4837
4838         if (!test_GetMembersInAlias(p, tctx, &alias_handle)) {
4839                 ret = false;
4840         }
4841
4842         if (!test_samr_handle_Close(p, tctx, &alias_handle)) {
4843                 ret = false;
4844         }
4845
4846         return ret;
4847 }
4848
4849 static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
4850                        struct policy_handle *handle, uint32_t rid,
4851                        uint32_t acct_flag_mask)
4852 {
4853         NTSTATUS status;
4854         struct samr_OpenUser r;
4855         struct samr_QueryUserInfo q;
4856         union samr_UserInfo *info;
4857         struct policy_handle user_handle;
4858         bool ret = true;
4859
4860         torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
4861
4862         r.in.domain_handle = handle;
4863         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4864         r.in.rid = rid;
4865         r.out.user_handle = &user_handle;
4866
4867         status = dcerpc_samr_OpenUser(p, tctx, &r);
4868         if (!NT_STATUS_IS_OK(status)) {
4869                 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
4870                 return false;
4871         }
4872
4873         q.in.user_handle = &user_handle;
4874         q.in.level = 16;
4875         q.out.info = &info;
4876
4877         status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
4878         if (!NT_STATUS_IS_OK(status)) {
4879                 printf("QueryUserInfo level 16 failed - %s\n",
4880                        nt_errstr(status));
4881                 ret = false;
4882         } else {
4883                 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
4884                         printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
4885                                acct_flag_mask, info->info16.acct_flags, rid);
4886                         ret = false;
4887                 }
4888         }
4889
4890         if (!test_samr_handle_Close(p, tctx, &user_handle)) {
4891                 ret = false;
4892         }
4893
4894         return ret;
4895 }
4896
4897 static bool test_EnumDomainUsers_all(struct dcerpc_pipe *p,
4898                                      struct torture_context *tctx,
4899                                      struct policy_handle *handle)
4900 {
4901         NTSTATUS status = STATUS_MORE_ENTRIES;
4902         struct samr_EnumDomainUsers r;
4903         uint32_t mask, resume_handle=0;
4904         int i, mask_idx;
4905         bool ret = true;
4906         struct samr_LookupNames n;
4907         struct samr_LookupRids  lr ;
4908         struct lsa_Strings names;
4909         struct samr_Ids rids, types;
4910         struct samr_SamArray *sam = NULL;
4911         uint32_t num_entries = 0;
4912
4913         uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
4914                             ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
4915                             ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
4916                             ACB_PWNOEXP, 0};
4917
4918         printf("Testing EnumDomainUsers\n");
4919
4920         for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
4921                 r.in.domain_handle = handle;
4922                 r.in.resume_handle = &resume_handle;
4923                 r.in.acct_flags = mask = masks[mask_idx];
4924                 r.in.max_size = (uint32_t)-1;
4925                 r.out.resume_handle = &resume_handle;
4926                 r.out.num_entries = &num_entries;
4927                 r.out.sam = &sam;
4928
4929                 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
4930                 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
4931                     !NT_STATUS_IS_OK(status)) {
4932                         printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
4933                         return false;
4934                 }
4935
4936                 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
4937
4938                 if (sam->count == 0) {
4939                         continue;
4940                 }
4941
4942                 for (i=0;i<sam->count;i++) {
4943                         if (mask) {
4944                                 if (!check_mask(p, tctx, handle, sam->entries[i].idx, mask)) {
4945                                         ret = false;
4946                                 }
4947                         } else if (!test_OpenUser(p, tctx, handle, sam->entries[i].idx)) {
4948                                 ret = false;
4949                         }
4950                 }
4951         }
4952
4953         printf("Testing LookupNames\n");
4954         n.in.domain_handle = handle;
4955         n.in.num_names = sam->count;
4956         n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
4957         n.out.rids = &rids;
4958         n.out.types = &types;
4959         for (i=0;i<sam->count;i++) {
4960                 n.in.names[i].string = sam->entries[i].name.string;
4961         }
4962         status = dcerpc_samr_LookupNames(p, tctx, &n);
4963         if (!NT_STATUS_IS_OK(status)) {
4964                 printf("LookupNames failed - %s\n", nt_errstr(status));
4965                 ret = false;
4966         }
4967
4968
4969         printf("Testing LookupRids\n");
4970         lr.in.domain_handle = handle;
4971         lr.in.num_rids = sam->count;
4972         lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
4973         lr.out.names = &names;
4974         lr.out.types = &types;
4975         for (i=0;i<sam->count;i++) {
4976                 lr.in.rids[i] = sam->entries[i].idx;
4977         }
4978         status = dcerpc_samr_LookupRids(p, tctx, &lr);
4979         torture_assert_ntstatus_ok(tctx, status, "LookupRids");
4980
4981         return ret;
4982 }
4983
4984 /*
4985   try blasting the server with a bunch of sync requests
4986 */
4987 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
4988                                        struct policy_handle *handle)
4989 {
4990         NTSTATUS status;
4991         struct samr_EnumDomainUsers r;
4992         uint32_t resume_handle=0;
4993         int i;
4994 #define ASYNC_COUNT 100
4995         struct rpc_request *req[ASYNC_COUNT];
4996
4997         if (!torture_setting_bool(tctx, "dangerous", false)) {
4998                 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
4999         }
5000
5001         torture_comment(tctx, "Testing EnumDomainUsers_async\n");
5002
5003         r.in.domain_handle = handle;
5004         r.in.resume_handle = &resume_handle;
5005         r.in.acct_flags = 0;
5006         r.in.max_size = (uint32_t)-1;
5007         r.out.resume_handle = &resume_handle;
5008
5009         for (i=0;i<ASYNC_COUNT;i++) {
5010                 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
5011         }
5012
5013         for (i=0;i<ASYNC_COUNT;i++) {
5014                 status = dcerpc_ndr_request_recv(req[i]);
5015                 if (!NT_STATUS_IS_OK(status)) {
5016                         printf("EnumDomainUsers[%d] failed - %s\n",
5017                                i, nt_errstr(status));
5018                         return false;
5019                 }
5020         }
5021
5022         torture_comment(tctx, "%d async requests OK\n", i);
5023
5024         return true;
5025 }
5026
5027 static bool test_EnumDomainGroups_all(struct dcerpc_pipe *p,
5028                                       struct torture_context *tctx,
5029                                       struct policy_handle *handle)
5030 {
5031         NTSTATUS status;
5032         struct samr_EnumDomainGroups r;
5033         uint32_t resume_handle=0;
5034         struct samr_SamArray *sam = NULL;
5035         uint32_t num_entries = 0;
5036         int i;
5037         bool ret = true;
5038
5039         printf("Testing EnumDomainGroups\n");
5040
5041         r.in.domain_handle = handle;
5042         r.in.resume_handle = &resume_handle;
5043         r.in.max_size = (uint32_t)-1;
5044         r.out.resume_handle = &resume_handle;
5045         r.out.num_entries = &num_entries;
5046         r.out.sam = &sam;
5047
5048         status = dcerpc_samr_EnumDomainGroups(p, tctx, &r);
5049         if (!NT_STATUS_IS_OK(status)) {
5050                 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
5051                 return false;
5052         }
5053
5054         if (!sam) {
5055                 return false;
5056         }
5057
5058         for (i=0;i<sam->count;i++) {
5059                 if (!test_OpenGroup(p, tctx, handle, sam->entries[i].idx)) {
5060                         ret = false;
5061                 }
5062         }
5063
5064         return ret;
5065 }
5066
5067 static bool test_EnumDomainAliases_all(struct dcerpc_pipe *p,
5068                                        struct torture_context *tctx,
5069                                        struct policy_handle *handle)
5070 {
5071         NTSTATUS status;
5072         struct samr_EnumDomainAliases r;
5073         uint32_t resume_handle=0;
5074         struct samr_SamArray *sam = NULL;
5075         uint32_t num_entries = 0;
5076         int i;
5077         bool ret = true;
5078
5079         printf("Testing EnumDomainAliases\n");
5080
5081         r.in.domain_handle = handle;
5082         r.in.resume_handle = &resume_handle;
5083         r.in.max_size = (uint32_t)-1;
5084         r.out.sam = &sam;
5085         r.out.num_entries = &num_entries;
5086         r.out.resume_handle = &resume_handle;
5087
5088         status = dcerpc_samr_EnumDomainAliases(p, tctx, &r);
5089         if (!NT_STATUS_IS_OK(status)) {
5090                 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
5091                 return false;
5092         }
5093
5094         if (!sam) {
5095                 return false;
5096         }
5097
5098         for (i=0;i<sam->count;i++) {
5099                 if (!test_OpenAlias(p, tctx, handle, sam->entries[i].idx)) {
5100                         ret = false;
5101                 }
5102         }
5103
5104         return ret;
5105 }
5106
5107 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p,
5108                                             struct torture_context *tctx,
5109                                             struct policy_handle *handle)
5110 {
5111         NTSTATUS status;
5112         struct samr_GetDisplayEnumerationIndex r;
5113         bool ret = true;
5114         uint16_t levels[] = {1, 2, 3, 4, 5};
5115         uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
5116         struct lsa_String name;
5117         uint32_t idx = 0;
5118         int i;
5119
5120         for (i=0;i<ARRAY_SIZE(levels);i++) {
5121                 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
5122
5123                 init_lsa_String(&name, TEST_ACCOUNT_NAME);
5124
5125                 r.in.domain_handle = handle;
5126                 r.in.level = levels[i];
5127                 r.in.name = &name;
5128                 r.out.idx = &idx;
5129
5130                 status = dcerpc_samr_GetDisplayEnumerationIndex(p, tctx, &r);
5131
5132                 if (ok_lvl[i] &&
5133                     !NT_STATUS_IS_OK(status) &&
5134                     !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5135                         printf("GetDisplayEnumerationIndex level %u failed - %s\n",
5136                                levels[i], nt_errstr(status));
5137                         ret = false;
5138                 }
5139
5140                 init_lsa_String(&name, "zzzzzzzz");
5141
5142                 status = dcerpc_samr_GetDisplayEnumerationIndex(p, tctx, &r);
5143
5144                 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5145                         printf("GetDisplayEnumerationIndex level %u failed - %s\n",
5146                                levels[i], nt_errstr(status));
5147                         ret = false;
5148                 }
5149         }
5150
5151         return ret;
5152 }
5153
5154 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p,
5155                                              struct torture_context *tctx,
5156                                              struct policy_handle *handle)
5157 {
5158         NTSTATUS status;
5159         struct samr_GetDisplayEnumerationIndex2 r;
5160         bool ret = true;
5161         uint16_t levels[] = {1, 2, 3, 4, 5};
5162         uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
5163         struct lsa_String name;
5164         uint32_t idx = 0;
5165         int i;
5166
5167         for (i=0;i<ARRAY_SIZE(levels);i++) {
5168                 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
5169
5170                 init_lsa_String(&name, TEST_ACCOUNT_NAME);
5171
5172                 r.in.domain_handle = handle;
5173                 r.in.level = levels[i];
5174                 r.in.name = &name;
5175                 r.out.idx = &idx;
5176
5177                 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, tctx, &r);
5178                 if (ok_lvl[i] &&
5179                     !NT_STATUS_IS_OK(status) &&
5180                     !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5181                         printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
5182                                levels[i], nt_errstr(status));
5183                         ret = false;
5184                 }
5185
5186                 init_lsa_String(&name, "zzzzzzzz");
5187
5188                 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, tctx, &r);
5189                 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5190                         printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
5191                                levels[i], nt_errstr(status));
5192                         ret = false;
5193                 }
5194         }
5195
5196         return ret;
5197 }
5198
5199 #define STRING_EQUAL_QUERY(s1, s2, user)                                        \
5200         if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
5201                 /* odd, but valid */                                            \
5202         } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
5203                         printf("%s mismatch for %s: %s != %s (%s)\n", \
5204                                #s1, user.string,  s1.string, s2.string, __location__);   \
5205                         ret = false; \
5206         }
5207 #define INT_EQUAL_QUERY(s1, s2, user)           \
5208                 if (s1 != s2) { \
5209                         printf("%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
5210                                #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
5211                         ret = false; \
5212                 }
5213
5214 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p,
5215                                        struct torture_context *tctx,
5216                                        struct samr_QueryDisplayInfo *querydisplayinfo,
5217                                        bool *seen_testuser)
5218 {
5219         struct samr_OpenUser r;
5220         struct samr_QueryUserInfo q;
5221         union samr_UserInfo *info;
5222         struct policy_handle user_handle;
5223         int i, ret = true;
5224         NTSTATUS status;
5225         r.in.domain_handle = querydisplayinfo->in.domain_handle;
5226         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5227         for (i = 0; ; i++) {
5228                 switch (querydisplayinfo->in.level) {
5229                 case 1:
5230                         if (i >= querydisplayinfo->out.info->info1.count) {
5231                                 return ret;
5232                         }
5233                         r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
5234                         break;
5235                 case 2:
5236                         if (i >= querydisplayinfo->out.info->info2.count) {
5237                                 return ret;
5238                         }
5239                         r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
5240                         break;
5241                 case 3:
5242                         /* Groups */
5243                 case 4:
5244                 case 5:
5245                         /* Not interested in validating just the account name */
5246                         return true;
5247                 }
5248
5249                 r.out.user_handle = &user_handle;
5250
5251                 switch (querydisplayinfo->in.level) {
5252                 case 1:
5253                 case 2:
5254                         status = dcerpc_samr_OpenUser(p, tctx, &r);
5255                         if (!NT_STATUS_IS_OK(status)) {
5256                                 printf("OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
5257                                 return false;
5258                         }
5259                 }
5260
5261                 q.in.user_handle = &user_handle;
5262                 q.in.level = 21;
5263                 q.out.info = &info;
5264                 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
5265                 if (!NT_STATUS_IS_OK(status)) {
5266                         printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
5267                         return false;
5268                 }
5269
5270                 switch (querydisplayinfo->in.level) {
5271                 case 1:
5272                         if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
5273                                 *seen_testuser = true;
5274                         }
5275                         STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
5276                                            info->info21.full_name, info->info21.account_name);
5277                         STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
5278                                            info->info21.account_name, info->info21.account_name);
5279                         STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
5280                                            info->info21.description, info->info21.account_name);
5281                         INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
5282                                         info->info21.rid, info->info21.account_name);
5283                         INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
5284                                         info->info21.acct_flags, info->info21.account_name);
5285
5286                         break;
5287                 case 2:
5288                         STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
5289                                            info->info21.account_name, info->info21.account_name);
5290                         STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
5291                                            info->info21.description, info->info21.account_name);
5292                         INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
5293                                         info->info21.rid, info->info21.account_name);
5294                         INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
5295                                         info->info21.acct_flags, info->info21.account_name);
5296
5297                         if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
5298                                 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
5299                                        info->info21.account_name.string);
5300                         }
5301
5302                         if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
5303                                 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
5304                                        info->info21.account_name.string,
5305                                        querydisplayinfo->out.info->info2.entries[i].acct_flags,
5306                                        info->info21.acct_flags);
5307                                 return false;
5308                         }
5309
5310                         break;
5311                 }
5312
5313                 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
5314                         return false;
5315                 }
5316         }
5317         return ret;
5318 }
5319
5320 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p,
5321                                   struct torture_context *tctx,
5322                                   struct policy_handle *handle)
5323 {
5324         NTSTATUS status;
5325         struct samr_QueryDisplayInfo r;
5326         struct samr_QueryDomainInfo dom_info;
5327         union samr_DomainInfo *info = NULL;
5328         bool ret = true;
5329         uint16_t levels[] = {1, 2, 3, 4, 5};
5330         int i;
5331         bool seen_testuser = false;
5332         uint32_t total_size;
5333         uint32_t returned_size;
5334         union samr_DispInfo disp_info;
5335
5336
5337         for (i=0;i<ARRAY_SIZE(levels);i++) {
5338                 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
5339
5340                 r.in.start_idx = 0;
5341                 status = STATUS_MORE_ENTRIES;
5342                 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5343                         r.in.domain_handle = handle;
5344                         r.in.level = levels[i];
5345                         r.in.max_entries = 2;
5346                         r.in.buf_size = (uint32_t)-1;
5347                         r.out.total_size = &total_size;
5348                         r.out.returned_size = &returned_size;
5349                         r.out.info = &disp_info;
5350
5351                         status = dcerpc_samr_QueryDisplayInfo(p, tctx, &r);
5352                         if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
5353                                 printf("QueryDisplayInfo level %u failed - %s\n",
5354                                        levels[i], nt_errstr(status));
5355                                 ret = false;
5356                         }
5357                         switch (r.in.level) {
5358                         case 1:
5359                                 if (!test_each_DisplayInfo_user(p, tctx, &r, &seen_testuser)) {
5360                                         ret = false;
5361                                 }
5362                                 r.in.start_idx += r.out.info->info1.count;
5363                                 break;
5364                         case 2:
5365                                 if (!test_each_DisplayInfo_user(p, tctx, &r, NULL)) {
5366                                         ret = false;
5367                                 }
5368                                 r.in.start_idx += r.out.info->info2.count;
5369                                 break;
5370                         case 3:
5371                                 r.in.start_idx += r.out.info->info3.count;
5372                                 break;
5373                         case 4:
5374                                 r.in.start_idx += r.out.info->info4.count;
5375                                 break;
5376                         case 5:
5377                                 r.in.start_idx += r.out.info->info5.count;
5378                                 break;
5379                         }
5380                 }
5381                 dom_info.in.domain_handle = handle;
5382                 dom_info.in.level = 2;
5383                 dom_info.out.info = &info;
5384
5385                 /* Check number of users returned is correct */
5386                 status = dcerpc_samr_QueryDomainInfo(p, tctx, &dom_info);
5387                 if (!NT_STATUS_IS_OK(status)) {
5388                         printf("QueryDomainInfo level %u failed - %s\n",
5389                                r.in.level, nt_errstr(status));
5390                                 ret = false;
5391                                 break;
5392                 }
5393                 switch (r.in.level) {
5394                 case 1:
5395                 case 4:
5396                         if (info->general.num_users < r.in.start_idx) {
5397                                 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
5398                                        r.in.start_idx, info->general.num_groups,
5399                                        info->general.domain_name.string);
5400                                 ret = false;
5401                         }
5402                         if (!seen_testuser) {
5403                                 struct policy_handle user_handle;
5404                                 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, tctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
5405                                         printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
5406                                                info->general.domain_name.string);
5407                                         ret = false;
5408                                         test_samr_handle_Close(p, tctx, &user_handle);
5409                                 }
5410                         }
5411                         break;
5412                 case 3:
5413                 case 5:
5414                         if (info->general.num_groups != r.in.start_idx) {
5415                                 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
5416                                        r.in.start_idx, info->general.num_groups,
5417                                        info->general.domain_name.string);
5418                                 ret = false;
5419                         }
5420
5421                         break;
5422                 }
5423
5424         }
5425
5426         return ret;
5427 }
5428
5429 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p,
5430                                    struct torture_context *tctx,
5431                                    struct policy_handle *handle)
5432 {
5433         NTSTATUS status;
5434         struct samr_QueryDisplayInfo2 r;
5435         bool ret = true;
5436         uint16_t levels[] = {1, 2, 3, 4, 5};
5437         int i;
5438         uint32_t total_size;
5439         uint32_t returned_size;
5440         union samr_DispInfo info;
5441
5442         for (i=0;i<ARRAY_SIZE(levels);i++) {
5443                 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
5444
5445                 r.in.domain_handle = handle;
5446                 r.in.level = levels[i];
5447                 r.in.start_idx = 0;
5448                 r.in.max_entries = 1000;
5449                 r.in.buf_size = (uint32_t)-1;
5450                 r.out.total_size = &total_size;
5451                 r.out.returned_size = &returned_size;
5452                 r.out.info = &info;
5453
5454                 status = dcerpc_samr_QueryDisplayInfo2(p, tctx, &r);
5455                 if (!NT_STATUS_IS_OK(status)) {
5456                         printf("QueryDisplayInfo2 level %u failed - %s\n",
5457                                levels[i], nt_errstr(status));
5458                         ret = false;
5459                 }
5460         }
5461
5462         return ret;
5463 }
5464
5465 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context *tctx,
5466                                   struct policy_handle *handle)
5467 {
5468         NTSTATUS status;
5469         struct samr_QueryDisplayInfo3 r;
5470         bool ret = true;
5471         uint16_t levels[] = {1, 2, 3, 4, 5};
5472         int i;
5473         uint32_t total_size;
5474         uint32_t returned_size;
5475         union samr_DispInfo info;
5476
5477         for (i=0;i<ARRAY_SIZE(levels);i++) {
5478                 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
5479
5480                 r.in.domain_handle = handle;
5481                 r.in.level = levels[i];
5482                 r.in.start_idx = 0;
5483                 r.in.max_entries = 1000;
5484                 r.in.buf_size = (uint32_t)-1;
5485                 r.out.total_size = &total_size;
5486                 r.out.returned_size = &returned_size;
5487                 r.out.info = &info;
5488
5489                 status = dcerpc_samr_QueryDisplayInfo3(p, tctx, &r);
5490                 if (!NT_STATUS_IS_OK(status)) {
5491                         printf("QueryDisplayInfo3 level %u failed - %s\n",
5492                                levels[i], nt_errstr(status));
5493                         ret = false;
5494                 }
5495         }
5496
5497         return ret;
5498 }
5499
5500
5501 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p,
5502                                            struct torture_context *tctx,
5503                                            struct policy_handle *handle)
5504 {
5505         NTSTATUS status;
5506         struct samr_QueryDisplayInfo r;
5507         bool ret = true;
5508         uint32_t total_size;
5509         uint32_t returned_size;
5510         union samr_DispInfo info;
5511
5512         printf("Testing QueryDisplayInfo continuation\n");
5513
5514         r.in.domain_handle = handle;
5515         r.in.level = 1;
5516         r.in.start_idx = 0;
5517         r.in.max_entries = 1;
5518         r.in.buf_size = (uint32_t)-1;
5519         r.out.total_size = &total_size;
5520         r.out.returned_size = &returned_size;
5521         r.out.info = &info;
5522
5523         do {
5524                 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &r);
5525                 if (NT_STATUS_IS_OK(status) && *r.out.returned_size != 0) {
5526                         if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
5527                                 printf("expected idx %d but got %d\n",
5528                                        r.in.start_idx + 1,
5529                                        r.out.info->info1.entries[0].idx);
5530                                 break;
5531                         }
5532                 }
5533                 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
5534                     !NT_STATUS_IS_OK(status)) {
5535                         printf("QueryDisplayInfo level %u failed - %s\n",
5536                                r.in.level, nt_errstr(status));
5537                         ret = false;
5538                         break;
5539                 }
5540                 r.in.start_idx++;
5541         } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
5542                   NT_STATUS_IS_OK(status)) &&
5543                  *r.out.returned_size != 0);
5544
5545         return ret;
5546 }
5547
5548 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
5549                                  struct policy_handle *handle)
5550 {
5551         NTSTATUS status;
5552         struct samr_QueryDomainInfo r;
5553         union samr_DomainInfo *info = NULL;
5554         struct samr_SetDomainInfo s;
5555         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5556         uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1,  0,  1,  0};
5557         int i;
5558         bool ret = true;
5559         const char *domain_comment = talloc_asprintf(tctx,
5560                                   "Tortured by Samba4 RPC-SAMR: %s",
5561                                   timestring(tctx, time(NULL)));
5562
5563         s.in.domain_handle = handle;
5564         s.in.level = 4;
5565         s.in.info = talloc(tctx, union samr_DomainInfo);
5566
5567         s.in.info->oem.oem_information.string = domain_comment;
5568         status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5569         if (!NT_STATUS_IS_OK(status)) {
5570                 printf("SetDomainInfo level %u (set comment) failed - %s\n",
5571                        s.in.level, nt_errstr(status));
5572                 return false;
5573         }
5574
5575         for (i=0;i<ARRAY_SIZE(levels);i++) {
5576                 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
5577
5578                 r.in.domain_handle = handle;
5579                 r.in.level = levels[i];
5580                 r.out.info = &info;
5581
5582                 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
5583                 if (!NT_STATUS_IS_OK(status)) {
5584                         printf("QueryDomainInfo level %u failed - %s\n",
5585                                r.in.level, nt_errstr(status));
5586                         ret = false;
5587                         continue;
5588                 }
5589
5590                 switch (levels[i]) {
5591                 case 2:
5592                         if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
5593                                 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
5594                                        levels[i], info->general.oem_information.string, domain_comment);
5595                                 if (!torture_setting_bool(tctx, "samba3", false)) {
5596                                         ret = false;
5597                                 }
5598                         }
5599                         if (!info->general.primary.string) {
5600                                 printf("QueryDomainInfo level %u returned no PDC name\n",
5601                                        levels[i]);
5602                                 ret = false;
5603                         } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
5604                                 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
5605                                         printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
5606                                                levels[i], info->general.primary.string, dcerpc_server_name(p));
5607                                 }
5608                         }
5609                         break;
5610                 case 4:
5611                         if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
5612                                 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
5613                                        levels[i], info->oem.oem_information.string, domain_comment);
5614                                 if (!torture_setting_bool(tctx, "samba3", false)) {
5615                                         ret = false;
5616                                 }
5617                         }
5618                         break;
5619                 case 6:
5620                         if (!info->info6.primary.string) {
5621                                 printf("QueryDomainInfo level %u returned no PDC name\n",
5622                                        levels[i]);
5623                                 ret = false;
5624                         }
5625                         break;
5626                 case 11:
5627                         if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
5628                                 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
5629                                        levels[i], info->general2.general.oem_information.string, domain_comment);
5630                                 if (!torture_setting_bool(tctx, "samba3", false)) {
5631                                         ret = false;
5632                                 }
5633                         }
5634                         break;
5635                 }
5636
5637                 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
5638
5639                 s.in.domain_handle = handle;
5640                 s.in.level = levels[i];
5641                 s.in.info = info;
5642
5643                 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5644                 if (set_ok[i]) {
5645                         if (!NT_STATUS_IS_OK(status)) {
5646                                 printf("SetDomainInfo level %u failed - %s\n",
5647                                        r.in.level, nt_errstr(status));
5648                                 ret = false;
5649                                 continue;
5650                         }
5651                 } else {
5652                         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
5653                                 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
5654                                        r.in.level, nt_errstr(status));
5655                                 ret = false;
5656                                 continue;
5657                         }
5658                 }
5659
5660                 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
5661                 if (!NT_STATUS_IS_OK(status)) {
5662                         printf("QueryDomainInfo level %u failed - %s\n",
5663                                r.in.level, nt_errstr(status));
5664                         ret = false;
5665                         continue;
5666                 }
5667         }
5668
5669         return ret;
5670 }
5671
5672
5673 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context *tctx,
5674                                   struct policy_handle *handle)
5675 {
5676         NTSTATUS status;
5677         struct samr_QueryDomainInfo2 r;
5678         union samr_DomainInfo *info = NULL;
5679         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5680         int i;
5681         bool ret = true;
5682
5683         for (i=0;i<ARRAY_SIZE(levels);i++) {
5684                 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
5685
5686                 r.in.domain_handle = handle;
5687                 r.in.level = levels[i];
5688                 r.out.info = &info;
5689
5690                 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
5691                 if (!NT_STATUS_IS_OK(status)) {
5692                         printf("QueryDomainInfo2 level %u failed - %s\n",
5693                                r.in.level, nt_errstr(status));
5694                         ret = false;
5695                         continue;
5696                 }
5697         }
5698
5699         return true;
5700 }
5701
5702 /* Test whether querydispinfo level 5 and enumdomgroups return the same
5703    set of group names. */
5704 static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
5705                            struct policy_handle *handle)
5706 {
5707         struct samr_EnumDomainGroups q1;
5708         struct samr_QueryDisplayInfo q2;
5709         NTSTATUS status;
5710         uint32_t resume_handle=0;
5711         struct samr_SamArray *sam = NULL;
5712         uint32_t num_entries = 0;
5713         int i;
5714         bool ret = true;
5715         uint32_t total_size;
5716         uint32_t returned_size;
5717         union samr_DispInfo info;
5718
5719         int num_names = 0;
5720         const char **names = NULL;
5721
5722         torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
5723
5724         q1.in.domain_handle = handle;
5725         q1.in.resume_handle = &resume_handle;
5726         q1.in.max_size = 5;
5727         q1.out.resume_handle = &resume_handle;
5728         q1.out.num_entries = &num_entries;
5729         q1.out.sam = &sam;
5730
5731         status = STATUS_MORE_ENTRIES;
5732         while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5733                 status = dcerpc_samr_EnumDomainGroups(p, tctx, &q1);
5734
5735                 if (!NT_STATUS_IS_OK(status) &&
5736                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
5737                         break;
5738
5739                 for (i=0; i<*q1.out.num_entries; i++) {
5740                         add_string_to_array(tctx,
5741                                             sam->entries[i].name.string,
5742                                             &names, &num_names);
5743                 }
5744         }
5745
5746         torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
5747
5748         torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
5749
5750         q2.in.domain_handle = handle;
5751         q2.in.level = 5;
5752         q2.in.start_idx = 0;
5753         q2.in.max_entries = 5;
5754         q2.in.buf_size = (uint32_t)-1;
5755         q2.out.total_size = &total_size;
5756         q2.out.returned_size = &returned_size;
5757         q2.out.info = &info;
5758
5759         status = STATUS_MORE_ENTRIES;
5760         while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5761                 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &q2);
5762
5763                 if (!NT_STATUS_IS_OK(status) &&
5764                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
5765                         break;
5766
5767                 for (i=0; i<q2.out.info->info5.count; i++) {
5768                         int j;
5769                         const char *name = q2.out.info->info5.entries[i].account_name.string;
5770                         bool found = false;
5771                         for (j=0; j<num_names; j++) {
5772                                 if (names[j] == NULL)
5773                                         continue;
5774                                 if (strequal(names[j], name)) {
5775                                         names[j] = NULL;
5776                                         found = true;
5777                                         break;
5778                                 }
5779                         }
5780
5781                         if (!found) {
5782                                 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
5783                                        name);
5784                                 ret = false;
5785                         }
5786                 }
5787                 q2.in.start_idx += q2.out.info->info5.count;
5788         }
5789
5790         if (!NT_STATUS_IS_OK(status)) {
5791                 printf("QueryDisplayInfo level 5 failed - %s\n",
5792                        nt_errstr(status));
5793                 ret = false;
5794         }
5795
5796         for (i=0; i<num_names; i++) {
5797                 if (names[i] != NULL) {
5798                         printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
5799                                names[i]);
5800                         ret = false;
5801                 }
5802         }
5803
5804         return ret;
5805 }
5806
5807 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, struct torture_context *tctx,
5808                                    struct policy_handle *group_handle)
5809 {
5810         struct samr_DeleteDomainGroup d;
5811         NTSTATUS status;
5812
5813         torture_comment(tctx, "Testing DeleteDomainGroup\n");
5814
5815         d.in.group_handle = group_handle;
5816         d.out.group_handle = group_handle;
5817
5818         status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
5819         torture_assert_ntstatus_ok(tctx, status, "DeleteDomainGroup");
5820
5821         return true;
5822 }
5823
5824 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5825                                             struct policy_handle *domain_handle)
5826 {
5827         struct samr_TestPrivateFunctionsDomain r;
5828         NTSTATUS status;
5829         bool ret = true;
5830
5831         torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
5832
5833         r.in.domain_handle = domain_handle;
5834
5835         status = dcerpc_samr_TestPrivateFunctionsDomain(p, tctx, &r);
5836         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsDomain");
5837
5838         return ret;
5839 }
5840
5841 static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
5842                           struct dom_sid *domain_sid,
5843                           struct policy_handle *domain_handle)
5844 {
5845         struct samr_RidToSid r;
5846         NTSTATUS status;
5847         bool ret = true;
5848         struct dom_sid *calc_sid, *out_sid;
5849         int rids[] = { 0, 42, 512, 10200 };
5850         int i;
5851
5852         for (i=0;i<ARRAY_SIZE(rids);i++) {
5853                 torture_comment(tctx, "Testing RidToSid\n");
5854
5855                 calc_sid = dom_sid_dup(tctx, domain_sid);
5856                 r.in.domain_handle = domain_handle;
5857                 r.in.rid = rids[i];
5858                 r.out.sid = &out_sid;
5859
5860                 status = dcerpc_samr_RidToSid(p, tctx, &r);
5861                 if (!NT_STATUS_IS_OK(status)) {
5862                         printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
5863                         ret = false;
5864                 } else {
5865                         calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
5866
5867                         if (!dom_sid_equal(calc_sid, out_sid)) {
5868                                 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
5869                                        dom_sid_string(tctx, out_sid),
5870                                        dom_sid_string(tctx, calc_sid));
5871                                 ret = false;
5872                         }
5873                 }
5874         }
5875
5876         return ret;
5877 }
5878
5879 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, struct torture_context *tctx,
5880                                        struct policy_handle *domain_handle)
5881 {
5882         struct samr_GetBootKeyInformation r;
5883         NTSTATUS status;
5884         bool ret = true;
5885         uint32_t unknown = 0;
5886
5887         torture_comment(tctx, "Testing GetBootKeyInformation\n");
5888
5889         r.in.domain_handle = domain_handle;
5890         r.out.unknown = &unknown;
5891
5892         status = dcerpc_samr_GetBootKeyInformation(p, tctx, &r);
5893         if (!NT_STATUS_IS_OK(status)) {
5894                 /* w2k3 seems to fail this sometimes and pass it sometimes */
5895                 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
5896         }
5897
5898         return ret;
5899 }
5900
5901 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx,
5902                                 struct policy_handle *domain_handle,
5903                                 struct policy_handle *group_handle)
5904 {
5905         NTSTATUS status;
5906         struct samr_AddGroupMember r;
5907         struct samr_DeleteGroupMember d;
5908         struct samr_QueryGroupMember q;
5909         struct samr_RidTypeArray *rids = NULL;
5910         struct samr_SetMemberAttributesOfGroup s;
5911         uint32_t rid;
5912
5913         status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
5914         torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
5915
5916         r.in.group_handle = group_handle;
5917         r.in.rid = rid;
5918         r.in.flags = 0; /* ??? */
5919
5920         torture_comment(tctx, "Testing AddGroupMember and DeleteGroupMember\n");
5921
5922         d.in.group_handle = group_handle;
5923         d.in.rid = rid;
5924
5925         status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
5926         torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, status, "DeleteGroupMember");
5927
5928         status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5929         torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
5930
5931         status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5932         torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, status, "AddGroupMember");
5933
5934         if (torture_setting_bool(tctx, "samba4", false) ||
5935             torture_setting_bool(tctx, "samba3", false)) {
5936                 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba\n");
5937         } else {
5938                 /* this one is quite strange. I am using random inputs in the
5939                    hope of triggering an error that might give us a clue */
5940
5941                 s.in.group_handle = group_handle;
5942                 s.in.unknown1 = random();
5943                 s.in.unknown2 = random();
5944
5945                 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
5946                 torture_assert_ntstatus_ok(tctx, status, "SetMemberAttributesOfGroup");
5947         }
5948
5949         q.in.group_handle = group_handle;
5950         q.out.rids = &rids;
5951
5952         status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
5953         torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
5954
5955         status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
5956         torture_assert_ntstatus_ok(tctx, status, "DeleteGroupMember");
5957
5958         status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5959         torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
5960
5961         return true;
5962 }
5963
5964
5965 static bool test_CreateDomainGroup(struct dcerpc_pipe *p,
5966                                    struct torture_context *tctx,
5967                                    struct policy_handle *domain_handle,
5968                                    const char *group_name,
5969                                    struct policy_handle *group_handle,
5970                                    struct dom_sid *domain_sid,
5971                                    bool test_group)
5972 {
5973         NTSTATUS status;
5974         struct samr_CreateDomainGroup r;
5975         uint32_t rid;
5976         struct lsa_String name;
5977         bool ret = true;
5978
5979         init_lsa_String(&name, group_name);
5980
5981         r.in.domain_handle = domain_handle;
5982         r.in.name = &name;
5983         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5984         r.out.group_handle = group_handle;
5985         r.out.rid = &rid;
5986
5987         printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
5988
5989         status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
5990
5991         if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5992                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5993                         torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
5994                         return true;
5995                 } else {
5996                         printf("Server should have refused create of '%s', got %s instead\n", r.in.name->string,
5997                                nt_errstr(status));
5998                         return false;
5999                 }
6000         }
6001
6002         if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
6003                 if (!test_DeleteGroup_byname(p, tctx, domain_handle, r.in.name->string)) {
6004                         printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
6005                                nt_errstr(status));
6006                         return false;
6007                 }
6008                 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
6009         }
6010         if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
6011                 if (!test_DeleteUser_byname(p, tctx, domain_handle, r.in.name->string)) {
6012
6013                         printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
6014                                nt_errstr(status));
6015                         return false;
6016                 }
6017                 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
6018         }
6019         torture_assert_ntstatus_ok(tctx, status, "CreateDomainGroup");
6020
6021         if (!test_group) {
6022                 return ret;
6023         }
6024
6025         if (!test_AddGroupMember(p, tctx, domain_handle, group_handle)) {
6026                 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
6027                 ret = false;
6028         }
6029
6030         if (!test_SetGroupInfo(p, tctx, group_handle)) {
6031                 ret = false;
6032         }
6033
6034         return ret;
6035 }
6036
6037
6038 /*
6039   its not totally clear what this does. It seems to accept any sid you like.
6040 */
6041 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
6042                                                struct torture_context *tctx,
6043                                                struct policy_handle *domain_handle)
6044 {
6045         NTSTATUS status;
6046         struct samr_RemoveMemberFromForeignDomain r;
6047
6048         r.in.domain_handle = domain_handle;
6049         r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
6050
6051         status = dcerpc_samr_RemoveMemberFromForeignDomain(p, tctx, &r);
6052         torture_assert_ntstatus_ok(tctx, status, "RemoveMemberFromForeignDomain");
6053
6054         return true;
6055 }
6056
6057 static bool test_EnumDomainUsers(struct dcerpc_pipe *p,
6058                                  struct torture_context *tctx,
6059                                  struct policy_handle *domain_handle,
6060                                  uint32_t *total_num_entries_p)
6061 {
6062         NTSTATUS status;
6063         struct samr_EnumDomainUsers r;
6064         uint32_t resume_handle = 0;
6065         uint32_t num_entries = 0;
6066         uint32_t total_num_entries = 0;
6067         struct samr_SamArray *sam;
6068
6069         r.in.domain_handle = domain_handle;
6070         r.in.acct_flags = 0;
6071         r.in.max_size = (uint32_t)-1;
6072         r.in.resume_handle = &resume_handle;
6073
6074         r.out.sam = &sam;
6075         r.out.num_entries = &num_entries;
6076         r.out.resume_handle = &resume_handle;
6077
6078         printf("Testing EnumDomainUsers\n");
6079
6080         do {
6081                 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
6082                 if (NT_STATUS_IS_ERR(status)) {
6083                         torture_assert_ntstatus_ok(tctx, status,
6084                                 "failed to enumerate users");
6085                 }
6086
6087                 total_num_entries += num_entries;
6088         } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
6089
6090         if (total_num_entries_p) {
6091                 *total_num_entries_p = total_num_entries;
6092         }
6093
6094         return true;
6095 }
6096
6097 static bool test_EnumDomainGroups(struct dcerpc_pipe *p,
6098                                   struct torture_context *tctx,
6099                                   struct policy_handle *domain_handle,
6100                                   uint32_t *total_num_entries_p)
6101 {
6102         NTSTATUS status;
6103         struct samr_EnumDomainGroups r;
6104         uint32_t resume_handle = 0;
6105         uint32_t num_entries = 0;
6106         uint32_t total_num_entries = 0;
6107         struct samr_SamArray *sam;
6108
6109         r.in.domain_handle = domain_handle;
6110         r.in.max_size = (uint32_t)-1;
6111         r.in.resume_handle = &resume_handle;
6112
6113         r.out.sam = &sam;
6114         r.out.num_entries = &num_entries;
6115         r.out.resume_handle = &resume_handle;
6116
6117         printf("Testing EnumDomainGroups\n");
6118
6119         do {
6120                 status = dcerpc_samr_EnumDomainGroups(p, tctx, &r);
6121                 if (NT_STATUS_IS_ERR(status)) {
6122                         torture_assert_ntstatus_ok(tctx, status,
6123                                 "failed to enumerate groups");
6124                 }
6125
6126                 total_num_entries += num_entries;
6127         } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
6128
6129         if (total_num_entries_p) {
6130                 *total_num_entries_p = total_num_entries;
6131         }
6132
6133         return true;
6134 }
6135
6136 static bool test_EnumDomainAliases(struct dcerpc_pipe *p,
6137                                    struct torture_context *tctx,
6138                                    struct policy_handle *domain_handle,
6139                                    uint32_t *total_num_entries_p)
6140 {
6141         NTSTATUS status;
6142         struct samr_EnumDomainAliases r;
6143         uint32_t resume_handle = 0;
6144         uint32_t num_entries = 0;
6145         uint32_t total_num_entries = 0;
6146         struct samr_SamArray *sam;
6147
6148         r.in.domain_handle = domain_handle;
6149         r.in.max_size = (uint32_t)-1;
6150         r.in.resume_handle = &resume_handle;
6151
6152         r.out.sam = &sam;
6153         r.out.num_entries = &num_entries;
6154         r.out.resume_handle = &resume_handle;
6155
6156         printf("Testing EnumDomainAliases\n");
6157
6158         do {
6159                 status = dcerpc_samr_EnumDomainAliases(p, tctx, &r);
6160                 if (NT_STATUS_IS_ERR(status)) {
6161                         torture_assert_ntstatus_ok(tctx, status,
6162                                 "failed to enumerate aliases");
6163                 }
6164
6165                 total_num_entries += num_entries;
6166         } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
6167
6168         if (total_num_entries_p) {
6169                 *total_num_entries_p = total_num_entries;
6170         }
6171
6172         return true;
6173 }
6174
6175 static bool test_QueryDisplayInfo_level(struct dcerpc_pipe *p,
6176                                         struct torture_context *tctx,
6177                                         struct policy_handle *handle,
6178                                         uint16_t level,
6179                                         uint32_t *total_num_entries_p)
6180 {
6181         NTSTATUS status;
6182         struct samr_QueryDisplayInfo r;
6183         uint32_t total_num_entries = 0;
6184
6185         r.in.domain_handle = handle;
6186         r.in.level = level;
6187         r.in.start_idx = 0;
6188         r.in.max_entries = (uint32_t)-1;
6189         r.in.buf_size = (uint32_t)-1;
6190
6191         printf("Testing QueryDisplayInfo\n");
6192
6193         do {
6194                 uint32_t total_size;
6195                 uint32_t returned_size;
6196                 union samr_DispInfo info;
6197
6198                 r.out.total_size = &total_size;
6199                 r.out.returned_size = &returned_size;
6200                 r.out.info = &info;
6201
6202                 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &r);
6203                 if (NT_STATUS_IS_ERR(status)) {
6204                         torture_assert_ntstatus_ok(tctx, status,
6205                                 "failed to query displayinfo");
6206                 }
6207
6208                 if (*r.out.returned_size == 0) {
6209                         break;
6210                 }
6211
6212                 switch (r.in.level) {
6213                 case 1:
6214                         total_num_entries += info.info1.count;
6215                         r.in.start_idx += info.info1.entries[info.info1.count - 1].idx + 1;
6216                         break;
6217                 case 2:
6218                         total_num_entries += info.info2.count;
6219                         r.in.start_idx += info.info2.entries[info.info2.count - 1].idx + 1;
6220                         break;
6221                 case 3:
6222                         total_num_entries += info.info3.count;
6223                         r.in.start_idx += info.info3.entries[info.info3.count - 1].idx + 1;
6224                         break;
6225                 case 4:
6226                         total_num_entries += info.info4.count;
6227                         r.in.start_idx += info.info4.entries[info.info4.count - 1].idx + 1;
6228                         break;
6229                 case 5:
6230                         total_num_entries += info.info5.count;
6231                         r.in.start_idx += info.info5.entries[info.info5.count - 1].idx + 1;
6232                         break;
6233                 default:
6234                         return false;
6235                 }
6236
6237         } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
6238
6239         if (total_num_entries_p) {
6240                 *total_num_entries_p = total_num_entries;
6241         }
6242
6243         return true;
6244 }
6245
6246 static bool test_ManyObjects(struct dcerpc_pipe *p,
6247                              struct torture_context *tctx,
6248                              struct policy_handle *domain_handle,
6249                              struct dom_sid *domain_sid,
6250                              enum torture_samr_choice which_ops)
6251 {
6252         uint32_t num_total = 1500;
6253         uint32_t num_enum = 0;
6254         uint32_t num_disp = 0;
6255         uint32_t num_created = 0;
6256         uint32_t num_anounced = 0;
6257         bool ret = true;
6258         NTSTATUS status;
6259         uint32_t i;
6260
6261         struct policy_handle *handles = talloc_zero_array(tctx, struct policy_handle, num_total);
6262
6263         /* query */
6264
6265         {
6266                 struct samr_QueryDomainInfo2 r;
6267                 union samr_DomainInfo *info;
6268                 r.in.domain_handle = domain_handle;
6269                 r.in.level = 2;
6270                 r.out.info = &info;
6271
6272                 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
6273                 torture_assert_ntstatus_ok(tctx, status,
6274                         "failed to query domain info");
6275
6276                 switch (which_ops) {
6277                 case TORTURE_SAMR_MANY_ACCOUNTS:
6278                         num_anounced = info->general.num_users;
6279                         break;
6280                 case TORTURE_SAMR_MANY_GROUPS:
6281                         num_anounced = info->general.num_groups;
6282                         break;
6283                 case TORTURE_SAMR_MANY_ALIASES:
6284                         num_anounced = info->general.num_aliases;
6285                         break;
6286                 default:
6287                         return false;
6288                 }
6289         }
6290
6291         /* create */
6292
6293         for (i=0; i < num_total; i++) {
6294
6295                 const char *name = NULL;
6296
6297                 switch (which_ops) {
6298                 case TORTURE_SAMR_MANY_ACCOUNTS:
6299                         name = talloc_asprintf(tctx, "%s%04d", TEST_ACCOUNT_NAME, i);
6300                         ret &= test_CreateUser(p, tctx, domain_handle, name, &handles[i], domain_sid, 0, NULL, false);
6301                         break;
6302                 case TORTURE_SAMR_MANY_GROUPS:
6303                         name = talloc_asprintf(tctx, "%s%04d", TEST_GROUPNAME, i);
6304                         ret &= test_CreateDomainGroup(p, tctx, domain_handle, name, &handles[i], domain_sid, false);
6305                         break;
6306                 case TORTURE_SAMR_MANY_ALIASES:
6307                         name = talloc_asprintf(tctx, "%s%04d", TEST_ALIASNAME, i);
6308                         ret &= test_CreateAlias(p, tctx, domain_handle, name, &handles[i], domain_sid, false);
6309                         break;
6310                 default:
6311                         return false;
6312                 }
6313                 if (!policy_handle_empty(&handles[i])) {
6314                         num_created++;
6315                 }
6316         }
6317
6318         /* enum */
6319
6320         switch (which_ops) {
6321         case TORTURE_SAMR_MANY_ACCOUNTS:
6322                 ret &= test_EnumDomainUsers(p, tctx, domain_handle, &num_enum);
6323                 break;
6324         case TORTURE_SAMR_MANY_GROUPS:
6325                 ret &= test_EnumDomainGroups(p, tctx, domain_handle, &num_enum);
6326                 break;
6327         case TORTURE_SAMR_MANY_ALIASES:
6328                 ret &= test_EnumDomainAliases(p, tctx, domain_handle, &num_enum);
6329                 break;
6330         default:
6331                 return false;
6332         }
6333
6334         /* dispinfo */
6335
6336         switch (which_ops) {
6337         case TORTURE_SAMR_MANY_ACCOUNTS:
6338                 ret &= test_QueryDisplayInfo_level(p, tctx, domain_handle, 1, &num_disp);
6339                 break;
6340         case TORTURE_SAMR_MANY_GROUPS:
6341                 ret &= test_QueryDisplayInfo_level(p, tctx, domain_handle, 3, &num_disp);
6342                 break;
6343         case TORTURE_SAMR_MANY_ALIASES:
6344                 /* no aliases in dispinfo */
6345                 break;
6346         default:
6347                 return false;
6348         }
6349
6350         /* close or delete */
6351
6352         for (i=0; i < num_total; i++) {
6353
6354                 if (policy_handle_empty(&handles[i])) {
6355                         continue;
6356                 }
6357
6358                 if (torture_setting_bool(tctx, "samba3", false)) {
6359                         ret &= test_samr_handle_Close(p, tctx, &handles[i]);
6360                 } else {
6361                         switch (which_ops) {
6362                         case TORTURE_SAMR_MANY_ACCOUNTS:
6363                                 ret &= test_DeleteUser(p, tctx, &handles[i]);
6364                                 break;
6365                         case TORTURE_SAMR_MANY_GROUPS:
6366                                 ret &= test_DeleteDomainGroup(p, tctx, &handles[i]);
6367                                 break;
6368                         case TORTURE_SAMR_MANY_ALIASES:
6369                                 ret &= test_DeleteAlias(p, tctx, &handles[i]);
6370                                 break;
6371                         default:
6372                                 return false;
6373                         }
6374                 }
6375         }
6376
6377         talloc_free(handles);
6378
6379         if (which_ops == TORTURE_SAMR_MANY_ACCOUNTS && num_enum != num_anounced + num_created) {
6380                 torture_comment(tctx,
6381                                 "unexpected number of results (%u) returned in enum call, expected %u\n",
6382                                 num_enum, num_anounced + num_created);
6383
6384                 torture_comment(tctx,
6385                                 "unexpected number of results (%u) returned in dispinfo, call, expected %u\n",
6386                                 num_disp, num_anounced + num_created);
6387         }
6388         return ret;
6389 }
6390
6391 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
6392                          struct policy_handle *handle);
6393
6394 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
6395                             struct policy_handle *handle, struct dom_sid *sid,
6396                             enum torture_samr_choice which_ops,
6397                             struct cli_credentials *machine_credentials)
6398 {
6399         NTSTATUS status;
6400         struct samr_OpenDomain r;
6401         struct policy_handle domain_handle;
6402         struct policy_handle alias_handle;
6403         struct policy_handle user_handle;
6404         struct policy_handle group_handle;
6405         bool ret = true;
6406
6407         ZERO_STRUCT(alias_handle);
6408         ZERO_STRUCT(user_handle);
6409         ZERO_STRUCT(group_handle);
6410         ZERO_STRUCT(domain_handle);
6411
6412         torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
6413
6414         r.in.connect_handle = handle;
6415         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6416         r.in.sid = sid;
6417         r.out.domain_handle = &domain_handle;
6418
6419         status = dcerpc_samr_OpenDomain(p, tctx, &r);
6420         torture_assert_ntstatus_ok(tctx, status, "OpenDomain");
6421
6422         /* run the domain tests with the main handle closed - this tests
6423            the servers reference counting */
6424         torture_assert(tctx, test_samr_handle_Close(p, tctx, handle), "Failed to close SAMR handle");
6425
6426         switch (which_ops) {
6427         case TORTURE_SAMR_PASSWORDS:
6428         case TORTURE_SAMR_USER_PRIVILEGES:
6429                 if (!torture_setting_bool(tctx, "samba3", false)) {
6430                         ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, NULL);
6431                 }
6432                 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, which_ops, NULL, true);
6433                 if (!ret) {
6434                         printf("Testing PASSWORDS or PRIVILAGES on domain %s failed!\n", dom_sid_string(tctx, sid));
6435                 }
6436                 break;
6437         case TORTURE_SAMR_USER_ATTRIBUTES:
6438                 if (!torture_setting_bool(tctx, "samba3", false)) {
6439                         ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, NULL);
6440                 }
6441                 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, which_ops, NULL, true);
6442                 /* This test needs 'complex' users to validate */
6443                 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
6444                 if (!ret) {
6445                         printf("Testing ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
6446                 }
6447                 break;
6448         case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
6449                 if (!torture_setting_bool(tctx, "samba3", false)) {
6450                         ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, machine_credentials);
6451                 }
6452                 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, which_ops, machine_credentials, true);
6453                 if (!ret) {
6454                         printf("Testing PASSWORDS PWDLASTSET on domain %s failed!\n", dom_sid_string(tctx, sid));
6455                 }
6456                 break;
6457         case TORTURE_SAMR_MANY_ACCOUNTS:
6458         case TORTURE_SAMR_MANY_GROUPS:
6459         case TORTURE_SAMR_MANY_ALIASES:
6460                 ret &= test_ManyObjects(p, tctx, &domain_handle, sid, which_ops);
6461                 if (!ret) {
6462                         printf("Testing MANY-{ACCOUNTS,GROUPS,ALIASES} on domain %s failed!\n", dom_sid_string(tctx, sid));
6463                 }
6464                 break;
6465         case TORTURE_SAMR_OTHER:
6466                 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, which_ops, NULL, true);
6467                 if (!ret) {
6468                         printf("Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
6469                 }
6470                 if (!torture_setting_bool(tctx, "samba3", false)) {
6471                         ret &= test_QuerySecurity(p, tctx, &domain_handle);
6472                 }
6473                 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
6474                 ret &= test_CreateAlias(p, tctx, &domain_handle, TEST_ALIASNAME, &alias_handle, sid, true);
6475                 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, TEST_GROUPNAME, &group_handle, sid, true);
6476                 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
6477                 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
6478                 ret &= test_EnumDomainUsers_all(p, tctx, &domain_handle);
6479                 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
6480                 ret &= test_EnumDomainGroups_all(p, tctx, &domain_handle);
6481                 ret &= test_EnumDomainAliases_all(p, tctx, &domain_handle);
6482                 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
6483                 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
6484                 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
6485
6486                 if (torture_setting_bool(tctx, "samba4", false)) {
6487                         torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
6488                 } else {
6489                         ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
6490                         ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
6491                 }
6492                 ret &= test_GroupList(p, tctx, &domain_handle);
6493                 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
6494                 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
6495                 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
6496                 if (!ret) {
6497                         torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
6498                 }
6499                 break;
6500         }
6501
6502         if (!policy_handle_empty(&user_handle) &&
6503             !test_DeleteUser(p, tctx, &user_handle)) {
6504                 ret = false;
6505         }
6506
6507         if (!policy_handle_empty(&alias_handle) &&
6508             !test_DeleteAlias(p, tctx, &alias_handle)) {
6509                 ret = false;
6510         }
6511
6512         if (!policy_handle_empty(&group_handle) &&
6513             !test_DeleteDomainGroup(p, tctx, &group_handle)) {
6514                 ret = false;
6515         }
6516
6517         torture_assert(tctx, test_samr_handle_Close(p, tctx, &domain_handle), "Failed to close SAMR domain handle");
6518
6519         torture_assert(tctx, test_Connect(p, tctx, handle), "Faile to re-connect SAMR handle");
6520         /* reconnect the main handle */
6521
6522         if (!ret) {
6523                 printf("Testing domain %s failed!\n", dom_sid_string(tctx, sid));
6524         }
6525
6526         return ret;
6527 }
6528
6529 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
6530                               struct policy_handle *handle, const char *domain,
6531                               enum torture_samr_choice which_ops,
6532                               struct cli_credentials *machine_credentials)
6533 {
6534         NTSTATUS status;
6535         struct samr_LookupDomain r;
6536         struct dom_sid2 *sid = NULL;
6537         struct lsa_String n1;
6538         struct lsa_String n2;
6539         bool ret = true;
6540
6541         torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
6542
6543         /* check for correct error codes */
6544         r.in.connect_handle = handle;
6545         r.in.domain_name = &n2;
6546         r.out.sid = &sid;
6547         n2.string = NULL;
6548
6549         status = dcerpc_samr_LookupDomain(p, tctx, &r);
6550         torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, status, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
6551
6552         init_lsa_String(&n2, "xxNODOMAINxx");
6553
6554         status = dcerpc_samr_LookupDomain(p, tctx, &r);
6555         torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, status, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
6556
6557         r.in.connect_handle = handle;
6558
6559         init_lsa_String(&n1, domain);
6560         r.in.domain_name = &n1;
6561
6562         status = dcerpc_samr_LookupDomain(p, tctx, &r);
6563         torture_assert_ntstatus_ok(tctx, status, "LookupDomain");
6564
6565         if (!test_GetDomPwInfo(p, tctx, &n1)) {
6566                 ret = false;
6567         }
6568
6569         if (!test_OpenDomain(p, tctx, handle, *r.out.sid, which_ops,
6570                              machine_credentials)) {
6571                 ret = false;
6572         }
6573
6574         return ret;
6575 }
6576
6577
6578 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
6579                              struct policy_handle *handle, enum torture_samr_choice which_ops,
6580                              struct cli_credentials *machine_credentials)
6581 {
6582         NTSTATUS status;
6583         struct samr_EnumDomains r;
6584         uint32_t resume_handle = 0;
6585         uint32_t num_entries = 0;
6586         struct samr_SamArray *sam = NULL;
6587         int i;
6588         bool ret = true;
6589
6590         r.in.connect_handle = handle;
6591         r.in.resume_handle = &resume_handle;
6592         r.in.buf_size = (uint32_t)-1;
6593         r.out.resume_handle = &resume_handle;
6594         r.out.num_entries = &num_entries;
6595         r.out.sam = &sam;
6596
6597         status = dcerpc_samr_EnumDomains(p, tctx, &r);
6598         torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
6599
6600         if (!*r.out.sam) {
6601                 return false;
6602         }
6603
6604         for (i=0;i<sam->count;i++) {
6605                 if (!test_LookupDomain(p, tctx, handle,
6606                                        sam->entries[i].name.string, which_ops,
6607                                        machine_credentials)) {
6608                         ret = false;
6609                 }
6610         }
6611
6612         status = dcerpc_samr_EnumDomains(p, tctx, &r);
6613         torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
6614
6615         return ret;
6616 }
6617
6618
6619 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
6620                          struct policy_handle *handle)
6621 {
6622         NTSTATUS status;
6623         struct samr_Connect r;
6624         struct samr_Connect2 r2;
6625         struct samr_Connect3 r3;
6626         struct samr_Connect4 r4;
6627         struct samr_Connect5 r5;
6628         union samr_ConnectInfo info;
6629         struct policy_handle h;
6630         uint32_t level_out = 0;
6631         bool ret = true, got_handle = false;
6632
6633         torture_comment(tctx, "testing samr_Connect\n");
6634
6635         r.in.system_name = 0;
6636         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6637         r.out.connect_handle = &h;
6638
6639         status = dcerpc_samr_Connect(p, tctx, &r);
6640         if (!NT_STATUS_IS_OK(status)) {
6641                 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(status));
6642                 ret = false;
6643         } else {
6644                 got_handle = true;
6645                 *handle = h;
6646         }
6647
6648         torture_comment(tctx, "testing samr_Connect2\n");
6649
6650         r2.in.system_name = NULL;
6651         r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6652         r2.out.connect_handle = &h;
6653
6654         status = dcerpc_samr_Connect2(p, tctx, &r2);
6655         if (!NT_STATUS_IS_OK(status)) {
6656                 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(status));
6657                 ret = false;
6658         } else {
6659                 if (got_handle) {
6660                         test_samr_handle_Close(p, tctx, handle);
6661                 }
6662                 got_handle = true;
6663                 *handle = h;
6664         }
6665
6666         torture_comment(tctx, "testing samr_Connect3\n");
6667
6668         r3.in.system_name = NULL;
6669         r3.in.unknown = 0;
6670         r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6671         r3.out.connect_handle = &h;
6672
6673         status = dcerpc_samr_Connect3(p, tctx, &r3);
6674         if (!NT_STATUS_IS_OK(status)) {
6675                 printf("Connect3 failed - %s\n", nt_errstr(status));
6676                 ret = false;
6677         } else {
6678                 if (got_handle) {
6679                         test_samr_handle_Close(p, tctx, handle);
6680                 }
6681                 got_handle = true;
6682                 *handle = h;
6683         }
6684
6685         torture_comment(tctx, "testing samr_Connect4\n");
6686
6687         r4.in.system_name = "";
6688         r4.in.client_version = 0;
6689         r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6690         r4.out.connect_handle = &h;
6691
6692         status = dcerpc_samr_Connect4(p, tctx, &r4);
6693         if (!NT_STATUS_IS_OK(status)) {
6694                 printf("Connect4 failed - %s\n", nt_errstr(status));
6695                 ret = false;
6696         } else {
6697                 if (got_handle) {
6698                         test_samr_handle_Close(p, tctx, handle);
6699                 }
6700                 got_handle = true;
6701                 *handle = h;
6702         }
6703
6704         torture_comment(tctx, "testing samr_Connect5\n");
6705
6706         info.info1.client_version = 0;
6707         info.info1.unknown2 = 0;
6708
6709         r5.in.system_name = "";
6710         r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6711         r5.in.level_in = 1;
6712         r5.out.level_out = &level_out;
6713         r5.in.info_in = &info;
6714         r5.out.info_out = &info;
6715         r5.out.connect_handle = &h;
6716
6717         status = dcerpc_samr_Connect5(p, tctx, &r5);
6718         if (!NT_STATUS_IS_OK(status)) {
6719                 printf("Connect5 failed - %s\n", nt_errstr(status));
6720                 ret = false;
6721         } else {
6722                 if (got_handle) {
6723                         test_samr_handle_Close(p, tctx, handle);
6724                 }
6725                 got_handle = true;
6726                 *handle = h;
6727         }
6728
6729         return ret;
6730 }
6731
6732
6733 bool torture_rpc_samr(struct torture_context *torture)
6734 {
6735         NTSTATUS status;
6736         struct dcerpc_pipe *p;
6737         bool ret = true;
6738         struct policy_handle handle;
6739
6740         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6741         if (!NT_STATUS_IS_OK(status)) {
6742                 return false;
6743         }
6744
6745         ret &= test_Connect(p, torture, &handle);
6746
6747         if (!torture_setting_bool(torture, "samba3", false)) {
6748                 ret &= test_QuerySecurity(p, torture, &handle);
6749         }
6750
6751         ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER, NULL);
6752
6753         ret &= test_SetDsrmPassword(p, torture, &handle);
6754
6755         ret &= test_Shutdown(p, torture, &handle);
6756
6757         ret &= test_samr_handle_Close(p, torture, &handle);
6758
6759         return ret;
6760 }
6761
6762
6763 bool torture_rpc_samr_users(struct torture_context *torture)
6764 {
6765         NTSTATUS status;
6766         struct dcerpc_pipe *p;
6767         bool ret = true;
6768         struct policy_handle handle;
6769
6770         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6771         if (!NT_STATUS_IS_OK(status)) {
6772                 return false;
6773         }
6774
6775         ret &= test_Connect(p, torture, &handle);
6776
6777         if (!torture_setting_bool(torture, "samba3", false)) {
6778                 ret &= test_QuerySecurity(p, torture, &handle);
6779         }
6780
6781         ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES, NULL);
6782
6783         ret &= test_SetDsrmPassword(p, torture, &handle);
6784
6785         ret &= test_Shutdown(p, torture, &handle);
6786
6787         ret &= test_samr_handle_Close(p, torture, &handle);
6788
6789         return ret;
6790 }
6791
6792
6793 bool torture_rpc_samr_passwords(struct torture_context *torture)
6794 {
6795         NTSTATUS status;
6796         struct dcerpc_pipe *p;
6797         bool ret = true;
6798         struct policy_handle handle;
6799
6800         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6801         if (!NT_STATUS_IS_OK(status)) {
6802                 return false;
6803         }
6804
6805         ret &= test_Connect(p, torture, &handle);
6806
6807         ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS, NULL);
6808
6809         ret &= test_samr_handle_Close(p, torture, &handle);
6810
6811         return ret;
6812 }
6813
6814 static bool torture_rpc_samr_pwdlastset(struct torture_context *torture,
6815                                         struct dcerpc_pipe *p2,
6816                                         struct cli_credentials *machine_credentials)
6817 {
6818         NTSTATUS status;
6819         struct dcerpc_pipe *p;
6820         bool ret = true;
6821         struct policy_handle handle;
6822
6823         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6824         if (!NT_STATUS_IS_OK(status)) {
6825                 return false;
6826         }
6827
6828         ret &= test_Connect(p, torture, &handle);
6829
6830         ret &= test_EnumDomains(p, torture, &handle,
6831                                 TORTURE_SAMR_PASSWORDS_PWDLASTSET,
6832                                 machine_credentials);
6833
6834         ret &= test_samr_handle_Close(p, torture, &handle);
6835
6836         return ret;
6837 }
6838
6839 struct torture_suite *torture_rpc_samr_passwords_pwdlastset(TALLOC_CTX *mem_ctx)
6840 {
6841         struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-PASSWORDS-PWDLASTSET");
6842         struct torture_rpc_tcase *tcase;
6843
6844         tcase = torture_suite_add_machine_rpc_iface_tcase(suite, "samr",
6845                                                           &ndr_table_samr,
6846                                                           TEST_ACCOUNT_NAME_PWD);
6847
6848         torture_rpc_tcase_add_test_creds(tcase, "pwdLastSet",
6849                                          torture_rpc_samr_pwdlastset);
6850
6851         return suite;
6852 }
6853
6854 static bool torture_rpc_samr_users_privileges_delete_user(struct torture_context *torture,
6855                                                           struct dcerpc_pipe *p2,
6856                                                           struct cli_credentials *machine_credentials)
6857 {
6858         NTSTATUS status;
6859         struct dcerpc_pipe *p;
6860         bool ret = true;
6861         struct policy_handle handle;
6862
6863         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6864         if (!NT_STATUS_IS_OK(status)) {
6865                 return false;
6866         }
6867
6868         ret &= test_Connect(p, torture, &handle);
6869
6870         ret &= test_EnumDomains(p, torture, &handle,
6871                                 TORTURE_SAMR_USER_PRIVILEGES,
6872                                 machine_credentials);
6873
6874         ret &= test_samr_handle_Close(p, torture, &handle);
6875
6876         return ret;
6877 }
6878
6879 struct torture_suite *torture_rpc_samr_user_privileges(TALLOC_CTX *mem_ctx)
6880 {
6881         struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-USERS-PRIVILEGES");
6882         struct torture_rpc_tcase *tcase;
6883
6884         tcase = torture_suite_add_machine_rpc_iface_tcase(suite, "samr",
6885                                                           &ndr_table_samr,
6886                                                           TEST_ACCOUNT_NAME_PWD);
6887
6888         torture_rpc_tcase_add_test_creds(tcase, "delete_privileged_user",
6889                                          torture_rpc_samr_users_privileges_delete_user);
6890
6891         return suite;
6892 }
6893
6894 static bool torture_rpc_samr_many_accounts(struct torture_context *torture,
6895                                            struct dcerpc_pipe *p2,
6896                                            struct cli_credentials *machine_credentials)
6897 {
6898         NTSTATUS status;
6899         struct dcerpc_pipe *p;
6900         bool ret = true;
6901         struct policy_handle handle;
6902
6903         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6904         if (!NT_STATUS_IS_OK(status)) {
6905                 return false;
6906         }
6907
6908         ret &= test_Connect(p, torture, &handle);
6909
6910         ret &= test_EnumDomains(p, torture, &handle,
6911                                 TORTURE_SAMR_MANY_ACCOUNTS,
6912                                 machine_credentials);
6913
6914         ret &= test_samr_handle_Close(p, torture, &handle);
6915
6916         return ret;
6917 }
6918
6919 static bool torture_rpc_samr_many_groups(struct torture_context *torture,
6920                                          struct dcerpc_pipe *p2,
6921                                          struct cli_credentials *machine_credentials)
6922 {
6923         NTSTATUS status;
6924         struct dcerpc_pipe *p;
6925         bool ret = true;
6926         struct policy_handle handle;
6927
6928         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6929         if (!NT_STATUS_IS_OK(status)) {
6930                 return false;
6931         }
6932
6933         ret &= test_Connect(p, torture, &handle);
6934
6935         ret &= test_EnumDomains(p, torture, &handle,
6936                                 TORTURE_SAMR_MANY_GROUPS,
6937                                 machine_credentials);
6938
6939         ret &= test_samr_handle_Close(p, torture, &handle);
6940
6941         return ret;
6942 }
6943
6944 static bool torture_rpc_samr_many_aliases(struct torture_context *torture,
6945                                           struct dcerpc_pipe *p2,
6946                                           struct cli_credentials *machine_credentials)
6947 {
6948         NTSTATUS status;
6949         struct dcerpc_pipe *p;
6950         bool ret = true;
6951         struct policy_handle handle;
6952
6953         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6954         if (!NT_STATUS_IS_OK(status)) {
6955                 return false;
6956         }
6957
6958         ret &= test_Connect(p, torture, &handle);
6959
6960         ret &= test_EnumDomains(p, torture, &handle,
6961                                 TORTURE_SAMR_MANY_ALIASES,
6962                                 machine_credentials);
6963
6964         ret &= test_samr_handle_Close(p, torture, &handle);
6965
6966         return ret;
6967 }
6968
6969 struct torture_suite *torture_rpc_samr_large_dc(TALLOC_CTX *mem_ctx)
6970 {
6971         struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-LARGE-DC");
6972         struct torture_rpc_tcase *tcase;
6973
6974         tcase = torture_suite_add_machine_rpc_iface_tcase(suite, "samr",
6975                                                           &ndr_table_samr,
6976                                                           TEST_ACCOUNT_NAME);
6977
6978         torture_rpc_tcase_add_test_creds(tcase, "many_aliases",
6979                                          torture_rpc_samr_many_aliases);
6980         torture_rpc_tcase_add_test_creds(tcase, "many_groups",
6981                                          torture_rpc_samr_many_groups);
6982         torture_rpc_tcase_add_test_creds(tcase, "many_accounts",
6983                                          torture_rpc_samr_many_accounts);
6984
6985         return suite;
6986 }