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