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