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