s4:torture Make the RPC-SAMR-PWDLASTET more efficient
[abartlet/samba.git/.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_IS_OK(status)) {
2749                 torture_assert_ntstatus_equal(tctx, status, expected_result, "LogonSamLogonEx failed");
2750                 return true;
2751         } else {
2752                 torture_assert_ntstatus_ok(tctx, status, "LogonSamLogonEx failed");
2753         }
2754
2755         return true;
2756 }
2757
2758 static bool test_SamLogon_with_creds(struct torture_context *tctx,
2759                                      struct dcerpc_pipe *p,
2760                                      struct cli_credentials *machine_creds,
2761                                      const char *acct_name,
2762                                      char *password,
2763                                      NTSTATUS expected_samlogon_result)
2764 {
2765         bool ret = true;
2766         struct cli_credentials *test_credentials;
2767
2768         test_credentials = cli_credentials_init(tctx);
2769
2770         cli_credentials_set_workstation(test_credentials,
2771                                         cli_credentials_get_workstation(machine_creds), CRED_SPECIFIED);
2772         cli_credentials_set_domain(test_credentials,
2773                                    cli_credentials_get_domain(machine_creds), CRED_SPECIFIED);
2774         cli_credentials_set_username(test_credentials,
2775                                      acct_name, CRED_SPECIFIED);
2776         cli_credentials_set_password(test_credentials,
2777                                      password, CRED_SPECIFIED);
2778
2779         printf("testing samlogon as %s password: %s\n",
2780                 acct_name, password);
2781
2782         if (!test_SamLogon(tctx, p, test_credentials,
2783                            expected_samlogon_result)) {
2784                 torture_warning(tctx, "new password did not work\n");
2785                 ret = false;
2786         }
2787
2788         return ret;
2789 }
2790
2791 static bool test_SetPassword_level(struct dcerpc_pipe *p,
2792                                    struct dcerpc_pipe *np,
2793                                    struct torture_context *tctx,
2794                                    struct policy_handle *handle,
2795                                    uint16_t level,
2796                                    uint32_t fields_present,
2797                                    uint8_t password_expired,
2798                                    bool *matched_expected_error,
2799                                    bool use_setinfo2,
2800                                    const char *acct_name,
2801                                    char **password,
2802                                    struct cli_credentials *machine_creds,
2803                                    bool use_queryinfo2,
2804                                    NTTIME *pwdlastset,
2805                                    NTSTATUS expected_samlogon_result)
2806 {
2807         const char *fields = NULL;
2808         bool ret = true;
2809
2810         switch (level) {
2811         case 21:
2812         case 23:
2813         case 25:
2814                 fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
2815                                          fields_present);
2816                 break;
2817         default:
2818                 break;
2819         }
2820
2821         torture_comment(tctx, "Testing SetUserInfo%s level %d call "
2822                 "(password_expired: %d) %s\n",
2823                 use_setinfo2 ? "2":"", level, password_expired,
2824                 fields ? fields : "");
2825
2826         if (!test_SetUserPass_level_ex(p, tctx, handle, level,
2827                                        fields_present,
2828                                        password,
2829                                        password_expired,
2830                                        use_setinfo2,
2831                                        matched_expected_error)) {
2832                 ret = false;
2833         }
2834
2835         if (!test_QueryUserInfo_pwdlastset(p, tctx, handle,
2836                                            use_queryinfo2,
2837                                            pwdlastset)) {
2838                 ret = false;
2839         }
2840
2841         if (*matched_expected_error == true) {
2842                 return ret;
2843         }
2844
2845         if (!test_SamLogon_with_creds(tctx, np,
2846                                       machine_creds,
2847                                       acct_name,
2848                                       *password,
2849                                       expected_samlogon_result)) {
2850                 ret = false;
2851         }
2852
2853         return ret;
2854 }
2855
2856 static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
2857                                         struct torture_context *tctx,
2858                                         uint32_t acct_flags,
2859                                         const char *acct_name,
2860                                         struct policy_handle *handle,
2861                                         char **password,
2862                                         struct cli_credentials *machine_credentials)
2863 {
2864         int s = 0, q = 0, f = 0, l = 0, z = 0;
2865         struct dcerpc_binding *b;
2866         bool ret = true;
2867         int delay = 50000;
2868         bool set_levels[] = { false, true };
2869         bool query_levels[] = { false, true };
2870         uint32_t levels[] = { 18, 21, 23, 24, 25, 26 };
2871         uint32_t nonzeros[] = { 1, 24 };
2872         uint32_t fields_present[] = {
2873                 0,
2874                 SAMR_FIELD_EXPIRED_FLAG,
2875                 SAMR_FIELD_LAST_PWD_CHANGE,
2876                 SAMR_FIELD_EXPIRED_FLAG | SAMR_FIELD_LAST_PWD_CHANGE,
2877                 SAMR_FIELD_COMMENT,
2878                 SAMR_FIELD_NT_PASSWORD_PRESENT,
2879                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2880                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
2881                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE,
2882                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2883                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_EXPIRED_FLAG,
2884                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT | SAMR_FIELD_LAST_PWD_CHANGE | SAMR_FIELD_EXPIRED_FLAG
2885         };
2886         NTSTATUS status;
2887         struct dcerpc_pipe *np = NULL;
2888
2889         if (torture_setting_bool(tctx, "samba3", false)) {
2890                 delay = 1000000;
2891                 printf("Samba3 has second granularity, setting delay to: %d\n",
2892                         delay);
2893         }
2894
2895         status = torture_rpc_binding(tctx, &b);
2896         if (!NT_STATUS_IS_OK(status)) {
2897                 ret = false;
2898                 return ret;
2899         }
2900
2901         /* We have to use schannel, otherwise the SamLogonEx fails
2902          * with INTERNAL_ERROR */
2903
2904         b->flags &= ~DCERPC_AUTH_OPTIONS;
2905         b->flags |= DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_128;
2906
2907         status = dcerpc_pipe_connect_b(tctx, &np, b, 
2908                                        &ndr_table_netlogon,
2909                                        machine_credentials, tctx->ev, tctx->lp_ctx);
2910
2911         if (!NT_STATUS_IS_OK(status)) {
2912                 d_printf("RPC pipe connect as domain member failed: %s\n", nt_errstr(status));
2913                 ret = false;
2914                 return ret;
2915         }
2916
2917         /* set to 1 to enable testing for all possible opcode
2918            (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
2919            combinations */
2920 #if 0
2921 #define TEST_SET_LEVELS 1
2922 #define TEST_QUERY_LEVELS 1
2923 #endif
2924         for (l=0; l<ARRAY_SIZE(levels); l++) {
2925         for (z=0; z<ARRAY_SIZE(nonzeros); z++) {
2926         for (f=0; f<ARRAY_SIZE(fields_present); f++) {
2927 #ifdef TEST_SET_LEVELS
2928         for (s=0; s<ARRAY_SIZE(set_levels); s++) {
2929 #endif
2930 #ifdef TEST_QUERY_LEVELS
2931         for (q=0; q<ARRAY_SIZE(query_levels); q++) {
2932 #endif
2933                 NTTIME pwdlastset_old = 0;
2934                 NTTIME pwdlastset_new = 0;
2935                 bool matched_expected_error = false;
2936                 NTSTATUS expected_samlogon_result = NT_STATUS_ACCOUNT_DISABLED;
2937
2938                 torture_comment(tctx, "------------------------------\n"
2939                                 "Testing pwdLastSet attribute for flags: 0x%08x "
2940                                 "(s: %d (l: %d), q: %d)\n",
2941                                 acct_flags, s, levels[l], q);
2942
2943                 switch (levels[l]) {
2944                 case 21:
2945                 case 23:
2946                 case 25:
2947                         if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
2948                               (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT))) {
2949                                 expected_samlogon_result = NT_STATUS_WRONG_PASSWORD;
2950                         }
2951                         break;
2952                 }
2953
2954
2955                 /* set #1 */
2956
2957                 /* set a password and force password change (pwdlastset 0) by
2958                  * setting the password expired flag to a non-0 value */
2959
2960                 if (!test_SetPassword_level(p, np, tctx, handle,
2961                                             levels[l],
2962                                             fields_present[f],
2963                                             nonzeros[z],
2964                                             &matched_expected_error,
2965                                             set_levels[s],
2966                                             acct_name,
2967                                             password,
2968                                             machine_credentials,
2969                                             query_levels[q],
2970                                             &pwdlastset_old,
2971                                             expected_samlogon_result)) {
2972                         ret = false;
2973                 }
2974
2975                 if (matched_expected_error == true) {
2976                         /* skipping on expected failure */
2977                         continue;
2978                 }
2979
2980                 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
2981                  * set without the SAMR_FIELD_EXPIRED_FLAG */
2982
2983                 switch (levels[l]) {
2984                 case 21:
2985                 case 23:
2986                 case 25:
2987                         if ((pwdlastset_new != 0) &&
2988                             !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
2989                                 torture_comment(tctx, "not considering a non-0 "
2990                                         "pwdLastSet as a an error as the "
2991                                         "SAMR_FIELD_EXPIRED_FLAG has not "
2992                                         "been set\n");
2993                                 break;
2994                         }
2995                 default:
2996                         if (pwdlastset_new != 0) {
2997                                 torture_warning(tctx, "pwdLastSet test failed: "
2998                                         "expected pwdLastSet 0 but got %lld\n",
2999                                         pwdlastset_old);
3000                                 ret = false;
3001                         }
3002                         break;
3003                 }
3004
3005                 switch (levels[l]) {
3006                 case 21:
3007                 case 23:
3008                 case 25:
3009                         if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3010                              (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3011                              (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3012                              (pwdlastset_old >= pwdlastset_new)) {
3013                                 torture_warning(tctx, "pwdlastset not increasing\n");
3014                                 ret = false;
3015                         }
3016                         break;
3017                 default:
3018                         if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3019                             (pwdlastset_old >= pwdlastset_new)) {
3020                                 torture_warning(tctx, "pwdlastset not increasing\n");
3021                                 ret = false;
3022                         }
3023                         break;
3024                 }
3025
3026                 usleep(delay);
3027
3028                 /* set #2 */
3029
3030                 /* set a password, pwdlastset needs to get updated (increased
3031                  * value), password_expired value used here is 0 */
3032
3033                 if (!test_SetPassword_level(p, np, tctx, handle,
3034                                             levels[l],
3035                                             fields_present[f],
3036                                             0,
3037                                             &matched_expected_error,
3038                                             set_levels[s],
3039                                             acct_name,
3040                                             password,
3041                                             machine_credentials,
3042                                             query_levels[q],
3043                                             &pwdlastset_new,
3044                                             expected_samlogon_result)) {
3045                         ret = false;
3046                 }
3047
3048                 /* when a password has been changed, pwdlastset must not be 0 afterwards
3049                  * and must be larger then the old value */
3050
3051                 switch (levels[l]) {
3052                 case 21:
3053                 case 23:
3054                 case 25:
3055
3056                         /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3057                          * password has been changed, old and new pwdlastset
3058                          * need to be the same value */
3059
3060                         if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3061                             !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3062                               (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3063                         {
3064                                 torture_assert_int_equal(tctx, pwdlastset_old,
3065                                         pwdlastset_new, "pwdlastset must be equal");
3066                                 break;
3067                         }
3068                 default:
3069                         if (pwdlastset_old >= pwdlastset_new) {
3070                                 torture_warning(tctx, "pwdLastSet test failed: "
3071                                         "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3072                                         pwdlastset_old, pwdlastset_new);
3073                                 ret = false;
3074                         }
3075                         if (pwdlastset_new == 0) {
3076                                 torture_warning(tctx, "pwdLastSet test failed: "
3077                                         "expected non-0 pwdlastset, got: %lld\n",
3078                                         pwdlastset_new);
3079                                 ret = false;
3080                         }
3081                 }
3082
3083                 switch (levels[l]) {
3084                 case 21:
3085                 case 23:
3086                 case 25:
3087                         if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3088                              (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3089                              (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3090                              (pwdlastset_old >= pwdlastset_new)) {
3091                                 torture_warning(tctx, "pwdlastset not increasing\n");
3092                                 ret = false;
3093                         }
3094                         break;
3095                 default:
3096                         if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3097                             (pwdlastset_old >= pwdlastset_new)) {
3098                                 torture_warning(tctx, "pwdlastset not increasing\n");
3099                                 ret = false;
3100                         }
3101                         break;
3102                 }
3103
3104                 pwdlastset_old = pwdlastset_new;
3105
3106                 usleep(delay);
3107
3108                 /* set #2b */
3109
3110                 /* set a password, pwdlastset needs to get updated (increased
3111                  * value), password_expired value used here is 0 */
3112
3113                 if (!test_SetPassword_level(p, np, tctx, handle,
3114                                             levels[l],
3115                                             fields_present[f],
3116                                             0,
3117                                             &matched_expected_error,
3118                                             set_levels[s],
3119                                             acct_name,
3120                                             password,
3121                                             machine_credentials,
3122                                             query_levels[q],
3123                                             &pwdlastset_new,
3124                                             expected_samlogon_result)) {
3125                         ret = false;
3126                 }
3127
3128                 /* when a password has been changed, pwdlastset must not be 0 afterwards
3129                  * and must be larger then the old value */
3130
3131                 switch (levels[l]) {
3132                 case 21:
3133                 case 23:
3134                 case 25:
3135
3136                         /* if no password has been changed, old and new pwdlastset
3137                          * need to be the same value */
3138
3139                         if (!((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3140                               (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3141                         {
3142                                 torture_assert_int_equal(tctx, pwdlastset_old,
3143                                         pwdlastset_new, "pwdlastset must be equal");
3144                                 break;
3145                         }
3146                 default:
3147                         if (pwdlastset_old >= pwdlastset_new) {
3148                                 torture_warning(tctx, "pwdLastSet test failed: "
3149                                         "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
3150                                         pwdlastset_old, pwdlastset_new);
3151                                 ret = false;
3152                         }
3153                         if (pwdlastset_new == 0) {
3154                                 torture_warning(tctx, "pwdLastSet test failed: "
3155                                         "expected non-0 pwdlastset, got: %lld\n",
3156                                         pwdlastset_new);
3157                                 ret = false;
3158                         }
3159                 }
3160
3161                 /* set #3 */
3162
3163                 /* set a password and force password change (pwdlastset 0) by
3164                  * setting the password expired flag to a non-0 value */
3165
3166                 if (!test_SetPassword_level(p, np, tctx, handle,
3167                                             levels[l],
3168                                             fields_present[f],
3169                                             nonzeros[z],
3170                                             &matched_expected_error,
3171                                             set_levels[s],
3172                                             acct_name,
3173                                             password,
3174                                             machine_credentials,
3175                                             query_levels[q],
3176                                             &pwdlastset_new,
3177                                             expected_samlogon_result)) {
3178                         ret = false;
3179                 }
3180
3181                 /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
3182                  * set without the SAMR_FIELD_EXPIRED_FLAG */
3183
3184                 switch (levels[l]) {
3185                 case 21:
3186                 case 23:
3187                 case 25:
3188                         if ((pwdlastset_new != 0) &&
3189                             !(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG)) {
3190                                 torture_comment(tctx, "not considering a non-0 "
3191                                         "pwdLastSet as a an error as the "
3192                                         "SAMR_FIELD_EXPIRED_FLAG has not "
3193                                         "been set\n");
3194                                 break;
3195                         }
3196
3197                         /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
3198                          * password has been changed, old and new pwdlastset
3199                          * need to be the same value */
3200
3201                         if (!(fields_present[f] & SAMR_FIELD_EXPIRED_FLAG) &&
3202                             !((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3203                               (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)))
3204                         {
3205                                 torture_assert_int_equal(tctx, pwdlastset_old,
3206                                         pwdlastset_new, "pwdlastset must be equal");
3207                                 break;
3208                         }
3209                 default:
3210
3211                         if (pwdlastset_old == pwdlastset_new) {
3212                                 torture_warning(tctx, "pwdLastSet test failed: "
3213                                         "expected last pwdlastset (%lld) != new pwdlastset (%lld)\n",
3214                                         pwdlastset_old, pwdlastset_new);
3215                                 ret = false;
3216                         }
3217
3218                         if (pwdlastset_new != 0) {
3219                                 torture_warning(tctx, "pwdLastSet test failed: "
3220                                         "expected pwdLastSet 0, got %lld\n",
3221                                         pwdlastset_old);
3222                                 ret = false;
3223                         }
3224                         break;
3225                 }
3226
3227                 switch (levels[l]) {
3228                 case 21:
3229                 case 23:
3230                 case 25:
3231                         if (((fields_present[f] & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
3232                              (fields_present[f] & SAMR_FIELD_LM_PASSWORD_PRESENT)) &&
3233                              (pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3234                              (pwdlastset_old >= pwdlastset_new)) {
3235                                 torture_warning(tctx, "pwdlastset not increasing\n");
3236                                 ret = false;
3237                         }
3238                         break;
3239                 default:
3240                         if ((pwdlastset_old > 0) && (pwdlastset_new > 0) &&
3241                             (pwdlastset_old >= pwdlastset_new)) {
3242                                 torture_warning(tctx, "pwdlastset not increasing\n");
3243                                 ret = false;
3244                         }
3245                         break;
3246                 }
3247
3248                 /* if the level we are testing does not have a fields_present
3249                  * field, skip all fields present tests by setting f to to
3250                  * arraysize */
3251                 switch (levels[l]) {
3252                 case 18:
3253                 case 24:
3254                 case 26:
3255                         f = ARRAY_SIZE(fields_present);
3256                         break;
3257                 }
3258
3259 #ifdef TEST_QUERY_LEVELS
3260         }
3261 #endif
3262 #ifdef TEST_SET_LEVELS
3263         }
3264 #endif
3265         } /* fields present */
3266         } /* nonzeros */
3267         } /* levels */
3268
3269 #undef TEST_SET_LEVELS
3270 #undef TEST_QUERY_LEVELS
3271
3272         return ret;
3273 }
3274
3275 static bool test_DeleteUser_with_privs(struct dcerpc_pipe *p,
3276                                        struct dcerpc_pipe *lp,
3277                                        struct torture_context *tctx,
3278                                        struct policy_handle *domain_handle,
3279                                        struct policy_handle *lsa_handle,
3280                                        struct policy_handle *user_handle,
3281                                        const struct dom_sid *domain_sid,
3282                                        uint32_t rid,
3283                                        struct cli_credentials *machine_credentials)
3284 {
3285         NTSTATUS status;
3286         bool ret = true;
3287
3288         struct policy_handle lsa_acct_handle;
3289         struct dom_sid *user_sid;
3290
3291         user_sid = dom_sid_add_rid(tctx, domain_sid, rid);
3292
3293         {
3294                 struct lsa_EnumAccountRights r;
3295                 struct lsa_RightSet rights;
3296
3297                 printf("Testing LSA EnumAccountRights\n");
3298
3299                 r.in.handle = lsa_handle;
3300                 r.in.sid = user_sid;
3301                 r.out.rights = &rights;
3302
3303                 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3304                 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3305                         "Expected enum rights for account to fail");
3306         }
3307
3308         {
3309                 struct lsa_RightSet rights;
3310                 struct lsa_StringLarge names[2];
3311                 struct lsa_AddAccountRights r;
3312
3313                 printf("Testing LSA AddAccountRights\n");
3314
3315                 init_lsa_StringLarge(&names[0], "SeMachineAccountPrivilege");
3316                 init_lsa_StringLarge(&names[1], NULL);
3317
3318                 rights.count = 1;
3319                 rights.names = names;
3320
3321                 r.in.handle = lsa_handle;
3322                 r.in.sid = user_sid;
3323                 r.in.rights = &rights;
3324
3325                 status = dcerpc_lsa_AddAccountRights(lp, tctx, &r);
3326                 torture_assert_ntstatus_ok(tctx, status,
3327                         "Failed to add privileges");
3328         }
3329
3330         {
3331                 struct lsa_EnumAccounts r;
3332                 uint32_t resume_handle = 0;
3333                 struct lsa_SidArray lsa_sid_array;
3334                 int i;
3335                 bool found_sid = false;
3336
3337                 printf("Testing LSA EnumAccounts\n");
3338
3339                 r.in.handle = lsa_handle;
3340                 r.in.num_entries = 0x1000;
3341                 r.in.resume_handle = &resume_handle;
3342                 r.out.sids = &lsa_sid_array;
3343                 r.out.resume_handle = &resume_handle;
3344
3345                 status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
3346                 torture_assert_ntstatus_ok(tctx, status,
3347                         "Failed to enum accounts");
3348
3349                 for (i=0; i < lsa_sid_array.num_sids; i++) {
3350                         if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
3351                                 found_sid = true;
3352                         }
3353                 }
3354
3355                 torture_assert(tctx, found_sid,
3356                         "failed to list privileged account");
3357         }
3358
3359         {
3360                 struct lsa_EnumAccountRights r;
3361                 struct lsa_RightSet user_rights;
3362
3363                 printf("Testing LSA EnumAccountRights\n");
3364
3365                 r.in.handle = lsa_handle;
3366                 r.in.sid = user_sid;
3367                 r.out.rights = &user_rights;
3368
3369                 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3370                 torture_assert_ntstatus_ok(tctx, status,
3371                         "Failed to enum rights for account");
3372
3373                 if (user_rights.count < 1) {
3374                         torture_warning(tctx, "failed to find newly added rights");
3375                         return false;
3376                 }
3377         }
3378
3379         {
3380                 struct lsa_OpenAccount r;
3381
3382                 printf("Testing LSA OpenAccount\n");
3383
3384                 r.in.handle = lsa_handle;
3385                 r.in.sid = user_sid;
3386                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3387                 r.out.acct_handle = &lsa_acct_handle;
3388
3389                 status = dcerpc_lsa_OpenAccount(lp, tctx, &r);
3390                 torture_assert_ntstatus_ok(tctx, status,
3391                         "Failed to open lsa account");
3392         }
3393
3394         {
3395                 struct lsa_GetSystemAccessAccount r;
3396                 uint32_t access_mask;
3397
3398                 printf("Testing LSA GetSystemAccessAccount\n");
3399
3400                 r.in.handle = &lsa_acct_handle;
3401                 r.out.access_mask = &access_mask;
3402
3403                 status = dcerpc_lsa_GetSystemAccessAccount(lp, tctx, &r);
3404                 torture_assert_ntstatus_ok(tctx, status,
3405                         "Failed to get lsa system access account");
3406         }
3407
3408         {
3409                 struct lsa_Close r;
3410
3411                 printf("Testing LSA Close\n");
3412
3413                 r.in.handle = &lsa_acct_handle;
3414                 r.out.handle = &lsa_acct_handle;
3415
3416                 status = dcerpc_lsa_Close(lp, tctx, &r);
3417                 torture_assert_ntstatus_ok(tctx, status,
3418                         "Failed to close lsa");
3419         }
3420
3421         {
3422                 struct samr_DeleteUser r;
3423
3424                 printf("Testing SAMR DeleteUser\n");
3425
3426                 r.in.user_handle = user_handle;
3427                 r.out.user_handle = user_handle;
3428
3429                 status = dcerpc_samr_DeleteUser(p, tctx, &r);
3430                 torture_assert_ntstatus_ok(tctx, status, "Delete User failed");
3431         }
3432
3433         {
3434                 struct lsa_EnumAccounts r;
3435                 uint32_t resume_handle = 0;
3436                 struct lsa_SidArray lsa_sid_array;
3437                 int i;
3438                 bool found_sid = false;
3439
3440                 printf("Testing LSA EnumAccounts\n");
3441
3442                 r.in.handle = lsa_handle;
3443                 r.in.num_entries = 0x1000;
3444                 r.in.resume_handle = &resume_handle;
3445                 r.out.sids = &lsa_sid_array;
3446                 r.out.resume_handle = &resume_handle;
3447
3448                 status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
3449                 torture_assert_ntstatus_ok(tctx, status,
3450                         "Failed to enum accounts");
3451
3452                 for (i=0; i < lsa_sid_array.num_sids; i++) {
3453                         if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
3454                                 found_sid = true;
3455                         }
3456                 }
3457
3458                 torture_assert(tctx, found_sid,
3459                         "failed to list privileged account");
3460         }
3461
3462         {
3463                 struct lsa_EnumAccountRights r;
3464                 struct lsa_RightSet user_rights;
3465
3466                 printf("Testing LSA EnumAccountRights\n");
3467
3468                 r.in.handle = lsa_handle;
3469                 r.in.sid = user_sid;
3470                 r.out.rights = &user_rights;
3471
3472                 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3473                 torture_assert_ntstatus_ok(tctx, status,
3474                         "Failed to enum rights for account");
3475
3476                 if (user_rights.count < 1) {
3477                         torture_warning(tctx, "failed to find newly added rights");
3478                         return false;
3479                 }
3480         }
3481
3482         {
3483                 struct lsa_OpenAccount r;
3484
3485                 printf("Testing LSA OpenAccount\n");
3486
3487                 r.in.handle = lsa_handle;
3488                 r.in.sid = user_sid;
3489                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3490                 r.out.acct_handle = &lsa_acct_handle;
3491
3492                 status = dcerpc_lsa_OpenAccount(lp, tctx, &r);
3493                 torture_assert_ntstatus_ok(tctx, status,
3494                         "Failed to open lsa account");
3495         }
3496
3497         {
3498                 struct lsa_GetSystemAccessAccount r;
3499                 uint32_t access_mask;
3500
3501                 printf("Testing LSA GetSystemAccessAccount\n");
3502
3503                 r.in.handle = &lsa_acct_handle;
3504                 r.out.access_mask = &access_mask;
3505
3506                 status = dcerpc_lsa_GetSystemAccessAccount(lp, tctx, &r);
3507                 torture_assert_ntstatus_ok(tctx, status,
3508                         "Failed to get lsa system access account");
3509         }
3510
3511         {
3512                 struct lsa_DeleteObject r;
3513
3514                 printf("Testing LSA DeleteObject\n");
3515
3516                 r.in.handle = &lsa_acct_handle;
3517                 r.out.handle = &lsa_acct_handle;
3518
3519                 status = dcerpc_lsa_DeleteObject(lp, tctx, &r);
3520                 torture_assert_ntstatus_ok(tctx, status,
3521                         "Failed to delete object");
3522         }
3523
3524         {
3525                 struct lsa_EnumAccounts r;
3526                 uint32_t resume_handle = 0;
3527                 struct lsa_SidArray lsa_sid_array;
3528                 int i;
3529                 bool found_sid = false;
3530
3531                 printf("Testing LSA EnumAccounts\n");
3532
3533                 r.in.handle = lsa_handle;
3534                 r.in.num_entries = 0x1000;
3535                 r.in.resume_handle = &resume_handle;
3536                 r.out.sids = &lsa_sid_array;
3537                 r.out.resume_handle = &resume_handle;
3538
3539                 status = dcerpc_lsa_EnumAccounts(lp, tctx, &r);
3540                 torture_assert_ntstatus_ok(tctx, status,
3541                         "Failed to enum accounts");
3542
3543                 for (i=0; i < lsa_sid_array.num_sids; i++) {
3544                         if (dom_sid_equal(user_sid, lsa_sid_array.sids[i].sid)) {
3545                                 found_sid = true;
3546                         }
3547                 }
3548
3549                 torture_assert(tctx, !found_sid,
3550                         "should not have listed privileged account");
3551         }
3552
3553         {
3554                 struct lsa_EnumAccountRights r;
3555                 struct lsa_RightSet user_rights;
3556
3557                 printf("Testing LSA EnumAccountRights\n");
3558
3559                 r.in.handle = lsa_handle;
3560                 r.in.sid = user_sid;
3561                 r.out.rights = &user_rights;
3562
3563                 status = dcerpc_lsa_EnumAccountRights(lp, tctx, &r);
3564                 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
3565                         "Failed to enum rights for account");
3566         }
3567
3568         return ret;
3569 }
3570
3571 static bool test_user_ops(struct dcerpc_pipe *p,
3572                           struct torture_context *tctx,
3573                           struct policy_handle *user_handle,
3574                           struct policy_handle *domain_handle,
3575                           const struct dom_sid *domain_sid,
3576                           uint32_t base_acct_flags,
3577                           const char *base_acct_name, enum torture_samr_choice which_ops,
3578                           struct cli_credentials *machine_credentials)
3579 {
3580         char *password = NULL;
3581         struct samr_QueryUserInfo q;
3582         union samr_UserInfo *info;
3583         NTSTATUS status;
3584
3585         bool ret = true;
3586         int i;
3587         uint32_t rid;
3588         const uint32_t password_fields[] = {
3589                 SAMR_FIELD_NT_PASSWORD_PRESENT,
3590                 SAMR_FIELD_LM_PASSWORD_PRESENT,
3591                 SAMR_FIELD_NT_PASSWORD_PRESENT | SAMR_FIELD_LM_PASSWORD_PRESENT,
3592                 0
3593         };
3594
3595         status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
3596         if (!NT_STATUS_IS_OK(status)) {
3597                 ret = false;
3598         }
3599
3600         switch (which_ops) {
3601         case TORTURE_SAMR_USER_ATTRIBUTES:
3602                 if (!test_QuerySecurity(p, tctx, user_handle)) {
3603                         ret = false;
3604                 }
3605
3606                 if (!test_QueryUserInfo(p, tctx, user_handle)) {
3607                         ret = false;
3608                 }
3609
3610                 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
3611                         ret = false;
3612                 }
3613
3614                 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
3615                                       base_acct_name)) {
3616                         ret = false;
3617                 }
3618
3619                 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
3620                         ret = false;
3621                 }
3622
3623                 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
3624                         ret = false;
3625                 }
3626
3627                 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
3628                         ret = false;
3629                 }
3630                 break;
3631         case TORTURE_SAMR_PASSWORDS:
3632                 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
3633                         char simple_pass[9];
3634                         char *v = generate_random_str(tctx, 1);
3635
3636                         ZERO_STRUCT(simple_pass);
3637                         memset(simple_pass, *v, sizeof(simple_pass) - 1);
3638
3639                         printf("Testing machine account password policy rules\n");
3640
3641                         /* Workstation trust accounts don't seem to need to honour password quality policy */
3642                         if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
3643                                 ret = false;
3644                         }
3645
3646                         if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
3647                                 ret = false;
3648                         }
3649
3650                         /* reset again, to allow another 'user' password change */
3651                         if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
3652                                 ret = false;
3653                         }
3654
3655                         /* Try a 'short' password */
3656                         if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
3657                                 ret = false;
3658                         }
3659
3660                         /* Try a compleatly random password */
3661                         if (!test_ChangePasswordRandomBytes(p, tctx, base_acct_name, user_handle, &password)) {
3662                                 ret = false;
3663                         }
3664                 }
3665
3666                 for (i = 0; password_fields[i]; i++) {
3667                         if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
3668                                 ret = false;
3669                         }
3670
3671                         /* check it was set right */
3672                         if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3673                                 ret = false;
3674                         }
3675                 }
3676
3677                 for (i = 0; password_fields[i]; i++) {
3678                         if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
3679                                 ret = false;
3680                         }
3681
3682                         /* check it was set right */
3683                         if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3684                                 ret = false;
3685                         }
3686                 }
3687
3688                 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
3689                         ret = false;
3690                 }
3691
3692                 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
3693                         ret = false;
3694                 }
3695
3696                 if (torture_setting_bool(tctx, "samba4", false)) {
3697                         printf("skipping Set Password level 18 and 21 against Samba4\n");
3698                 } else {
3699
3700                         if (!test_SetUserPass_18(p, tctx, user_handle, &password)) {
3701                                 ret = false;
3702                         }
3703
3704                         if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3705                                 ret = false;
3706                         }
3707
3708                         for (i = 0; password_fields[i]; i++) {
3709
3710                                 if (password_fields[i] == SAMR_FIELD_LM_PASSWORD_PRESENT) {
3711                                         /* we need to skip as that would break
3712                                          * the ChangePasswordUser3 verify */
3713                                         continue;
3714                                 }
3715
3716                                 if (!test_SetUserPass_21(p, tctx, user_handle, password_fields[i], &password)) {
3717                                         ret = false;
3718                                 }
3719
3720                                 /* check it was set right */
3721                                 if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
3722                                         ret = false;
3723                                 }
3724                         }
3725                 }
3726
3727                 q.in.user_handle = user_handle;
3728                 q.in.level = 5;
3729                 q.out.info = &info;
3730
3731                 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
3732                 if (!NT_STATUS_IS_OK(status)) {
3733                         printf("QueryUserInfo level %u failed - %s\n",
3734                                q.in.level, nt_errstr(status));
3735                         ret = false;
3736                 } else {
3737                         uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
3738                         if ((info->info5.acct_flags) != expected_flags) {
3739                                 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
3740                                        info->info5.acct_flags,
3741                                        expected_flags);
3742                                 /* FIXME: GD */
3743                                 if (!torture_setting_bool(tctx, "samba3", false)) {
3744                                         ret = false;
3745                                 }
3746                         }
3747                         if (info->info5.rid != rid) {
3748                                 printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
3749                                        info->info5.rid, rid);
3750
3751                         }
3752                 }
3753
3754                 break;
3755
3756         case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
3757
3758                 /* test last password change timestamp behaviour */
3759                 if (!test_SetPassword_pwdlastset(p, tctx, base_acct_flags,
3760                                                  base_acct_name,
3761                                                  user_handle, &password,
3762                                                  machine_credentials)) {
3763                         ret = false;
3764                 }
3765
3766                 if (ret == true) {
3767                         torture_comment(tctx, "pwdLastSet test succeeded\n");
3768                 } else {
3769                         torture_warning(tctx, "pwdLastSet test failed\n");
3770                 }
3771
3772                 break;
3773
3774         case TORTURE_SAMR_USER_PRIVILEGES: {
3775
3776                 struct dcerpc_pipe *lp;
3777                 struct policy_handle *lsa_handle;
3778
3779                 status = torture_rpc_connection(tctx, &lp, &ndr_table_lsarpc);
3780                 torture_assert_ntstatus_ok(tctx, status, "Failed to open LSA pipe");
3781
3782                 if (!test_lsa_OpenPolicy2(lp, tctx, &lsa_handle)) {
3783                         ret = false;
3784                 }
3785
3786                 if (!test_DeleteUser_with_privs(p, lp, tctx,
3787                                                 domain_handle, lsa_handle, user_handle,
3788                                                 domain_sid, rid,
3789                                                 machine_credentials)) {
3790                         ret = false;
3791                 }
3792
3793                 if (!test_lsa_Close(lp, tctx, lsa_handle)) {
3794                         ret = false;
3795                 }
3796
3797                 if (!ret) {
3798                         torture_warning(tctx, "privileged user delete test failed\n");
3799                 }
3800
3801                 break;
3802         }
3803         case TORTURE_SAMR_OTHER:
3804                 /* We just need the account to exist */
3805                 break;
3806         }
3807         return ret;
3808 }
3809
3810 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
3811                            struct policy_handle *alias_handle,
3812                            const struct dom_sid *domain_sid)
3813 {
3814         bool ret = true;
3815
3816         if (!torture_setting_bool(tctx, "samba3", false)) {
3817                 if (!test_QuerySecurity(p, tctx, alias_handle)) {
3818                         ret = false;
3819                 }
3820         }
3821
3822         if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
3823                 ret = false;
3824         }
3825
3826         if (!test_SetAliasInfo(p, tctx, alias_handle)) {
3827                 ret = false;
3828         }
3829
3830         if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
3831                 ret = false;
3832         }
3833
3834         if (torture_setting_bool(tctx, "samba4", false)) {
3835                 printf("skipping MultipleMembers Alias tests against Samba4\n");
3836                 return ret;
3837         }
3838
3839         if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
3840                 ret = false;
3841         }
3842
3843         return ret;
3844 }
3845
3846
3847 static bool test_DeleteUser(struct dcerpc_pipe *p, struct torture_context *tctx,
3848                                      struct policy_handle *user_handle)
3849 {
3850         struct samr_DeleteUser d;
3851         NTSTATUS status;
3852         torture_comment(tctx, "Testing DeleteUser\n");
3853
3854         d.in.user_handle = user_handle;
3855         d.out.user_handle = user_handle;
3856
3857         status = dcerpc_samr_DeleteUser(p, tctx, &d);
3858         torture_assert_ntstatus_ok(tctx, status, "DeleteUser");
3859
3860         return true;
3861 }
3862
3863 bool test_DeleteUser_byname(struct dcerpc_pipe *p,
3864                             struct torture_context *tctx,
3865                             struct policy_handle *handle, const char *name)
3866 {
3867         NTSTATUS status;
3868         struct samr_DeleteUser d;
3869         struct policy_handle user_handle;
3870         uint32_t rid;
3871
3872         status = test_LookupName(p, tctx, handle, name, &rid);
3873         if (!NT_STATUS_IS_OK(status)) {
3874                 goto failed;
3875         }
3876
3877         status = test_OpenUser_byname(p, tctx, handle, name, &user_handle);
3878         if (!NT_STATUS_IS_OK(status)) {
3879                 goto failed;
3880         }
3881
3882         d.in.user_handle = &user_handle;
3883         d.out.user_handle = &user_handle;
3884         status = dcerpc_samr_DeleteUser(p, tctx, &d);
3885         if (!NT_STATUS_IS_OK(status)) {
3886                 goto failed;
3887         }
3888
3889         return true;
3890
3891 failed:
3892         printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
3893         return false;
3894 }
3895
3896
3897 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p,
3898                                     struct torture_context *tctx,
3899                                     struct policy_handle *handle, const char *name)
3900 {
3901         NTSTATUS status;
3902         struct samr_OpenGroup r;
3903         struct samr_DeleteDomainGroup d;
3904         struct policy_handle group_handle;
3905         uint32_t rid;
3906
3907         status = test_LookupName(p, tctx, handle, name, &rid);
3908         if (!NT_STATUS_IS_OK(status)) {
3909                 goto failed;
3910         }
3911
3912         r.in.domain_handle = handle;
3913         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3914         r.in.rid = rid;
3915         r.out.group_handle = &group_handle;
3916         status = dcerpc_samr_OpenGroup(p, tctx, &r);
3917         if (!NT_STATUS_IS_OK(status)) {
3918                 goto failed;
3919         }
3920
3921         d.in.group_handle = &group_handle;
3922         d.out.group_handle = &group_handle;
3923         status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
3924         if (!NT_STATUS_IS_OK(status)) {
3925                 goto failed;
3926         }
3927
3928         return true;
3929
3930 failed:
3931         printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
3932         return false;
3933 }
3934
3935
3936 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p,
3937                                     struct torture_context *tctx,
3938                                     struct policy_handle *domain_handle,
3939                                     const char *name)
3940 {
3941         NTSTATUS status;
3942         struct samr_OpenAlias r;
3943         struct samr_DeleteDomAlias d;
3944         struct policy_handle alias_handle;
3945         uint32_t rid;
3946
3947         printf("testing DeleteAlias_byname\n");
3948
3949         status = test_LookupName(p, tctx, domain_handle, name, &rid);
3950         if (!NT_STATUS_IS_OK(status)) {
3951                 goto failed;
3952         }
3953
3954         r.in.domain_handle = domain_handle;
3955         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3956         r.in.rid = rid;
3957         r.out.alias_handle = &alias_handle;
3958         status = dcerpc_samr_OpenAlias(p, tctx, &r);
3959         if (!NT_STATUS_IS_OK(status)) {
3960                 goto failed;
3961         }
3962
3963         d.in.alias_handle = &alias_handle;
3964         d.out.alias_handle = &alias_handle;
3965         status = dcerpc_samr_DeleteDomAlias(p, tctx, &d);
3966         if (!NT_STATUS_IS_OK(status)) {
3967                 goto failed;
3968         }
3969
3970         return true;
3971
3972 failed:
3973         printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
3974         return false;
3975 }
3976
3977 static bool test_DeleteAlias(struct dcerpc_pipe *p,
3978                              struct torture_context *tctx,
3979                              struct policy_handle *alias_handle)
3980 {
3981         struct samr_DeleteDomAlias d;
3982         NTSTATUS status;
3983         bool ret = true;
3984         printf("Testing DeleteAlias\n");
3985
3986         d.in.alias_handle = alias_handle;
3987         d.out.alias_handle = alias_handle;
3988
3989         status = dcerpc_samr_DeleteDomAlias(p, tctx, &d);
3990         if (!NT_STATUS_IS_OK(status)) {
3991                 printf("DeleteAlias failed - %s\n", nt_errstr(status));
3992                 ret = false;
3993         }
3994
3995         return ret;
3996 }
3997
3998 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
3999                              struct policy_handle *domain_handle,
4000                              const char *alias_name,
4001                              struct policy_handle *alias_handle,
4002                              const struct dom_sid *domain_sid,
4003                              bool test_alias)
4004 {
4005         NTSTATUS status;
4006         struct samr_CreateDomAlias r;
4007         struct lsa_String name;
4008         uint32_t rid;
4009         bool ret = true;
4010
4011         init_lsa_String(&name, alias_name);
4012         r.in.domain_handle = domain_handle;
4013         r.in.alias_name = &name;
4014         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4015         r.out.alias_handle = alias_handle;
4016         r.out.rid = &rid;
4017
4018         printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
4019
4020         status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
4021
4022         if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4023                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4024                         printf("Server correctly refused create of '%s'\n", r.in.alias_name->string);
4025                         return true;
4026                 } else {
4027                         printf("Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string,
4028                                nt_errstr(status));
4029                         return false;
4030                 }
4031         }
4032
4033         if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
4034                 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
4035                         return false;
4036                 }
4037                 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
4038         }
4039
4040         if (!NT_STATUS_IS_OK(status)) {
4041                 printf("CreateAlias failed - %s\n", nt_errstr(status));
4042                 return false;
4043         }
4044
4045         if (!test_alias) {
4046                 return ret;
4047         }
4048
4049         if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
4050                 ret = false;
4051         }
4052
4053         return ret;
4054 }
4055
4056 static bool test_ChangePassword(struct dcerpc_pipe *p,
4057                                 struct torture_context *tctx,
4058                                 const char *acct_name,
4059                                 struct policy_handle *domain_handle, char **password)
4060 {
4061         bool ret = true;
4062
4063         if (!*password) {
4064                 return false;
4065         }
4066
4067         if (!test_ChangePasswordUser(p, tctx, acct_name, domain_handle, password)) {
4068                 ret = false;
4069         }
4070
4071         if (!test_ChangePasswordUser2(p, tctx, acct_name, password, 0, true)) {
4072                 ret = false;
4073         }
4074
4075         if (!test_OemChangePasswordUser2(p, tctx, acct_name, domain_handle, password)) {
4076                 ret = false;
4077         }
4078
4079         /* test what happens when setting the old password again */
4080         if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, *password, 0, true)) {
4081                 ret = false;
4082         }
4083
4084         {
4085                 char simple_pass[9];
4086                 char *v = generate_random_str(tctx, 1);
4087
4088                 ZERO_STRUCT(simple_pass);
4089                 memset(simple_pass, *v, sizeof(simple_pass) - 1);
4090
4091                 /* test what happens when picking a simple password */
4092                 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, simple_pass, 0, true)) {
4093                         ret = false;
4094                 }
4095         }
4096
4097         /* set samr_SetDomainInfo level 1 with min_length 5 */
4098         {
4099                 struct samr_QueryDomainInfo r;
4100                 union samr_DomainInfo *info = NULL;
4101                 struct samr_SetDomainInfo s;
4102                 uint16_t len_old, len;
4103                 uint32_t pwd_prop_old;
4104                 int64_t min_pwd_age_old;
4105                 NTSTATUS status;
4106
4107                 len = 5;
4108
4109                 r.in.domain_handle = domain_handle;
4110                 r.in.level = 1;
4111                 r.out.info = &info;
4112
4113                 printf("testing samr_QueryDomainInfo level 1\n");
4114                 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
4115                 if (!NT_STATUS_IS_OK(status)) {
4116                         return false;
4117                 }
4118
4119                 s.in.domain_handle = domain_handle;
4120                 s.in.level = 1;
4121                 s.in.info = info;
4122
4123                 /* remember the old min length, so we can reset it */
4124                 len_old = s.in.info->info1.min_password_length;
4125                 s.in.info->info1.min_password_length = len;
4126                 pwd_prop_old = s.in.info->info1.password_properties;
4127                 /* turn off password complexity checks for this test */
4128                 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
4129
4130                 min_pwd_age_old = s.in.info->info1.min_password_age;
4131                 s.in.info->info1.min_password_age = 0;
4132
4133                 printf("testing samr_SetDomainInfo level 1\n");
4134                 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
4135                 if (!NT_STATUS_IS_OK(status)) {
4136                         return false;
4137                 }
4138
4139                 printf("calling test_ChangePasswordUser3 with too short password\n");
4140
4141                 if (!test_ChangePasswordUser3(p, tctx, acct_name, len - 1, password, NULL, 0, true)) {
4142                         ret = false;
4143                 }
4144
4145                 s.in.info->info1.min_password_length = len_old;
4146                 s.in.info->info1.password_properties = pwd_prop_old;
4147                 s.in.info->info1.min_password_age = min_pwd_age_old;
4148
4149                 printf("testing samr_SetDomainInfo level 1\n");
4150                 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
4151                 if (!NT_STATUS_IS_OK(status)) {
4152                         return false;
4153                 }
4154
4155         }
4156
4157         {
4158                 NTSTATUS status;
4159                 struct samr_OpenUser r;
4160                 struct samr_QueryUserInfo q;
4161                 union samr_UserInfo *info;
4162                 struct samr_LookupNames n;
4163                 struct policy_handle user_handle;
4164                 struct samr_Ids rids, types;
4165
4166                 n.in.domain_handle = domain_handle;
4167                 n.in.num_names = 1;
4168                 n.in.names = talloc_array(tctx, struct lsa_String, 1);
4169                 n.in.names[0].string = acct_name;
4170                 n.out.rids = &rids;
4171                 n.out.types = &types;
4172
4173                 status = dcerpc_samr_LookupNames(p, tctx, &n);
4174                 if (!NT_STATUS_IS_OK(status)) {
4175                         printf("LookupNames failed - %s\n", nt_errstr(status));
4176                         return false;
4177                 }
4178
4179                 r.in.domain_handle = domain_handle;
4180                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4181                 r.in.rid = n.out.rids->ids[0];
4182                 r.out.user_handle = &user_handle;
4183
4184                 status = dcerpc_samr_OpenUser(p, tctx, &r);
4185                 if (!NT_STATUS_IS_OK(status)) {
4186                         printf("OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(status));
4187                         return false;
4188                 }
4189
4190                 q.in.user_handle = &user_handle;
4191                 q.in.level = 5;
4192                 q.out.info = &info;
4193
4194                 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
4195                 if (!NT_STATUS_IS_OK(status)) {
4196                         printf("QueryUserInfo failed - %s\n", nt_errstr(status));
4197                         return false;
4198                 }
4199
4200                 printf("calling test_ChangePasswordUser3 with too early password change\n");
4201
4202                 if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL,
4203                                               info->info5.last_password_change, true)) {
4204                         ret = false;
4205                 }
4206         }
4207
4208         /* we change passwords twice - this has the effect of verifying
4209            they were changed correctly for the final call */
4210         if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
4211                 ret = false;
4212         }
4213
4214         if (!test_ChangePasswordUser3(p, tctx, acct_name, 0, password, NULL, 0, true)) {
4215                 ret = false;
4216         }
4217
4218         return ret;
4219 }
4220
4221 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
4222                             struct policy_handle *domain_handle,
4223                             const char *user_name,
4224                             struct policy_handle *user_handle_out,
4225                             struct dom_sid *domain_sid,
4226                             enum torture_samr_choice which_ops,
4227                             struct cli_credentials *machine_credentials,
4228                             bool test_user)
4229 {
4230
4231         TALLOC_CTX *user_ctx;
4232
4233         NTSTATUS status;
4234         struct samr_CreateUser r;
4235         struct samr_QueryUserInfo q;
4236         union samr_UserInfo *info;
4237         struct samr_DeleteUser d;
4238         uint32_t rid;
4239
4240         /* This call creates a 'normal' account - check that it really does */
4241         const uint32_t acct_flags = ACB_NORMAL;
4242         struct lsa_String name;
4243         bool ret = true;
4244
4245         struct policy_handle user_handle;
4246         user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
4247         init_lsa_String(&name, user_name);
4248
4249         r.in.domain_handle = domain_handle;
4250         r.in.account_name = &name;
4251         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4252         r.out.user_handle = &user_handle;
4253         r.out.rid = &rid;
4254
4255         printf("Testing CreateUser(%s)\n", r.in.account_name->string);
4256
4257         status = dcerpc_samr_CreateUser(p, user_ctx, &r);
4258
4259         if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4260                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
4261                         printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
4262                         return true;
4263                 } else {
4264                         printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
4265                                nt_errstr(status));
4266                         return false;
4267                 }
4268         }
4269
4270         if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4271                 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
4272                         talloc_free(user_ctx);
4273                         return false;
4274                 }
4275                 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
4276         }
4277
4278         if (!NT_STATUS_IS_OK(status)) {
4279                 talloc_free(user_ctx);
4280                 printf("CreateUser failed - %s\n", nt_errstr(status));
4281                 return false;
4282         }
4283
4284         if (!test_user) {
4285                 if (user_handle_out) {
4286                         *user_handle_out = user_handle;
4287                 }
4288                 return ret;
4289         }
4290
4291         {
4292                 q.in.user_handle = &user_handle;
4293                 q.in.level = 16;
4294                 q.out.info = &info;
4295
4296                 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
4297                 if (!NT_STATUS_IS_OK(status)) {
4298                         printf("QueryUserInfo level %u failed - %s\n",
4299                                q.in.level, nt_errstr(status));
4300                         ret = false;
4301                 } else {
4302                         if ((info->info16.acct_flags & acct_flags) != acct_flags) {
4303                                 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4304                                        info->info16.acct_flags,
4305                                        acct_flags);
4306                                 ret = false;
4307                         }
4308                 }
4309
4310                 if (!test_user_ops(p, tctx, &user_handle, domain_handle,
4311                                    domain_sid, acct_flags, name.string, which_ops,
4312                                    machine_credentials)) {
4313                         ret = false;
4314                 }
4315
4316                 if (user_handle_out) {
4317                         *user_handle_out = user_handle;
4318                 } else {
4319                         printf("Testing DeleteUser (createuser test)\n");
4320
4321                         d.in.user_handle = &user_handle;
4322                         d.out.user_handle = &user_handle;
4323
4324                         status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
4325                         if (!NT_STATUS_IS_OK(status)) {
4326                                 printf("DeleteUser failed - %s\n", nt_errstr(status));
4327                                 ret = false;
4328                         }
4329                 }
4330
4331         }
4332
4333         talloc_free(user_ctx);
4334
4335         return ret;
4336 }
4337
4338
4339 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
4340                              struct policy_handle *domain_handle,
4341                              struct dom_sid *domain_sid,
4342                              enum torture_samr_choice which_ops,
4343                              struct cli_credentials *machine_credentials)
4344 {
4345         NTSTATUS status;
4346         struct samr_CreateUser2 r;
4347         struct samr_QueryUserInfo q;
4348         union samr_UserInfo *info;
4349         struct samr_DeleteUser d;
4350         struct policy_handle user_handle;
4351         uint32_t rid;
4352         struct lsa_String name;
4353         bool ret = true;
4354         int i;
4355
4356         struct {
4357                 uint32_t acct_flags;
4358                 const char *account_name;
4359                 NTSTATUS nt_status;
4360         } account_types[] = {
4361                 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
4362                 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4363                 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4364                 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
4365                 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4366                 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4367                 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
4368                 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4369                 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
4370                 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
4371                 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
4372                 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
4373                 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4374                 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
4375                 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
4376         };
4377
4378         for (i = 0; account_types[i].account_name; i++) {
4379                 TALLOC_CTX *user_ctx;
4380                 uint32_t acct_flags = account_types[i].acct_flags;
4381                 uint32_t access_granted;
4382                 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
4383                 init_lsa_String(&name, account_types[i].account_name);
4384
4385                 r.in.domain_handle = domain_handle;
4386                 r.in.account_name = &name;
4387                 r.in.acct_flags = acct_flags;
4388                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4389                 r.out.user_handle = &user_handle;
4390                 r.out.access_granted = &access_granted;
4391                 r.out.rid = &rid;
4392
4393                 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
4394
4395                 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
4396
4397                 if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
4398                         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
4399                                 printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
4400                                 continue;
4401                         } else {
4402                                 printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string,
4403                                        nt_errstr(status));
4404                                 ret = false;
4405                                 continue;
4406                         }
4407                 }
4408
4409                 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4410                         if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
4411                                 talloc_free(user_ctx);
4412                                 ret = false;
4413                                 continue;
4414                         }
4415                         status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
4416
4417                 }
4418                 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
4419                         printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n",
4420                                nt_errstr(status), nt_errstr(account_types[i].nt_status));
4421                         ret = false;
4422                 }
4423
4424                 if (NT_STATUS_IS_OK(status)) {
4425                         q.in.user_handle = &user_handle;
4426                         q.in.level = 5;
4427                         q.out.info = &info;
4428
4429                         status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
4430                         if (!NT_STATUS_IS_OK(status)) {
4431                                 printf("QueryUserInfo level %u failed - %s\n",
4432                                        q.in.level, nt_errstr(status));
4433                                 ret = false;
4434                         } else {
4435                                 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
4436                                 if (acct_flags == ACB_NORMAL) {
4437                                         expected_flags |= ACB_PW_EXPIRED;
4438                                 }
4439                                 if ((info->info5.acct_flags) != expected_flags) {
4440                                         printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
4441                                                info->info5.acct_flags,
4442                                                expected_flags);
4443                                         ret = false;
4444                                 }
4445                                 switch (acct_flags) {
4446                                 case ACB_SVRTRUST:
4447                                         if (info->info5.primary_gid != DOMAIN_RID_DCS) {
4448                                                 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
4449                                                        DOMAIN_RID_DCS, info->info5.primary_gid);
4450                                                 ret = false;
4451                                         }
4452                                         break;
4453                                 case ACB_WSTRUST:
4454                                         if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
4455                                                 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
4456                                                        DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
4457                                                 ret = false;
4458                                         }
4459                                         break;
4460                                 case ACB_NORMAL:
4461                                         if (info->info5.primary_gid != DOMAIN_RID_USERS) {
4462                                                 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
4463                                                        DOMAIN_RID_USERS, info->info5.primary_gid);
4464                                                 ret = false;
4465                                         }
4466                                         break;
4467                                 }
4468                         }
4469
4470                         if (!test_user_ops(p, tctx, &user_handle, domain_handle,
4471                                            domain_sid, acct_flags, name.string, which_ops,
4472                                            machine_credentials)) {
4473                                 ret = false;
4474                         }
4475
4476                         if (!policy_handle_empty(&user_handle)) {
4477                                 printf("Testing DeleteUser (createuser2 test)\n");
4478
4479                                 d.in.user_handle = &user_handle;
4480                                 d.out.user_handle = &user_handle;
4481
4482                                 status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
4483                                 if (!NT_STATUS_IS_OK(status)) {
4484                                         printf("DeleteUser failed - %s\n", nt_errstr(status));
4485                                         ret = false;
4486                                 }
4487                         }
4488                 }
4489                 talloc_free(user_ctx);
4490         }
4491
4492         return ret;
4493 }
4494
4495 static bool test_QueryAliasInfo(struct dcerpc_pipe *p,
4496                                 struct torture_context *tctx,
4497                                 struct policy_handle *handle)
4498 {
4499         NTSTATUS status;
4500         struct samr_QueryAliasInfo r;
4501         union samr_AliasInfo *info;
4502         uint16_t levels[] = {1, 2, 3};
4503         int i;
4504         bool ret = true;
4505
4506         for (i=0;i<ARRAY_SIZE(levels);i++) {
4507                 printf("Testing QueryAliasInfo level %u\n", levels[i]);
4508
4509                 r.in.alias_handle = handle;
4510                 r.in.level = levels[i];
4511                 r.out.info = &info;
4512
4513                 status = dcerpc_samr_QueryAliasInfo(p, tctx, &r);
4514                 if (!NT_STATUS_IS_OK(status)) {
4515                         printf("QueryAliasInfo level %u failed - %s\n",
4516                                levels[i], nt_errstr(status));
4517                         ret = false;
4518                 }
4519         }
4520
4521         return ret;
4522 }
4523
4524 static bool test_QueryGroupInfo(struct dcerpc_pipe *p,
4525                                 struct torture_context *tctx,
4526                                 struct policy_handle *handle)
4527 {
4528         NTSTATUS status;
4529         struct samr_QueryGroupInfo r;
4530         union samr_GroupInfo *info;
4531         uint16_t levels[] = {1, 2, 3, 4, 5};
4532         int i;
4533         bool ret = true;
4534
4535         for (i=0;i<ARRAY_SIZE(levels);i++) {
4536                 printf("Testing QueryGroupInfo level %u\n", levels[i]);
4537
4538                 r.in.group_handle = handle;
4539                 r.in.level = levels[i];
4540                 r.out.info = &info;
4541
4542                 status = dcerpc_samr_QueryGroupInfo(p, tctx, &r);
4543                 if (!NT_STATUS_IS_OK(status)) {
4544                         printf("QueryGroupInfo level %u failed - %s\n",
4545                                levels[i], nt_errstr(status));
4546                         ret = false;
4547                 }
4548         }
4549
4550         return ret;
4551 }
4552
4553 static bool test_QueryGroupMember(struct dcerpc_pipe *p,
4554                                   struct torture_context *tctx,
4555                                   struct policy_handle *handle)
4556 {
4557         NTSTATUS status;
4558         struct samr_QueryGroupMember r;
4559         struct samr_RidTypeArray *rids = NULL;
4560         bool ret = true;
4561
4562         printf("Testing QueryGroupMember\n");
4563
4564         r.in.group_handle = handle;
4565         r.out.rids = &rids;
4566
4567         status = dcerpc_samr_QueryGroupMember(p, tctx, &r);
4568         if (!NT_STATUS_IS_OK(status)) {
4569                 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
4570                 ret = false;
4571         }
4572
4573         return ret;
4574 }
4575
4576
4577 static bool test_SetGroupInfo(struct dcerpc_pipe *p,
4578                               struct torture_context *tctx,
4579                               struct policy_handle *handle)
4580 {
4581         NTSTATUS status;
4582         struct samr_QueryGroupInfo r;
4583         union samr_GroupInfo *info;
4584         struct samr_SetGroupInfo s;
4585         uint16_t levels[] = {1, 2, 3, 4};
4586         uint16_t set_ok[] = {0, 1, 1, 1};
4587         int i;
4588         bool ret = true;
4589
4590         for (i=0;i<ARRAY_SIZE(levels);i++) {
4591                 printf("Testing QueryGroupInfo level %u\n", levels[i]);
4592
4593                 r.in.group_handle = handle;
4594                 r.in.level = levels[i];
4595                 r.out.info = &info;
4596
4597                 status = dcerpc_samr_QueryGroupInfo(p, tctx, &r);
4598                 if (!NT_STATUS_IS_OK(status)) {
4599                         printf("QueryGroupInfo level %u failed - %s\n",
4600                                levels[i], nt_errstr(status));
4601                         ret = false;
4602                 }
4603
4604                 printf("Testing SetGroupInfo level %u\n", levels[i]);
4605
4606                 s.in.group_handle = handle;
4607                 s.in.level = levels[i];
4608                 s.in.info = *r.out.info;
4609
4610 #if 0
4611                 /* disabled this, as it changes the name only from the point of view of samr,
4612                    but leaves the name from the point of view of w2k3 internals (and ldap). This means
4613                    the name is still reserved, so creating the old name fails, but deleting by the old name
4614                    also fails */
4615                 if (s.in.level == 2) {
4616                         init_lsa_String(&s.in.info->string, "NewName");
4617                 }
4618 #endif
4619
4620                 if (s.in.level == 4) {
4621                         init_lsa_String(&s.in.info->description, "test description");
4622                 }
4623
4624                 status = dcerpc_samr_SetGroupInfo(p, tctx, &s);
4625                 if (set_ok[i]) {
4626                         if (!NT_STATUS_IS_OK(status)) {
4627                                 printf("SetGroupInfo level %u failed - %s\n",
4628                                        r.in.level, nt_errstr(status));
4629                                 ret = false;
4630                                 continue;
4631                         }
4632                 } else {
4633                         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
4634                                 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
4635                                        r.in.level, nt_errstr(status));
4636                                 ret = false;
4637                                 continue;
4638                         }
4639                 }
4640         }
4641
4642         return ret;
4643 }
4644
4645 static bool test_QueryUserInfo(struct dcerpc_pipe *p,
4646                                struct torture_context *tctx,
4647                                struct policy_handle *handle)
4648 {
4649         NTSTATUS status;
4650         struct samr_QueryUserInfo r;
4651         union samr_UserInfo *info;
4652         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4653                            11, 12, 13, 14, 16, 17, 20, 21};
4654         int i;
4655         bool ret = true;
4656
4657         for (i=0;i<ARRAY_SIZE(levels);i++) {
4658                 printf("Testing QueryUserInfo level %u\n", levels[i]);
4659
4660                 r.in.user_handle = handle;
4661                 r.in.level = levels[i];
4662                 r.out.info = &info;
4663
4664                 status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
4665                 if (!NT_STATUS_IS_OK(status)) {
4666                         printf("QueryUserInfo level %u failed - %s\n",
4667                                levels[i], nt_errstr(status));
4668                         ret = false;
4669                 }
4670         }
4671
4672         return ret;
4673 }
4674
4675 static bool test_QueryUserInfo2(struct dcerpc_pipe *p,
4676                                 struct torture_context *tctx,
4677                                 struct policy_handle *handle)
4678 {
4679         NTSTATUS status;
4680         struct samr_QueryUserInfo2 r;
4681         union samr_UserInfo *info;
4682         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
4683                            11, 12, 13, 14, 16, 17, 20, 21};
4684         int i;
4685         bool ret = true;
4686
4687         for (i=0;i<ARRAY_SIZE(levels);i++) {
4688                 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
4689
4690                 r.in.user_handle = handle;
4691                 r.in.level = levels[i];
4692                 r.out.info = &info;
4693
4694                 status = dcerpc_samr_QueryUserInfo2(p, tctx, &r);
4695                 if (!NT_STATUS_IS_OK(status)) {
4696                         printf("QueryUserInfo2 level %u failed - %s\n",
4697                                levels[i], nt_errstr(status));
4698                         ret = false;
4699                 }
4700         }
4701
4702         return ret;
4703 }
4704
4705 static bool test_OpenUser(struct dcerpc_pipe *p,
4706                           struct torture_context *tctx,
4707                           struct policy_handle *handle, uint32_t rid)
4708 {
4709         NTSTATUS status;
4710         struct samr_OpenUser r;
4711         struct policy_handle user_handle;
4712         bool ret = true;
4713
4714         printf("Testing OpenUser(%u)\n", rid);
4715
4716         r.in.domain_handle = handle;
4717         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4718         r.in.rid = rid;
4719         r.out.user_handle = &user_handle;
4720
4721         status = dcerpc_samr_OpenUser(p, tctx, &r);
4722         if (!NT_STATUS_IS_OK(status)) {
4723                 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
4724                 return false;
4725         }
4726
4727         if (!test_QuerySecurity(p, tctx, &user_handle)) {
4728                 ret = false;
4729         }
4730
4731         if (!test_QueryUserInfo(p, tctx, &user_handle)) {
4732                 ret = false;
4733         }
4734
4735         if (!test_QueryUserInfo2(p, tctx, &user_handle)) {
4736                 ret = false;
4737         }
4738
4739         if (!test_GetUserPwInfo(p, tctx, &user_handle)) {
4740                 ret = false;
4741         }
4742
4743         if (!test_GetGroupsForUser(p,tctx, &user_handle)) {
4744                 ret = false;
4745         }
4746
4747         if (!test_samr_handle_Close(p, tctx, &user_handle)) {
4748                 ret = false;
4749         }
4750
4751         return ret;
4752 }
4753
4754 static bool test_OpenGroup(struct dcerpc_pipe *p,
4755                            struct torture_context *tctx,
4756                            struct policy_handle *handle, uint32_t rid)
4757 {
4758         NTSTATUS status;
4759         struct samr_OpenGroup r;
4760         struct policy_handle group_handle;
4761         bool ret = true;
4762
4763         printf("Testing OpenGroup(%u)\n", rid);
4764
4765         r.in.domain_handle = handle;
4766         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4767         r.in.rid = rid;
4768         r.out.group_handle = &group_handle;
4769
4770         status = dcerpc_samr_OpenGroup(p, tctx, &r);
4771         if (!NT_STATUS_IS_OK(status)) {
4772                 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
4773                 return false;
4774         }
4775
4776         if (!torture_setting_bool(tctx, "samba3", false)) {
4777                 if (!test_QuerySecurity(p, tctx, &group_handle)) {
4778                         ret = false;
4779                 }
4780         }
4781
4782         if (!test_QueryGroupInfo(p, tctx, &group_handle)) {
4783                 ret = false;
4784         }
4785
4786         if (!test_QueryGroupMember(p, tctx, &group_handle)) {
4787                 ret = false;
4788         }
4789
4790         if (!test_samr_handle_Close(p, tctx, &group_handle)) {
4791                 ret = false;
4792         }
4793
4794         return ret;
4795 }
4796
4797 static bool test_OpenAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
4798                            struct policy_handle *handle, uint32_t rid)
4799 {
4800         NTSTATUS status;
4801         struct samr_OpenAlias r;
4802         struct policy_handle alias_handle;
4803         bool ret = true;
4804
4805         torture_comment(tctx, "Testing OpenAlias(%u)\n", rid);
4806
4807         r.in.domain_handle = handle;
4808         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4809         r.in.rid = rid;
4810         r.out.alias_handle = &alias_handle;
4811
4812         status = dcerpc_samr_OpenAlias(p, tctx, &r);
4813         if (!NT_STATUS_IS_OK(status)) {
4814                 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
4815                 return false;
4816         }
4817
4818         if (!torture_setting_bool(tctx, "samba3", false)) {
4819                 if (!test_QuerySecurity(p, tctx, &alias_handle)) {
4820                         ret = false;
4821                 }
4822         }
4823
4824         if (!test_QueryAliasInfo(p, tctx, &alias_handle)) {
4825                 ret = false;
4826         }
4827
4828         if (!test_GetMembersInAlias(p, tctx, &alias_handle)) {
4829                 ret = false;
4830         }
4831
4832         if (!test_samr_handle_Close(p, tctx, &alias_handle)) {
4833                 ret = false;
4834         }
4835
4836         return ret;
4837 }
4838
4839 static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
4840                        struct policy_handle *handle, uint32_t rid,
4841                        uint32_t acct_flag_mask)
4842 {
4843         NTSTATUS status;
4844         struct samr_OpenUser r;
4845         struct samr_QueryUserInfo q;
4846         union samr_UserInfo *info;
4847         struct policy_handle user_handle;
4848         bool ret = true;
4849
4850         torture_comment(tctx, "Testing OpenUser(%u)\n", rid);
4851
4852         r.in.domain_handle = handle;
4853         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4854         r.in.rid = rid;
4855         r.out.user_handle = &user_handle;
4856
4857         status = dcerpc_samr_OpenUser(p, tctx, &r);
4858         if (!NT_STATUS_IS_OK(status)) {
4859                 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
4860                 return false;
4861         }
4862
4863         q.in.user_handle = &user_handle;
4864         q.in.level = 16;
4865         q.out.info = &info;
4866
4867         status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
4868         if (!NT_STATUS_IS_OK(status)) {
4869                 printf("QueryUserInfo level 16 failed - %s\n",
4870                        nt_errstr(status));
4871                 ret = false;
4872         } else {
4873                 if ((acct_flag_mask & info->info16.acct_flags) == 0) {
4874                         printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
4875                                acct_flag_mask, info->info16.acct_flags, rid);
4876                         ret = false;
4877                 }
4878         }
4879
4880         if (!test_samr_handle_Close(p, tctx, &user_handle)) {
4881                 ret = false;
4882         }
4883
4884         return ret;
4885 }
4886
4887 static bool test_EnumDomainUsers_all(struct dcerpc_pipe *p,
4888                                      struct torture_context *tctx,
4889                                      struct policy_handle *handle)
4890 {
4891         NTSTATUS status = STATUS_MORE_ENTRIES;
4892         struct samr_EnumDomainUsers r;
4893         uint32_t mask, resume_handle=0;
4894         int i, mask_idx;
4895         bool ret = true;
4896         struct samr_LookupNames n;
4897         struct samr_LookupRids  lr ;
4898         struct lsa_Strings names;
4899         struct samr_Ids rids, types;
4900         struct samr_SamArray *sam = NULL;
4901         uint32_t num_entries = 0;
4902
4903         uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
4904                             ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
4905                             ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
4906                             ACB_PWNOEXP, 0};
4907
4908         printf("Testing EnumDomainUsers\n");
4909
4910         for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
4911                 r.in.domain_handle = handle;
4912                 r.in.resume_handle = &resume_handle;
4913                 r.in.acct_flags = mask = masks[mask_idx];
4914                 r.in.max_size = (uint32_t)-1;
4915                 r.out.resume_handle = &resume_handle;
4916                 r.out.num_entries = &num_entries;
4917                 r.out.sam = &sam;
4918
4919                 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
4920                 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
4921                     !NT_STATUS_IS_OK(status)) {
4922                         printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
4923                         return false;
4924                 }
4925
4926                 torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
4927
4928                 if (sam->count == 0) {
4929                         continue;
4930                 }
4931
4932                 for (i=0;i<sam->count;i++) {
4933                         if (mask) {
4934                                 if (!check_mask(p, tctx, handle, sam->entries[i].idx, mask)) {
4935                                         ret = false;
4936                                 }
4937                         } else if (!test_OpenUser(p, tctx, handle, sam->entries[i].idx)) {
4938                                 ret = false;
4939                         }
4940                 }
4941         }
4942
4943         printf("Testing LookupNames\n");
4944         n.in.domain_handle = handle;
4945         n.in.num_names = sam->count;
4946         n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
4947         n.out.rids = &rids;
4948         n.out.types = &types;
4949         for (i=0;i<sam->count;i++) {
4950                 n.in.names[i].string = sam->entries[i].name.string;
4951         }
4952         status = dcerpc_samr_LookupNames(p, tctx, &n);
4953         if (!NT_STATUS_IS_OK(status)) {
4954                 printf("LookupNames failed - %s\n", nt_errstr(status));
4955                 ret = false;
4956         }
4957
4958
4959         printf("Testing LookupRids\n");
4960         lr.in.domain_handle = handle;
4961         lr.in.num_rids = sam->count;
4962         lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
4963         lr.out.names = &names;
4964         lr.out.types = &types;
4965         for (i=0;i<sam->count;i++) {
4966                 lr.in.rids[i] = sam->entries[i].idx;
4967         }
4968         status = dcerpc_samr_LookupRids(p, tctx, &lr);
4969         torture_assert_ntstatus_ok(tctx, status, "LookupRids");
4970
4971         return ret;
4972 }
4973
4974 /*
4975   try blasting the server with a bunch of sync requests
4976 */
4977 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, struct torture_context *tctx,
4978                                        struct policy_handle *handle)
4979 {
4980         NTSTATUS status;
4981         struct samr_EnumDomainUsers r;
4982         uint32_t resume_handle=0;
4983         int i;
4984 #define ASYNC_COUNT 100
4985         struct rpc_request *req[ASYNC_COUNT];
4986
4987         if (!torture_setting_bool(tctx, "dangerous", false)) {
4988                 torture_skip(tctx, "samr async test disabled - enable dangerous tests to use\n");
4989         }
4990
4991         torture_comment(tctx, "Testing EnumDomainUsers_async\n");
4992
4993         r.in.domain_handle = handle;
4994         r.in.resume_handle = &resume_handle;
4995         r.in.acct_flags = 0;
4996         r.in.max_size = (uint32_t)-1;
4997         r.out.resume_handle = &resume_handle;
4998
4999         for (i=0;i<ASYNC_COUNT;i++) {
5000                 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
5001         }
5002
5003         for (i=0;i<ASYNC_COUNT;i++) {
5004                 status = dcerpc_ndr_request_recv(req[i]);
5005                 if (!NT_STATUS_IS_OK(status)) {
5006                         printf("EnumDomainUsers[%d] failed - %s\n",
5007                                i, nt_errstr(status));
5008                         return false;
5009                 }
5010         }
5011
5012         torture_comment(tctx, "%d async requests OK\n", i);
5013
5014         return true;
5015 }
5016
5017 static bool test_EnumDomainGroups_all(struct dcerpc_pipe *p,
5018                                       struct torture_context *tctx,
5019                                       struct policy_handle *handle)
5020 {
5021         NTSTATUS status;
5022         struct samr_EnumDomainGroups r;
5023         uint32_t resume_handle=0;
5024         struct samr_SamArray *sam = NULL;
5025         uint32_t num_entries = 0;
5026         int i;
5027         bool ret = true;
5028
5029         printf("Testing EnumDomainGroups\n");
5030
5031         r.in.domain_handle = handle;
5032         r.in.resume_handle = &resume_handle;
5033         r.in.max_size = (uint32_t)-1;
5034         r.out.resume_handle = &resume_handle;
5035         r.out.num_entries = &num_entries;
5036         r.out.sam = &sam;
5037
5038         status = dcerpc_samr_EnumDomainGroups(p, tctx, &r);
5039         if (!NT_STATUS_IS_OK(status)) {
5040                 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
5041                 return false;
5042         }
5043
5044         if (!sam) {
5045                 return false;
5046         }
5047
5048         for (i=0;i<sam->count;i++) {
5049                 if (!test_OpenGroup(p, tctx, handle, sam->entries[i].idx)) {
5050                         ret = false;
5051                 }
5052         }
5053
5054         return ret;
5055 }
5056
5057 static bool test_EnumDomainAliases_all(struct dcerpc_pipe *p,
5058                                        struct torture_context *tctx,
5059                                        struct policy_handle *handle)
5060 {
5061         NTSTATUS status;
5062         struct samr_EnumDomainAliases r;
5063         uint32_t resume_handle=0;
5064         struct samr_SamArray *sam = NULL;
5065         uint32_t num_entries = 0;
5066         int i;
5067         bool ret = true;
5068
5069         printf("Testing EnumDomainAliases\n");
5070
5071         r.in.domain_handle = handle;
5072         r.in.resume_handle = &resume_handle;
5073         r.in.max_size = (uint32_t)-1;
5074         r.out.sam = &sam;
5075         r.out.num_entries = &num_entries;
5076         r.out.resume_handle = &resume_handle;
5077
5078         status = dcerpc_samr_EnumDomainAliases(p, tctx, &r);
5079         if (!NT_STATUS_IS_OK(status)) {
5080                 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
5081                 return false;
5082         }
5083
5084         if (!sam) {
5085                 return false;
5086         }
5087
5088         for (i=0;i<sam->count;i++) {
5089                 if (!test_OpenAlias(p, tctx, handle, sam->entries[i].idx)) {
5090                         ret = false;
5091                 }
5092         }
5093
5094         return ret;
5095 }
5096
5097 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p,
5098                                             struct torture_context *tctx,
5099                                             struct policy_handle *handle)
5100 {
5101         NTSTATUS status;
5102         struct samr_GetDisplayEnumerationIndex r;
5103         bool ret = true;
5104         uint16_t levels[] = {1, 2, 3, 4, 5};
5105         uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
5106         struct lsa_String name;
5107         uint32_t idx = 0;
5108         int i;
5109
5110         for (i=0;i<ARRAY_SIZE(levels);i++) {
5111                 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
5112
5113                 init_lsa_String(&name, TEST_ACCOUNT_NAME);
5114
5115                 r.in.domain_handle = handle;
5116                 r.in.level = levels[i];
5117                 r.in.name = &name;
5118                 r.out.idx = &idx;
5119
5120                 status = dcerpc_samr_GetDisplayEnumerationIndex(p, tctx, &r);
5121
5122                 if (ok_lvl[i] &&
5123                     !NT_STATUS_IS_OK(status) &&
5124                     !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5125                         printf("GetDisplayEnumerationIndex level %u failed - %s\n",
5126                                levels[i], nt_errstr(status));
5127                         ret = false;
5128                 }
5129
5130                 init_lsa_String(&name, "zzzzzzzz");
5131
5132                 status = dcerpc_samr_GetDisplayEnumerationIndex(p, tctx, &r);
5133
5134                 if (ok_lvl[i] && !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
5141         return ret;
5142 }
5143
5144 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p,
5145                                              struct torture_context *tctx,
5146                                              struct policy_handle *handle)
5147 {
5148         NTSTATUS status;
5149         struct samr_GetDisplayEnumerationIndex2 r;
5150         bool ret = true;
5151         uint16_t levels[] = {1, 2, 3, 4, 5};
5152         uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
5153         struct lsa_String name;
5154         uint32_t idx = 0;
5155         int i;
5156
5157         for (i=0;i<ARRAY_SIZE(levels);i++) {
5158                 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
5159
5160                 init_lsa_String(&name, TEST_ACCOUNT_NAME);
5161
5162                 r.in.domain_handle = handle;
5163                 r.in.level = levels[i];
5164                 r.in.name = &name;
5165                 r.out.idx = &idx;
5166
5167                 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, tctx, &r);
5168                 if (ok_lvl[i] &&
5169                     !NT_STATUS_IS_OK(status) &&
5170                     !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5171                         printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
5172                                levels[i], nt_errstr(status));
5173                         ret = false;
5174                 }
5175
5176                 init_lsa_String(&name, "zzzzzzzz");
5177
5178                 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, tctx, &r);
5179                 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
5180                         printf("GetDisplayEnumerationIndex2 level %u failed - %s\n",
5181                                levels[i], nt_errstr(status));
5182                         ret = false;
5183                 }
5184         }
5185
5186         return ret;
5187 }
5188
5189 #define STRING_EQUAL_QUERY(s1, s2, user)                                        \
5190         if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
5191                 /* odd, but valid */                                            \
5192         } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
5193                         printf("%s mismatch for %s: %s != %s (%s)\n", \
5194                                #s1, user.string,  s1.string, s2.string, __location__);   \
5195                         ret = false; \
5196         }
5197 #define INT_EQUAL_QUERY(s1, s2, user)           \
5198                 if (s1 != s2) { \
5199                         printf("%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
5200                                #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
5201                         ret = false; \
5202                 }
5203
5204 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p,
5205                                        struct torture_context *tctx,
5206                                        struct samr_QueryDisplayInfo *querydisplayinfo,
5207                                        bool *seen_testuser)
5208 {
5209         struct samr_OpenUser r;
5210         struct samr_QueryUserInfo q;
5211         union samr_UserInfo *info;
5212         struct policy_handle user_handle;
5213         int i, ret = true;
5214         NTSTATUS status;
5215         r.in.domain_handle = querydisplayinfo->in.domain_handle;
5216         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5217         for (i = 0; ; i++) {
5218                 switch (querydisplayinfo->in.level) {
5219                 case 1:
5220                         if (i >= querydisplayinfo->out.info->info1.count) {
5221                                 return ret;
5222                         }
5223                         r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
5224                         break;
5225                 case 2:
5226                         if (i >= querydisplayinfo->out.info->info2.count) {
5227                                 return ret;
5228                         }
5229                         r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
5230                         break;
5231                 case 3:
5232                         /* Groups */
5233                 case 4:
5234                 case 5:
5235                         /* Not interested in validating just the account name */
5236                         return true;
5237                 }
5238
5239                 r.out.user_handle = &user_handle;
5240
5241                 switch (querydisplayinfo->in.level) {
5242                 case 1:
5243                 case 2:
5244                         status = dcerpc_samr_OpenUser(p, tctx, &r);
5245                         if (!NT_STATUS_IS_OK(status)) {
5246                                 printf("OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
5247                                 return false;
5248                         }
5249                 }
5250
5251                 q.in.user_handle = &user_handle;
5252                 q.in.level = 21;
5253                 q.out.info = &info;
5254                 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
5255                 if (!NT_STATUS_IS_OK(status)) {
5256                         printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
5257                         return false;
5258                 }
5259
5260                 switch (querydisplayinfo->in.level) {
5261                 case 1:
5262                         if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
5263                                 *seen_testuser = true;
5264                         }
5265                         STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
5266                                            info->info21.full_name, info->info21.account_name);
5267                         STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
5268                                            info->info21.account_name, info->info21.account_name);
5269                         STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
5270                                            info->info21.description, info->info21.account_name);
5271                         INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
5272                                         info->info21.rid, info->info21.account_name);
5273                         INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
5274                                         info->info21.acct_flags, info->info21.account_name);
5275
5276                         break;
5277                 case 2:
5278                         STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
5279                                            info->info21.account_name, info->info21.account_name);
5280                         STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
5281                                            info->info21.description, info->info21.account_name);
5282                         INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
5283                                         info->info21.rid, info->info21.account_name);
5284                         INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
5285                                         info->info21.acct_flags, info->info21.account_name);
5286
5287                         if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
5288                                 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
5289                                        info->info21.account_name.string);
5290                         }
5291
5292                         if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
5293                                 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
5294                                        info->info21.account_name.string,
5295                                        querydisplayinfo->out.info->info2.entries[i].acct_flags,
5296                                        info->info21.acct_flags);
5297                                 return false;
5298                         }
5299
5300                         break;
5301                 }
5302
5303                 if (!test_samr_handle_Close(p, tctx, &user_handle)) {
5304                         return false;
5305                 }
5306         }
5307         return ret;
5308 }
5309
5310 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p,
5311                                   struct torture_context *tctx,
5312                                   struct policy_handle *handle)
5313 {
5314         NTSTATUS status;
5315         struct samr_QueryDisplayInfo r;
5316         struct samr_QueryDomainInfo dom_info;
5317         union samr_DomainInfo *info = NULL;
5318         bool ret = true;
5319         uint16_t levels[] = {1, 2, 3, 4, 5};
5320         int i;
5321         bool seen_testuser = false;
5322         uint32_t total_size;
5323         uint32_t returned_size;
5324         union samr_DispInfo disp_info;
5325
5326
5327         for (i=0;i<ARRAY_SIZE(levels);i++) {
5328                 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
5329
5330                 r.in.start_idx = 0;
5331                 status = STATUS_MORE_ENTRIES;
5332                 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5333                         r.in.domain_handle = handle;
5334                         r.in.level = levels[i];
5335                         r.in.max_entries = 2;
5336                         r.in.buf_size = (uint32_t)-1;
5337                         r.out.total_size = &total_size;
5338                         r.out.returned_size = &returned_size;
5339                         r.out.info = &disp_info;
5340
5341                         status = dcerpc_samr_QueryDisplayInfo(p, tctx, &r);
5342                         if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
5343                                 printf("QueryDisplayInfo level %u failed - %s\n",
5344                                        levels[i], nt_errstr(status));
5345                                 ret = false;
5346                         }
5347                         switch (r.in.level) {
5348                         case 1:
5349                                 if (!test_each_DisplayInfo_user(p, tctx, &r, &seen_testuser)) {
5350                                         ret = false;
5351                                 }
5352                                 r.in.start_idx += r.out.info->info1.count;
5353                                 break;
5354                         case 2:
5355                                 if (!test_each_DisplayInfo_user(p, tctx, &r, NULL)) {
5356                                         ret = false;
5357                                 }
5358                                 r.in.start_idx += r.out.info->info2.count;
5359                                 break;
5360                         case 3:
5361                                 r.in.start_idx += r.out.info->info3.count;
5362                                 break;
5363                         case 4:
5364                                 r.in.start_idx += r.out.info->info4.count;
5365                                 break;
5366                         case 5:
5367                                 r.in.start_idx += r.out.info->info5.count;
5368                                 break;
5369                         }
5370                 }
5371                 dom_info.in.domain_handle = handle;
5372                 dom_info.in.level = 2;
5373                 dom_info.out.info = &info;
5374
5375                 /* Check number of users returned is correct */
5376                 status = dcerpc_samr_QueryDomainInfo(p, tctx, &dom_info);
5377                 if (!NT_STATUS_IS_OK(status)) {
5378                         printf("QueryDomainInfo level %u failed - %s\n",
5379                                r.in.level, nt_errstr(status));
5380                                 ret = false;
5381                                 break;
5382                 }
5383                 switch (r.in.level) {
5384                 case 1:
5385                 case 4:
5386                         if (info->general.num_users < r.in.start_idx) {
5387                                 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
5388                                        r.in.start_idx, info->general.num_groups,
5389                                        info->general.domain_name.string);
5390                                 ret = false;
5391                         }
5392                         if (!seen_testuser) {
5393                                 struct policy_handle user_handle;
5394                                 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, tctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
5395                                         printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
5396                                                info->general.domain_name.string);
5397                                         ret = false;
5398                                         test_samr_handle_Close(p, tctx, &user_handle);
5399                                 }
5400                         }
5401                         break;
5402                 case 3:
5403                 case 5:
5404                         if (info->general.num_groups != r.in.start_idx) {
5405                                 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
5406                                        r.in.start_idx, info->general.num_groups,
5407                                        info->general.domain_name.string);
5408                                 ret = false;
5409                         }
5410
5411                         break;
5412                 }
5413
5414         }
5415
5416         return ret;
5417 }
5418
5419 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p,
5420                                    struct torture_context *tctx,
5421                                    struct policy_handle *handle)
5422 {
5423         NTSTATUS status;
5424         struct samr_QueryDisplayInfo2 r;
5425         bool ret = true;
5426         uint16_t levels[] = {1, 2, 3, 4, 5};
5427         int i;
5428         uint32_t total_size;
5429         uint32_t returned_size;
5430         union samr_DispInfo info;
5431
5432         for (i=0;i<ARRAY_SIZE(levels);i++) {
5433                 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
5434
5435                 r.in.domain_handle = handle;
5436                 r.in.level = levels[i];
5437                 r.in.start_idx = 0;
5438                 r.in.max_entries = 1000;
5439                 r.in.buf_size = (uint32_t)-1;
5440                 r.out.total_size = &total_size;
5441                 r.out.returned_size = &returned_size;
5442                 r.out.info = &info;
5443
5444                 status = dcerpc_samr_QueryDisplayInfo2(p, tctx, &r);
5445                 if (!NT_STATUS_IS_OK(status)) {
5446                         printf("QueryDisplayInfo2 level %u failed - %s\n",
5447                                levels[i], nt_errstr(status));
5448                         ret = false;
5449                 }
5450         }
5451
5452         return ret;
5453 }
5454
5455 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context *tctx,
5456                                   struct policy_handle *handle)
5457 {
5458         NTSTATUS status;
5459         struct samr_QueryDisplayInfo3 r;
5460         bool ret = true;
5461         uint16_t levels[] = {1, 2, 3, 4, 5};
5462         int i;
5463         uint32_t total_size;
5464         uint32_t returned_size;
5465         union samr_DispInfo info;
5466
5467         for (i=0;i<ARRAY_SIZE(levels);i++) {
5468                 torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
5469
5470                 r.in.domain_handle = handle;
5471                 r.in.level = levels[i];
5472                 r.in.start_idx = 0;
5473                 r.in.max_entries = 1000;
5474                 r.in.buf_size = (uint32_t)-1;
5475                 r.out.total_size = &total_size;
5476                 r.out.returned_size = &returned_size;
5477                 r.out.info = &info;
5478
5479                 status = dcerpc_samr_QueryDisplayInfo3(p, tctx, &r);
5480                 if (!NT_STATUS_IS_OK(status)) {
5481                         printf("QueryDisplayInfo3 level %u failed - %s\n",
5482                                levels[i], nt_errstr(status));
5483                         ret = false;
5484                 }
5485         }
5486
5487         return ret;
5488 }
5489
5490
5491 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p,
5492                                            struct torture_context *tctx,
5493                                            struct policy_handle *handle)
5494 {
5495         NTSTATUS status;
5496         struct samr_QueryDisplayInfo r;
5497         bool ret = true;
5498         uint32_t total_size;
5499         uint32_t returned_size;
5500         union samr_DispInfo info;
5501
5502         printf("Testing QueryDisplayInfo continuation\n");
5503
5504         r.in.domain_handle = handle;
5505         r.in.level = 1;
5506         r.in.start_idx = 0;
5507         r.in.max_entries = 1;
5508         r.in.buf_size = (uint32_t)-1;
5509         r.out.total_size = &total_size;
5510         r.out.returned_size = &returned_size;
5511         r.out.info = &info;
5512
5513         do {
5514                 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &r);
5515                 if (NT_STATUS_IS_OK(status) && *r.out.returned_size != 0) {
5516                         if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
5517                                 printf("expected idx %d but got %d\n",
5518                                        r.in.start_idx + 1,
5519                                        r.out.info->info1.entries[0].idx);
5520                                 break;
5521                         }
5522                 }
5523                 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
5524                     !NT_STATUS_IS_OK(status)) {
5525                         printf("QueryDisplayInfo level %u failed - %s\n",
5526                                r.in.level, nt_errstr(status));
5527                         ret = false;
5528                         break;
5529                 }
5530                 r.in.start_idx++;
5531         } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
5532                   NT_STATUS_IS_OK(status)) &&
5533                  *r.out.returned_size != 0);
5534
5535         return ret;
5536 }
5537
5538 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
5539                                  struct policy_handle *handle)
5540 {
5541         NTSTATUS status;
5542         struct samr_QueryDomainInfo r;
5543         union samr_DomainInfo *info = NULL;
5544         struct samr_SetDomainInfo s;
5545         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5546         uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1,  0,  1,  0};
5547         int i;
5548         bool ret = true;
5549         const char *domain_comment = talloc_asprintf(tctx,
5550                                   "Tortured by Samba4 RPC-SAMR: %s",
5551                                   timestring(tctx, time(NULL)));
5552
5553         s.in.domain_handle = handle;
5554         s.in.level = 4;
5555         s.in.info = talloc(tctx, union samr_DomainInfo);
5556
5557         s.in.info->oem.oem_information.string = domain_comment;
5558         status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5559         if (!NT_STATUS_IS_OK(status)) {
5560                 printf("SetDomainInfo level %u (set comment) failed - %s\n",
5561                        s.in.level, nt_errstr(status));
5562                 return false;
5563         }
5564
5565         for (i=0;i<ARRAY_SIZE(levels);i++) {
5566                 torture_comment(tctx, "Testing QueryDomainInfo level %u\n", levels[i]);
5567
5568                 r.in.domain_handle = handle;
5569                 r.in.level = levels[i];
5570                 r.out.info = &info;
5571
5572                 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
5573                 if (!NT_STATUS_IS_OK(status)) {
5574                         printf("QueryDomainInfo level %u failed - %s\n",
5575                                r.in.level, nt_errstr(status));
5576                         ret = false;
5577                         continue;
5578                 }
5579
5580                 switch (levels[i]) {
5581                 case 2:
5582                         if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
5583                                 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
5584                                        levels[i], info->general.oem_information.string, domain_comment);
5585                                 ret = false;
5586                         }
5587                         if (!info->general.primary.string) {
5588                                 printf("QueryDomainInfo level %u returned no PDC name\n",
5589                                        levels[i]);
5590                                 ret = false;
5591                         } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
5592                                 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
5593                                         printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
5594                                                levels[i], info->general.primary.string, dcerpc_server_name(p));
5595                                 }
5596                         }
5597                         break;
5598                 case 4:
5599                         if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
5600                                 printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
5601                                        levels[i], info->oem.oem_information.string, domain_comment);
5602                                 ret = false;
5603                         }
5604                         break;
5605                 case 6:
5606                         if (!info->info6.primary.string) {
5607                                 printf("QueryDomainInfo level %u returned no PDC name\n",
5608                                        levels[i]);
5609                                 ret = false;
5610                         }
5611                         break;
5612                 case 11:
5613                         if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
5614                                 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
5615                                        levels[i], info->general2.general.oem_information.string, domain_comment);
5616                                 ret = false;
5617                         }
5618                         break;
5619                 }
5620
5621                 torture_comment(tctx, "Testing SetDomainInfo level %u\n", levels[i]);
5622
5623                 s.in.domain_handle = handle;
5624                 s.in.level = levels[i];
5625                 s.in.info = info;
5626
5627                 status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
5628                 if (set_ok[i]) {
5629                         if (!NT_STATUS_IS_OK(status)) {
5630                                 printf("SetDomainInfo level %u failed - %s\n",
5631                                        r.in.level, nt_errstr(status));
5632                                 ret = false;
5633                                 continue;
5634                         }
5635                 } else {
5636                         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
5637                                 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n",
5638                                        r.in.level, nt_errstr(status));
5639                                 ret = false;
5640                                 continue;
5641                         }
5642                 }
5643
5644                 status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
5645                 if (!NT_STATUS_IS_OK(status)) {
5646                         printf("QueryDomainInfo level %u failed - %s\n",
5647                                r.in.level, nt_errstr(status));
5648                         ret = false;
5649                         continue;
5650                 }
5651         }
5652
5653         return ret;
5654 }
5655
5656
5657 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context *tctx,
5658                                   struct policy_handle *handle)
5659 {
5660         NTSTATUS status;
5661         struct samr_QueryDomainInfo2 r;
5662         union samr_DomainInfo *info = NULL;
5663         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
5664         int i;
5665         bool ret = true;
5666
5667         for (i=0;i<ARRAY_SIZE(levels);i++) {
5668                 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
5669
5670                 r.in.domain_handle = handle;
5671                 r.in.level = levels[i];
5672                 r.out.info = &info;
5673
5674                 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
5675                 if (!NT_STATUS_IS_OK(status)) {
5676                         printf("QueryDomainInfo2 level %u failed - %s\n",
5677                                r.in.level, nt_errstr(status));
5678                         ret = false;
5679                         continue;
5680                 }
5681         }
5682
5683         return true;
5684 }
5685
5686 /* Test whether querydispinfo level 5 and enumdomgroups return the same
5687    set of group names. */
5688 static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
5689                            struct policy_handle *handle)
5690 {
5691         struct samr_EnumDomainGroups q1;
5692         struct samr_QueryDisplayInfo q2;
5693         NTSTATUS status;
5694         uint32_t resume_handle=0;
5695         struct samr_SamArray *sam = NULL;
5696         uint32_t num_entries = 0;
5697         int i;
5698         bool ret = true;
5699         uint32_t total_size;
5700         uint32_t returned_size;
5701         union samr_DispInfo info;
5702
5703         int num_names = 0;
5704         const char **names = NULL;
5705
5706         torture_comment(tctx, "Testing coherency of querydispinfo vs enumdomgroups\n");
5707
5708         q1.in.domain_handle = handle;
5709         q1.in.resume_handle = &resume_handle;
5710         q1.in.max_size = 5;
5711         q1.out.resume_handle = &resume_handle;
5712         q1.out.num_entries = &num_entries;
5713         q1.out.sam = &sam;
5714
5715         status = STATUS_MORE_ENTRIES;
5716         while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5717                 status = dcerpc_samr_EnumDomainGroups(p, tctx, &q1);
5718
5719                 if (!NT_STATUS_IS_OK(status) &&
5720                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
5721                         break;
5722
5723                 for (i=0; i<*q1.out.num_entries; i++) {
5724                         add_string_to_array(tctx,
5725                                             sam->entries[i].name.string,
5726                                             &names, &num_names);
5727                 }
5728         }
5729
5730         torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
5731
5732         torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
5733
5734         q2.in.domain_handle = handle;
5735         q2.in.level = 5;
5736         q2.in.start_idx = 0;
5737         q2.in.max_entries = 5;
5738         q2.in.buf_size = (uint32_t)-1;
5739         q2.out.total_size = &total_size;
5740         q2.out.returned_size = &returned_size;
5741         q2.out.info = &info;
5742
5743         status = STATUS_MORE_ENTRIES;
5744         while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
5745                 status = dcerpc_samr_QueryDisplayInfo(p, tctx, &q2);
5746
5747                 if (!NT_STATUS_IS_OK(status) &&
5748                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
5749                         break;
5750
5751                 for (i=0; i<q2.out.info->info5.count; i++) {
5752                         int j;
5753                         const char *name = q2.out.info->info5.entries[i].account_name.string;
5754                         bool found = false;
5755                         for (j=0; j<num_names; j++) {
5756                                 if (names[j] == NULL)
5757                                         continue;
5758                                 if (strequal(names[j], name)) {
5759                                         names[j] = NULL;
5760                                         found = true;
5761                                         break;
5762                                 }
5763                         }
5764
5765                         if (!found) {
5766                                 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
5767                                        name);
5768                                 ret = false;
5769                         }
5770                 }
5771                 q2.in.start_idx += q2.out.info->info5.count;
5772         }
5773
5774         if (!NT_STATUS_IS_OK(status)) {
5775                 printf("QueryDisplayInfo level 5 failed - %s\n",
5776                        nt_errstr(status));
5777                 ret = false;
5778         }
5779
5780         for (i=0; i<num_names; i++) {
5781                 if (names[i] != NULL) {
5782                         printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
5783                                names[i]);
5784                         ret = false;
5785                 }
5786         }
5787
5788         return ret;
5789 }
5790
5791 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, struct torture_context *tctx,
5792                                    struct policy_handle *group_handle)
5793 {
5794         struct samr_DeleteDomainGroup d;
5795         NTSTATUS status;
5796
5797         torture_comment(tctx, "Testing DeleteDomainGroup\n");
5798
5799         d.in.group_handle = group_handle;
5800         d.out.group_handle = group_handle;
5801
5802         status = dcerpc_samr_DeleteDomainGroup(p, tctx, &d);
5803         torture_assert_ntstatus_ok(tctx, status, "DeleteDomainGroup");
5804
5805         return true;
5806 }
5807
5808 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
5809                                             struct policy_handle *domain_handle)
5810 {
5811         struct samr_TestPrivateFunctionsDomain r;
5812         NTSTATUS status;
5813         bool ret = true;
5814
5815         torture_comment(tctx, "Testing TestPrivateFunctionsDomain\n");
5816
5817         r.in.domain_handle = domain_handle;
5818
5819         status = dcerpc_samr_TestPrivateFunctionsDomain(p, tctx, &r);
5820         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "TestPrivateFunctionsDomain");
5821
5822         return ret;
5823 }
5824
5825 static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
5826                           struct dom_sid *domain_sid,
5827                           struct policy_handle *domain_handle)
5828 {
5829         struct samr_RidToSid r;
5830         NTSTATUS status;
5831         bool ret = true;
5832         struct dom_sid *calc_sid, *out_sid;
5833         int rids[] = { 0, 42, 512, 10200 };
5834         int i;
5835
5836         for (i=0;i<ARRAY_SIZE(rids);i++) {
5837                 torture_comment(tctx, "Testing RidToSid\n");
5838
5839                 calc_sid = dom_sid_dup(tctx, domain_sid);
5840                 r.in.domain_handle = domain_handle;
5841                 r.in.rid = rids[i];
5842                 r.out.sid = &out_sid;
5843
5844                 status = dcerpc_samr_RidToSid(p, tctx, &r);
5845                 if (!NT_STATUS_IS_OK(status)) {
5846                         printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
5847                         ret = false;
5848                 } else {
5849                         calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
5850
5851                         if (!dom_sid_equal(calc_sid, out_sid)) {
5852                                 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
5853                                        dom_sid_string(tctx, out_sid),
5854                                        dom_sid_string(tctx, calc_sid));
5855                                 ret = false;
5856                         }
5857                 }
5858         }
5859
5860         return ret;
5861 }
5862
5863 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, struct torture_context *tctx,
5864                                        struct policy_handle *domain_handle)
5865 {
5866         struct samr_GetBootKeyInformation r;
5867         NTSTATUS status;
5868         bool ret = true;
5869         uint32_t unknown = 0;
5870
5871         torture_comment(tctx, "Testing GetBootKeyInformation\n");
5872
5873         r.in.domain_handle = domain_handle;
5874         r.out.unknown = &unknown;
5875
5876         status = dcerpc_samr_GetBootKeyInformation(p, tctx, &r);
5877         if (!NT_STATUS_IS_OK(status)) {
5878                 /* w2k3 seems to fail this sometimes and pass it sometimes */
5879                 torture_comment(tctx, "GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
5880         }
5881
5882         return ret;
5883 }
5884
5885 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx,
5886                                 struct policy_handle *domain_handle,
5887                                 struct policy_handle *group_handle)
5888 {
5889         NTSTATUS status;
5890         struct samr_AddGroupMember r;
5891         struct samr_DeleteGroupMember d;
5892         struct samr_QueryGroupMember q;
5893         struct samr_RidTypeArray *rids = NULL;
5894         struct samr_SetMemberAttributesOfGroup s;
5895         uint32_t rid;
5896
5897         status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
5898         torture_assert_ntstatus_ok(tctx, status, "test_AddGroupMember looking up name " TEST_ACCOUNT_NAME);
5899
5900         r.in.group_handle = group_handle;
5901         r.in.rid = rid;
5902         r.in.flags = 0; /* ??? */
5903
5904         torture_comment(tctx, "Testing AddGroupMember and DeleteGroupMember\n");
5905
5906         d.in.group_handle = group_handle;
5907         d.in.rid = rid;
5908
5909         status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
5910         torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_NOT_IN_GROUP, status, "DeleteGroupMember");
5911
5912         status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5913         torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
5914
5915         status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5916         torture_assert_ntstatus_equal(tctx, NT_STATUS_MEMBER_IN_GROUP, status, "AddGroupMember");
5917
5918         if (torture_setting_bool(tctx, "samba4", false) ||
5919             torture_setting_bool(tctx, "samba3", false)) {
5920                 torture_comment(tctx, "skipping SetMemberAttributesOfGroup test against Samba4\n");
5921         } else {
5922                 /* this one is quite strange. I am using random inputs in the
5923                    hope of triggering an error that might give us a clue */
5924
5925                 s.in.group_handle = group_handle;
5926                 s.in.unknown1 = random();
5927                 s.in.unknown2 = random();
5928
5929                 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
5930                 torture_assert_ntstatus_ok(tctx, status, "SetMemberAttributesOfGroup");
5931         }
5932
5933         q.in.group_handle = group_handle;
5934         q.out.rids = &rids;
5935
5936         status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
5937         torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
5938
5939         status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
5940         torture_assert_ntstatus_ok(tctx, status, "DeleteGroupMember");
5941
5942         status = dcerpc_samr_AddGroupMember(p, tctx, &r);
5943         torture_assert_ntstatus_ok(tctx, status, "AddGroupMember");
5944
5945         return true;
5946 }
5947
5948
5949 static bool test_CreateDomainGroup(struct dcerpc_pipe *p,
5950                                    struct torture_context *tctx,
5951                                    struct policy_handle *domain_handle,
5952                                    const char *group_name,
5953                                    struct policy_handle *group_handle,
5954                                    struct dom_sid *domain_sid,
5955                                    bool test_group)
5956 {
5957         NTSTATUS status;
5958         struct samr_CreateDomainGroup r;
5959         uint32_t rid;
5960         struct lsa_String name;
5961         bool ret = true;
5962
5963         init_lsa_String(&name, group_name);
5964
5965         r.in.domain_handle = domain_handle;
5966         r.in.name = &name;
5967         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
5968         r.out.group_handle = group_handle;
5969         r.out.rid = &rid;
5970
5971         printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
5972
5973         status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
5974
5975         if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
5976                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5977                         torture_comment(tctx, "Server correctly refused create of '%s'\n", r.in.name->string);
5978                         return true;
5979                 } else {
5980                         printf("Server should have refused create of '%s', got %s instead\n", r.in.name->string,
5981                                nt_errstr(status));
5982                         return false;
5983                 }
5984         }
5985
5986         if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
5987                 if (!test_DeleteGroup_byname(p, tctx, domain_handle, r.in.name->string)) {
5988                         printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string,
5989                                nt_errstr(status));
5990                         return false;
5991                 }
5992                 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
5993         }
5994         if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
5995                 if (!test_DeleteUser_byname(p, tctx, domain_handle, r.in.name->string)) {
5996
5997                         printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string,
5998                                nt_errstr(status));
5999                         return false;
6000                 }
6001                 status = dcerpc_samr_CreateDomainGroup(p, tctx, &r);
6002         }
6003         torture_assert_ntstatus_ok(tctx, status, "CreateDomainGroup");
6004
6005         if (!test_group) {
6006                 return ret;
6007         }
6008
6009         if (!test_AddGroupMember(p, tctx, domain_handle, group_handle)) {
6010                 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
6011                 ret = false;
6012         }
6013
6014         if (!test_SetGroupInfo(p, tctx, group_handle)) {
6015                 ret = false;
6016         }
6017
6018         return ret;
6019 }
6020
6021
6022 /*
6023   its not totally clear what this does. It seems to accept any sid you like.
6024 */
6025 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p,
6026                                                struct torture_context *tctx,
6027                                                struct policy_handle *domain_handle)
6028 {
6029         NTSTATUS status;
6030         struct samr_RemoveMemberFromForeignDomain r;
6031
6032         r.in.domain_handle = domain_handle;
6033         r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-12-34-56-78");
6034
6035         status = dcerpc_samr_RemoveMemberFromForeignDomain(p, tctx, &r);
6036         torture_assert_ntstatus_ok(tctx, status, "RemoveMemberFromForeignDomain");
6037
6038         return true;
6039 }
6040
6041 static bool test_EnumDomainUsers(struct dcerpc_pipe *p,
6042                                  struct torture_context *tctx,
6043                                  struct policy_handle *domain_handle,
6044                                  uint32_t *total_num_entries_p)
6045 {
6046         NTSTATUS status;
6047         struct samr_EnumDomainUsers r;
6048         uint32_t resume_handle = 0;
6049         uint32_t num_entries = 0;
6050         uint32_t total_num_entries = 0;
6051         struct samr_SamArray *sam;
6052
6053         r.in.domain_handle = domain_handle;
6054         r.in.acct_flags = ACB_NORMAL;
6055         r.in.max_size = (uint32_t)-1;
6056         r.in.resume_handle = &resume_handle;
6057
6058         r.out.sam = &sam;
6059         r.out.num_entries = &num_entries;
6060         r.out.resume_handle = &resume_handle;
6061
6062         printf("Testing EnumDomainUsers\n");
6063
6064         do {
6065                 status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
6066                 if (NT_STATUS_IS_ERR(status)) {
6067                         torture_assert_ntstatus_ok(tctx, status,
6068                                 "failed to enumerate users");
6069                 }
6070
6071                 total_num_entries += num_entries;
6072         } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
6073
6074         if (total_num_entries_p) {
6075                 *total_num_entries_p = total_num_entries;
6076         }
6077
6078         return true;
6079 }
6080
6081 static bool test_EnumDomainGroups(struct dcerpc_pipe *p,
6082                                   struct torture_context *tctx,
6083                                   struct policy_handle *domain_handle,
6084                                   uint32_t *total_num_entries_p)
6085 {
6086         NTSTATUS status;
6087         struct samr_EnumDomainGroups r;
6088         uint32_t resume_handle = 0;
6089         uint32_t num_entries = 0;
6090         uint32_t total_num_entries = 0;
6091         struct samr_SamArray *sam;
6092
6093         r.in.domain_handle = domain_handle;
6094         r.in.max_size = (uint32_t)-1;
6095         r.in.resume_handle = &resume_handle;
6096
6097         r.out.sam = &sam;
6098         r.out.num_entries = &num_entries;
6099         r.out.resume_handle = &resume_handle;
6100
6101         printf("Testing EnumDomainGroups\n");
6102
6103         do {
6104                 status = dcerpc_samr_EnumDomainGroups(p, tctx, &r);
6105                 if (NT_STATUS_IS_ERR(status)) {
6106                         torture_assert_ntstatus_ok(tctx, status,
6107                                 "failed to enumerate groups");
6108                 }
6109
6110                 total_num_entries += num_entries;
6111         } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
6112
6113         if (total_num_entries_p) {
6114                 *total_num_entries_p = total_num_entries;
6115         }
6116
6117         return true;
6118 }
6119
6120 static bool test_EnumDomainAliases(struct dcerpc_pipe *p,
6121                                    struct torture_context *tctx,
6122                                    struct policy_handle *domain_handle,
6123                                    uint32_t *total_num_entries_p)
6124 {
6125         NTSTATUS status;
6126         struct samr_EnumDomainAliases r;
6127         uint32_t resume_handle = 0;
6128         uint32_t num_entries = 0;
6129         uint32_t total_num_entries = 0;
6130         struct samr_SamArray *sam;
6131
6132         r.in.domain_handle = domain_handle;
6133         r.in.max_size = (uint32_t)-1;
6134         r.in.resume_handle = &resume_handle;
6135
6136         r.out.sam = &sam;
6137         r.out.num_entries = &num_entries;
6138         r.out.resume_handle = &resume_handle;
6139
6140         printf("Testing EnumDomainAliases\n");
6141
6142         do {
6143                 status = dcerpc_samr_EnumDomainAliases(p, tctx, &r);
6144                 if (NT_STATUS_IS_ERR(status)) {
6145                         torture_assert_ntstatus_ok(tctx, status,
6146                                 "failed to enumerate aliases");
6147                 }
6148
6149                 total_num_entries += num_entries;
6150         } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
6151
6152         if (total_num_entries_p) {
6153                 *total_num_entries_p = total_num_entries;
6154         }
6155
6156         return true;
6157 }
6158
6159 static bool test_ManyObjects(struct dcerpc_pipe *p,
6160                              struct torture_context *tctx,
6161                              struct policy_handle *domain_handle,
6162                              struct dom_sid *domain_sid,
6163                              enum torture_samr_choice which_ops)
6164 {
6165         uint32_t num_total = 1500;
6166         uint32_t num_enum = 0;
6167         uint32_t num_disp = 0;
6168         uint32_t num_created = 0;
6169         uint32_t num_anounced = 0;
6170         bool ret = true;
6171         NTSTATUS status;
6172         uint32_t i;
6173
6174         /* query */
6175
6176         {
6177                 struct samr_QueryDomainInfo2 r;
6178                 union samr_DomainInfo *info;
6179                 r.in.domain_handle = domain_handle;
6180                 r.in.level = 2;
6181                 r.out.info = &info;
6182
6183                 status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
6184                 torture_assert_ntstatus_ok(tctx, status,
6185                         "failed to query domain info");
6186
6187                 switch (which_ops) {
6188                 case TORTURE_SAMR_MANY_ACCOUNTS:
6189                         num_anounced = info->general.num_users;
6190                         break;
6191                 case TORTURE_SAMR_MANY_GROUPS:
6192                         num_anounced = info->general.num_groups;
6193                         break;
6194                 case TORTURE_SAMR_MANY_ALIASES:
6195                         num_anounced = info->general.num_aliases;
6196                         break;
6197                 default:
6198                         return false;
6199                 }
6200         }
6201
6202         /* create */
6203
6204         for (i=0; i < num_total; i++) {
6205
6206                 struct policy_handle handle;
6207                 const char *name = NULL;
6208
6209                 ZERO_STRUCT(handle);
6210
6211                 switch (which_ops) {
6212                 case TORTURE_SAMR_MANY_ACCOUNTS:
6213                         name = talloc_asprintf(tctx, "%s%04d", TEST_ACCOUNT_NAME, i);
6214                         ret &= test_CreateUser(p, tctx, domain_handle, name, &handle, domain_sid, 0, NULL, false);
6215                         break;
6216                 case TORTURE_SAMR_MANY_GROUPS:
6217                         name = talloc_asprintf(tctx, "%s%04d", TEST_GROUPNAME, i);
6218                         ret &= test_CreateDomainGroup(p, tctx, domain_handle, name, &handle, domain_sid, false);
6219                         break;
6220                 case TORTURE_SAMR_MANY_ALIASES:
6221                         name = talloc_asprintf(tctx, "%s%04d", TEST_ALIASNAME, i);
6222                         ret &= test_CreateAlias(p, tctx, domain_handle, name, &handle, domain_sid, false);
6223                         break;
6224                 default:
6225                         return false;
6226                 }
6227                 if (!policy_handle_empty(&handle)) {
6228                         ret &= test_samr_handle_Close(p, tctx, &handle);
6229                         num_created++;
6230                 }
6231         }
6232
6233         /* enum */
6234
6235         switch (which_ops) {
6236         case TORTURE_SAMR_MANY_ACCOUNTS:
6237                 ret &= test_EnumDomainUsers(p, tctx, domain_handle, &num_enum);
6238                 break;
6239         case TORTURE_SAMR_MANY_GROUPS:
6240                 ret &= test_EnumDomainGroups(p, tctx, domain_handle, &num_enum);
6241                 break;
6242         case TORTURE_SAMR_MANY_ALIASES:
6243                 ret &= test_EnumDomainAliases(p, tctx, domain_handle, &num_enum);
6244                 break;
6245         default:
6246                 return false;
6247         }
6248
6249         torture_assert_int_equal(tctx, num_enum, num_anounced + num_created,
6250                 "unexpected number of results returned in enum call");
6251 #if 0
6252         /* TODO: dispinfo */
6253
6254         switch (which_ops) {
6255         case TORTURE_SAMR_MANY_ACCOUNTS:
6256                 break;
6257         case TORTURE_SAMR_MANY_GROUPS:
6258                 break;
6259         case TORTURE_SAMR_MANY_ALIASES:
6260                 break;
6261         default:
6262                 return false;
6263         }
6264
6265         torture_assert_int_equal(tctx, num_disp, num_anounced + num_created,
6266                 "unexpected number of results returned in dispinfo call");
6267 #endif
6268         return ret;
6269 }
6270
6271 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
6272                          struct policy_handle *handle);
6273
6274 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
6275                             struct policy_handle *handle, struct dom_sid *sid,
6276                             enum torture_samr_choice which_ops,
6277                             struct cli_credentials *machine_credentials)
6278 {
6279         NTSTATUS status;
6280         struct samr_OpenDomain r;
6281         struct policy_handle domain_handle;
6282         struct policy_handle alias_handle;
6283         struct policy_handle user_handle;
6284         struct policy_handle group_handle;
6285         bool ret = true;
6286
6287         ZERO_STRUCT(alias_handle);
6288         ZERO_STRUCT(user_handle);
6289         ZERO_STRUCT(group_handle);
6290         ZERO_STRUCT(domain_handle);
6291
6292         torture_comment(tctx, "Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
6293
6294         r.in.connect_handle = handle;
6295         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6296         r.in.sid = sid;
6297         r.out.domain_handle = &domain_handle;
6298
6299         status = dcerpc_samr_OpenDomain(p, tctx, &r);
6300         torture_assert_ntstatus_ok(tctx, status, "OpenDomain");
6301
6302         /* run the domain tests with the main handle closed - this tests
6303            the servers reference counting */
6304         ret &= test_samr_handle_Close(p, tctx, handle);
6305
6306         switch (which_ops) {
6307         case TORTURE_SAMR_USER_ATTRIBUTES:
6308         case TORTURE_SAMR_USER_PRIVILEGES:
6309         case TORTURE_SAMR_PASSWORDS:
6310                 if (!torture_setting_bool(tctx, "samba3", false)) {
6311                         ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, NULL);
6312                 }
6313                 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, which_ops, NULL, true);
6314                 /* This test needs 'complex' users to validate */
6315                 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
6316                 if (!ret) {
6317                         printf("Testing PASSWORDS or ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
6318                 }
6319                 break;
6320         case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
6321                 if (!torture_setting_bool(tctx, "samba3", false)) {
6322                         ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, machine_credentials);
6323                 }
6324                 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, which_ops, machine_credentials, true);
6325                 if (!ret) {
6326                         printf("Testing PASSWORDS PWDLASTSET on domain %s failed!\n", dom_sid_string(tctx, sid));
6327                 }
6328                 break;
6329         case TORTURE_SAMR_MANY_ACCOUNTS:
6330         case TORTURE_SAMR_MANY_GROUPS:
6331         case TORTURE_SAMR_MANY_ALIASES:
6332                 ret &= test_ManyObjects(p, tctx, &domain_handle, sid, which_ops);
6333                 break;
6334         case TORTURE_SAMR_OTHER:
6335                 ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, which_ops, NULL, true);
6336                 if (!ret) {
6337                         printf("Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
6338                 }
6339                 if (!torture_setting_bool(tctx, "samba3", false)) {
6340                         ret &= test_QuerySecurity(p, tctx, &domain_handle);
6341                 }
6342                 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
6343                 ret &= test_CreateAlias(p, tctx, &domain_handle, TEST_ALIASNAME, &alias_handle, sid, true);
6344                 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, TEST_GROUPNAME, &group_handle, sid, true);
6345                 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
6346                 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
6347                 ret &= test_EnumDomainUsers_all(p, tctx, &domain_handle);
6348                 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
6349                 ret &= test_EnumDomainGroups_all(p, tctx, &domain_handle);
6350                 ret &= test_EnumDomainAliases_all(p, tctx, &domain_handle);
6351                 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
6352                 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
6353                 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
6354
6355                 if (torture_setting_bool(tctx, "samba4", false)) {
6356                         torture_comment(tctx, "skipping GetDisplayEnumerationIndex test against Samba4\n");
6357                 } else {
6358                         ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
6359                         ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
6360                 }
6361                 ret &= test_GroupList(p, tctx, &domain_handle);
6362                 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
6363                 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
6364                 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
6365                 if (!ret) {
6366                         torture_comment(tctx, "Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
6367                 }
6368                 break;
6369         }
6370
6371         if (!policy_handle_empty(&user_handle) &&
6372             !test_DeleteUser(p, tctx, &user_handle)) {
6373                 ret = false;
6374         }
6375
6376         if (!policy_handle_empty(&alias_handle) &&
6377             !test_DeleteAlias(p, tctx, &alias_handle)) {
6378                 ret = false;
6379         }
6380
6381         if (!policy_handle_empty(&group_handle) &&
6382             !test_DeleteDomainGroup(p, tctx, &group_handle)) {
6383                 ret = false;
6384         }
6385
6386         ret &= test_samr_handle_Close(p, tctx, &domain_handle);
6387
6388         /* reconnect the main handle */
6389         ret &= test_Connect(p, tctx, handle);
6390
6391         if (!ret) {
6392                 printf("Testing domain %s failed!\n", dom_sid_string(tctx, sid));
6393         }
6394
6395         return ret;
6396 }
6397
6398 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
6399                               struct policy_handle *handle, const char *domain,
6400                               enum torture_samr_choice which_ops,
6401                               struct cli_credentials *machine_credentials)
6402 {
6403         NTSTATUS status;
6404         struct samr_LookupDomain r;
6405         struct dom_sid2 *sid = NULL;
6406         struct lsa_String n1;
6407         struct lsa_String n2;
6408         bool ret = true;
6409
6410         torture_comment(tctx, "Testing LookupDomain(%s)\n", domain);
6411
6412         /* check for correct error codes */
6413         r.in.connect_handle = handle;
6414         r.in.domain_name = &n2;
6415         r.out.sid = &sid;
6416         n2.string = NULL;
6417
6418         status = dcerpc_samr_LookupDomain(p, tctx, &r);
6419         torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER, status, "LookupDomain expected NT_STATUS_INVALID_PARAMETER");
6420
6421         init_lsa_String(&n2, "xxNODOMAINxx");
6422
6423         status = dcerpc_samr_LookupDomain(p, tctx, &r);
6424         torture_assert_ntstatus_equal(tctx, NT_STATUS_NO_SUCH_DOMAIN, status, "LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN");
6425
6426         r.in.connect_handle = handle;
6427
6428         init_lsa_String(&n1, domain);
6429         r.in.domain_name = &n1;
6430
6431         status = dcerpc_samr_LookupDomain(p, tctx, &r);
6432         torture_assert_ntstatus_ok(tctx, status, "LookupDomain");
6433
6434         if (!test_GetDomPwInfo(p, tctx, &n1)) {
6435                 ret = false;
6436         }
6437
6438         if (!test_OpenDomain(p, tctx, handle, *r.out.sid, which_ops,
6439                              machine_credentials)) {
6440                 ret = false;
6441         }
6442
6443         return ret;
6444 }
6445
6446
6447 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
6448                              struct policy_handle *handle, enum torture_samr_choice which_ops,
6449                              struct cli_credentials *machine_credentials)
6450 {
6451         NTSTATUS status;
6452         struct samr_EnumDomains r;
6453         uint32_t resume_handle = 0;
6454         uint32_t num_entries = 0;
6455         struct samr_SamArray *sam = NULL;
6456         int i;
6457         bool ret = true;
6458
6459         r.in.connect_handle = handle;
6460         r.in.resume_handle = &resume_handle;
6461         r.in.buf_size = (uint32_t)-1;
6462         r.out.resume_handle = &resume_handle;
6463         r.out.num_entries = &num_entries;
6464         r.out.sam = &sam;
6465
6466         status = dcerpc_samr_EnumDomains(p, tctx, &r);
6467         torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
6468
6469         if (!*r.out.sam) {
6470                 return false;
6471         }
6472
6473         for (i=0;i<sam->count;i++) {
6474                 if (!test_LookupDomain(p, tctx, handle,
6475                                        sam->entries[i].name.string, which_ops,
6476                                        machine_credentials)) {
6477                         ret = false;
6478                 }
6479         }
6480
6481         status = dcerpc_samr_EnumDomains(p, tctx, &r);
6482         torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
6483
6484         return ret;
6485 }
6486
6487
6488 static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
6489                          struct policy_handle *handle)
6490 {
6491         NTSTATUS status;
6492         struct samr_Connect r;
6493         struct samr_Connect2 r2;
6494         struct samr_Connect3 r3;
6495         struct samr_Connect4 r4;
6496         struct samr_Connect5 r5;
6497         union samr_ConnectInfo info;
6498         struct policy_handle h;
6499         uint32_t level_out = 0;
6500         bool ret = true, got_handle = false;
6501
6502         torture_comment(tctx, "testing samr_Connect\n");
6503
6504         r.in.system_name = 0;
6505         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6506         r.out.connect_handle = &h;
6507
6508         status = dcerpc_samr_Connect(p, tctx, &r);
6509         if (!NT_STATUS_IS_OK(status)) {
6510                 torture_comment(tctx, "Connect failed - %s\n", nt_errstr(status));
6511                 ret = false;
6512         } else {
6513                 got_handle = true;
6514                 *handle = h;
6515         }
6516
6517         torture_comment(tctx, "testing samr_Connect2\n");
6518
6519         r2.in.system_name = NULL;
6520         r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6521         r2.out.connect_handle = &h;
6522
6523         status = dcerpc_samr_Connect2(p, tctx, &r2);
6524         if (!NT_STATUS_IS_OK(status)) {
6525                 torture_comment(tctx, "Connect2 failed - %s\n", nt_errstr(status));
6526                 ret = false;
6527         } else {
6528                 if (got_handle) {
6529                         test_samr_handle_Close(p, tctx, handle);
6530                 }
6531                 got_handle = true;
6532                 *handle = h;
6533         }
6534
6535         torture_comment(tctx, "testing samr_Connect3\n");
6536
6537         r3.in.system_name = NULL;
6538         r3.in.unknown = 0;
6539         r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6540         r3.out.connect_handle = &h;
6541
6542         status = dcerpc_samr_Connect3(p, tctx, &r3);
6543         if (!NT_STATUS_IS_OK(status)) {
6544                 printf("Connect3 failed - %s\n", nt_errstr(status));
6545                 ret = false;
6546         } else {
6547                 if (got_handle) {
6548                         test_samr_handle_Close(p, tctx, handle);
6549                 }
6550                 got_handle = true;
6551                 *handle = h;
6552         }
6553
6554         torture_comment(tctx, "testing samr_Connect4\n");
6555
6556         r4.in.system_name = "";
6557         r4.in.client_version = 0;
6558         r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6559         r4.out.connect_handle = &h;
6560
6561         status = dcerpc_samr_Connect4(p, tctx, &r4);
6562         if (!NT_STATUS_IS_OK(status)) {
6563                 printf("Connect4 failed - %s\n", nt_errstr(status));
6564                 ret = false;
6565         } else {
6566                 if (got_handle) {
6567                         test_samr_handle_Close(p, tctx, handle);
6568                 }
6569                 got_handle = true;
6570                 *handle = h;
6571         }
6572
6573         torture_comment(tctx, "testing samr_Connect5\n");
6574
6575         info.info1.client_version = 0;
6576         info.info1.unknown2 = 0;
6577
6578         r5.in.system_name = "";
6579         r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6580         r5.in.level_in = 1;
6581         r5.out.level_out = &level_out;
6582         r5.in.info_in = &info;
6583         r5.out.info_out = &info;
6584         r5.out.connect_handle = &h;
6585
6586         status = dcerpc_samr_Connect5(p, tctx, &r5);
6587         if (!NT_STATUS_IS_OK(status)) {
6588                 printf("Connect5 failed - %s\n", nt_errstr(status));
6589                 ret = false;
6590         } else {
6591                 if (got_handle) {
6592                         test_samr_handle_Close(p, tctx, handle);
6593                 }
6594                 got_handle = true;
6595                 *handle = h;
6596         }
6597
6598         return ret;
6599 }
6600
6601
6602 bool torture_rpc_samr(struct torture_context *torture)
6603 {
6604         NTSTATUS status;
6605         struct dcerpc_pipe *p;
6606         bool ret = true;
6607         struct policy_handle handle;
6608
6609         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6610         if (!NT_STATUS_IS_OK(status)) {
6611                 return false;
6612         }
6613
6614         ret &= test_Connect(p, torture, &handle);
6615
6616         if (!torture_setting_bool(torture, "samba3", false)) {
6617                 ret &= test_QuerySecurity(p, torture, &handle);
6618         }
6619
6620         ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER, NULL);
6621
6622         ret &= test_SetDsrmPassword(p, torture, &handle);
6623
6624         ret &= test_Shutdown(p, torture, &handle);
6625
6626         ret &= test_samr_handle_Close(p, torture, &handle);
6627
6628         return ret;
6629 }
6630
6631
6632 bool torture_rpc_samr_users(struct torture_context *torture)
6633 {
6634         NTSTATUS status;
6635         struct dcerpc_pipe *p;
6636         bool ret = true;
6637         struct policy_handle handle;
6638
6639         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6640         if (!NT_STATUS_IS_OK(status)) {
6641                 return false;
6642         }
6643
6644         ret &= test_Connect(p, torture, &handle);
6645
6646         if (!torture_setting_bool(torture, "samba3", false)) {
6647                 ret &= test_QuerySecurity(p, torture, &handle);
6648         }
6649
6650         ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES, NULL);
6651
6652         ret &= test_SetDsrmPassword(p, torture, &handle);
6653
6654         ret &= test_Shutdown(p, torture, &handle);
6655
6656         ret &= test_samr_handle_Close(p, torture, &handle);
6657
6658         return ret;
6659 }
6660
6661
6662 bool torture_rpc_samr_passwords(struct torture_context *torture)
6663 {
6664         NTSTATUS status;
6665         struct dcerpc_pipe *p;
6666         bool ret = true;
6667         struct policy_handle handle;
6668
6669         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6670         if (!NT_STATUS_IS_OK(status)) {
6671                 return false;
6672         }
6673
6674         ret &= test_Connect(p, torture, &handle);
6675
6676         ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS, NULL);
6677
6678         ret &= test_samr_handle_Close(p, torture, &handle);
6679
6680         return ret;
6681 }
6682
6683 static bool torture_rpc_samr_pwdlastset(struct torture_context *torture,
6684                                         struct dcerpc_pipe *p2,
6685                                         struct cli_credentials *machine_credentials)
6686 {
6687         NTSTATUS status;
6688         struct dcerpc_pipe *p;
6689         bool ret = true;
6690         struct policy_handle handle;
6691
6692         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6693         if (!NT_STATUS_IS_OK(status)) {
6694                 return false;
6695         }
6696
6697         ret &= test_Connect(p, torture, &handle);
6698
6699         ret &= test_EnumDomains(p, torture, &handle,
6700                                 TORTURE_SAMR_PASSWORDS_PWDLASTSET,
6701                                 machine_credentials);
6702
6703         ret &= test_samr_handle_Close(p, torture, &handle);
6704
6705         return ret;
6706 }
6707
6708 struct torture_suite *torture_rpc_samr_passwords_pwdlastset(TALLOC_CTX *mem_ctx)
6709 {
6710         struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-PASSWORDS-PWDLASTSET");
6711         struct torture_rpc_tcase *tcase;
6712
6713         tcase = torture_suite_add_machine_rpc_iface_tcase(suite, "samr",
6714                                                           &ndr_table_samr,
6715                                                           TEST_ACCOUNT_NAME_PWD);
6716
6717         torture_rpc_tcase_add_test_creds(tcase, "pwdLastSet",
6718                                          torture_rpc_samr_pwdlastset);
6719
6720         return suite;
6721 }
6722
6723 static bool torture_rpc_samr_users_privileges_delete_user(struct torture_context *torture,
6724                                                           struct dcerpc_pipe *p2,
6725                                                           struct cli_credentials *machine_credentials)
6726 {
6727         NTSTATUS status;
6728         struct dcerpc_pipe *p;
6729         bool ret = true;
6730         struct policy_handle handle;
6731
6732         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6733         if (!NT_STATUS_IS_OK(status)) {
6734                 return false;
6735         }
6736
6737         ret &= test_Connect(p, torture, &handle);
6738
6739         ret &= test_EnumDomains(p, torture, &handle,
6740                                 TORTURE_SAMR_USER_PRIVILEGES,
6741                                 machine_credentials);
6742
6743         ret &= test_samr_handle_Close(p, torture, &handle);
6744
6745         return ret;
6746 }
6747
6748 struct torture_suite *torture_rpc_samr_user_privileges(TALLOC_CTX *mem_ctx)
6749 {
6750         struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-USERS-PRIVILEGES");
6751         struct torture_rpc_tcase *tcase;
6752
6753         tcase = torture_suite_add_machine_rpc_iface_tcase(suite, "samr",
6754                                                           &ndr_table_samr,
6755                                                           TEST_ACCOUNT_NAME_PWD);
6756
6757         torture_rpc_tcase_add_test_creds(tcase, "delete_privileged_user",
6758                                          torture_rpc_samr_users_privileges_delete_user);
6759
6760         return suite;
6761 }
6762
6763 static bool torture_rpc_samr_many_accounts(struct torture_context *torture,
6764                                            struct dcerpc_pipe *p2,
6765                                            struct cli_credentials *machine_credentials)
6766 {
6767         NTSTATUS status;
6768         struct dcerpc_pipe *p;
6769         bool ret = true;
6770         struct policy_handle handle;
6771
6772         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6773         if (!NT_STATUS_IS_OK(status)) {
6774                 return false;
6775         }
6776
6777         ret &= test_Connect(p, torture, &handle);
6778
6779         ret &= test_EnumDomains(p, torture, &handle,
6780                                 TORTURE_SAMR_MANY_ACCOUNTS,
6781                                 machine_credentials);
6782
6783         ret &= test_samr_handle_Close(p, torture, &handle);
6784
6785         return ret;
6786 }
6787
6788 static bool torture_rpc_samr_many_groups(struct torture_context *torture,
6789                                          struct dcerpc_pipe *p2,
6790                                          struct cli_credentials *machine_credentials)
6791 {
6792         NTSTATUS status;
6793         struct dcerpc_pipe *p;
6794         bool ret = true;
6795         struct policy_handle handle;
6796
6797         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6798         if (!NT_STATUS_IS_OK(status)) {
6799                 return false;
6800         }
6801
6802         ret &= test_Connect(p, torture, &handle);
6803
6804         ret &= test_EnumDomains(p, torture, &handle,
6805                                 TORTURE_SAMR_MANY_GROUPS,
6806                                 machine_credentials);
6807
6808         ret &= test_samr_handle_Close(p, torture, &handle);
6809
6810         return ret;
6811 }
6812
6813 static bool torture_rpc_samr_many_aliases(struct torture_context *torture,
6814                                           struct dcerpc_pipe *p2,
6815                                           struct cli_credentials *machine_credentials)
6816 {
6817         NTSTATUS status;
6818         struct dcerpc_pipe *p;
6819         bool ret = true;
6820         struct policy_handle handle;
6821
6822         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
6823         if (!NT_STATUS_IS_OK(status)) {
6824                 return false;
6825         }
6826
6827         ret &= test_Connect(p, torture, &handle);
6828
6829         ret &= test_EnumDomains(p, torture, &handle,
6830                                 TORTURE_SAMR_MANY_ALIASES,
6831                                 machine_credentials);
6832
6833         ret &= test_samr_handle_Close(p, torture, &handle);
6834
6835         return ret;
6836 }
6837
6838 struct torture_suite *torture_rpc_samr_large_dc(TALLOC_CTX *mem_ctx)
6839 {
6840         struct torture_suite *suite = torture_suite_create(mem_ctx, "SAMR-LARGE-DC");
6841         struct torture_rpc_tcase *tcase;
6842
6843         tcase = torture_suite_add_machine_rpc_iface_tcase(suite, "samr",
6844                                                           &ndr_table_samr,
6845                                                           TEST_ACCOUNT_NAME);
6846
6847         torture_rpc_tcase_add_test_creds(tcase, "many_aliases",
6848                                          torture_rpc_samr_many_aliases);
6849         torture_rpc_tcase_add_test_creds(tcase, "many_groups",
6850                                          torture_rpc_samr_many_groups);
6851         torture_rpc_tcase_add_test_creds(tcase, "many_accounts",
6852                                          torture_rpc_samr_many_accounts);
6853
6854         return suite;
6855 }