Merge branch 'v4-0-test' of ssh://git.samba.org/data/git/samba into v4-0-test
[ira/wip.git] / source4 / torture / rpc / samr.c
1 /* 
2    Unix SMB/CIFS implementation.
3    test suite for samr rpc operations
4
5    Copyright (C) Andrew Tridgell 2003
6    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
7    
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 #include "param/param.h"
32
33 #define TEST_ACCOUNT_NAME "samrtorturetest"
34 #define TEST_ALIASNAME "samrtorturetestalias"
35 #define TEST_GROUPNAME "samrtorturetestgroup"
36 #define TEST_MACHINENAME "samrtestmach$"
37 #define TEST_DOMAINNAME "samrtestdom$"
38
39 enum torture_samr_choice {
40         TORTURE_SAMR_PASSWORDS,
41         TORTURE_SAMR_USER_ATTRIBUTES,
42         TORTURE_SAMR_OTHER
43 };
44
45 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
46                                struct policy_handle *handle);
47
48 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
49                                 struct policy_handle *handle);
50
51 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
52                                struct policy_handle *handle);
53
54 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
55                                 const char *acct_name, 
56                                 struct policy_handle *domain_handle, char **password);
57
58 static void init_lsa_String(struct lsa_String *string, const char *s)
59 {
60         string->string = s;
61 }
62
63 bool test_samr_handle_Close(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
64                                    struct policy_handle *handle)
65 {
66         NTSTATUS status;
67         struct samr_Close r;
68
69         r.in.handle = handle;
70         r.out.handle = handle;
71
72         status = dcerpc_samr_Close(p, mem_ctx, &r);
73         if (!NT_STATUS_IS_OK(status)) {
74                 printf("Close handle failed - %s\n", nt_errstr(status));
75                 return false;
76         }
77
78         return true;
79 }
80
81 static bool test_Shutdown(struct dcerpc_pipe *p, struct torture_context *tctx,
82                        struct policy_handle *handle)
83 {
84         NTSTATUS status;
85         struct samr_Shutdown r;
86
87         if (!torture_setting_bool(tctx, "dangerous", false)) {
88                 printf("samr_Shutdown disabled - enable dangerous tests to use\n");
89                 return true;
90         }
91
92         r.in.connect_handle = handle;
93
94         printf("testing samr_Shutdown\n");
95
96         status = dcerpc_samr_Shutdown(p, tctx, &r);
97         if (!NT_STATUS_IS_OK(status)) {
98                 printf("samr_Shutdown failed - %s\n", nt_errstr(status));
99                 return false;
100         }
101
102         return true;
103 }
104
105 static bool test_SetDsrmPassword(struct dcerpc_pipe *p, struct torture_context *tctx,
106                                  struct policy_handle *handle)
107 {
108         NTSTATUS status;
109         struct samr_SetDsrmPassword r;
110         struct lsa_String string;
111         struct samr_Password hash;
112
113         if (!torture_setting_bool(tctx, "dangerous", false)) {
114                 printf("samr_SetDsrmPassword disabled - enable dangerous tests to use\n");
115                 return true;
116         }
117
118         E_md4hash("TeSTDSRM123", hash.hash);
119
120         init_lsa_String(&string, "Administrator");
121
122         r.in.name = &string;
123         r.in.unknown = 0;
124         r.in.hash = &hash;
125
126         printf("testing samr_SetDsrmPassword\n");
127
128         status = dcerpc_samr_SetDsrmPassword(p, tctx, &r);
129         if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
130                 printf("samr_SetDsrmPassword failed - %s\n", nt_errstr(status));
131                 return false;
132         }
133
134         return true;
135 }
136
137
138 static bool test_QuerySecurity(struct dcerpc_pipe *p, 
139                                struct torture_context *tctx, 
140                                struct policy_handle *handle)
141 {
142         NTSTATUS status;
143         struct samr_QuerySecurity r;
144         struct samr_SetSecurity s;
145
146         r.in.handle = handle;
147         r.in.sec_info = 7;
148
149         status = dcerpc_samr_QuerySecurity(p, tctx, &r);
150         if (!NT_STATUS_IS_OK(status)) {
151                 printf("QuerySecurity failed - %s\n", nt_errstr(status));
152                 return false;
153         }
154
155         if (r.out.sdbuf == NULL) {
156                 return false;
157         }
158
159         s.in.handle = handle;
160         s.in.sec_info = 7;
161         s.in.sdbuf = r.out.sdbuf;
162
163         if (torture_setting_bool(tctx, "samba4", false)) {
164                 printf("skipping SetSecurity test against Samba4\n");
165                 return true;
166         }
167
168         status = dcerpc_samr_SetSecurity(p, tctx, &s);
169         if (!NT_STATUS_IS_OK(status)) {
170                 printf("SetSecurity failed - %s\n", nt_errstr(status));
171                 return false;
172         }
173
174         status = dcerpc_samr_QuerySecurity(p, tctx, &r);
175         if (!NT_STATUS_IS_OK(status)) {
176                 printf("QuerySecurity failed - %s\n", nt_errstr(status));
177                 return false;
178         }
179
180         return true;
181 }
182
183
184 static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx, 
185                              struct policy_handle *handle, uint32_t base_acct_flags,
186                              const char *base_account_name)
187 {
188         NTSTATUS status;
189         struct samr_SetUserInfo s;
190         struct samr_SetUserInfo2 s2;
191         struct samr_QueryUserInfo q;
192         struct samr_QueryUserInfo q0;
193         union samr_UserInfo u;
194         bool ret = true;
195         const char *test_account_name;
196
197         uint32_t user_extra_flags = 0;
198         if (base_acct_flags == ACB_NORMAL) {
199                 /* When created, accounts are expired by default */
200                 user_extra_flags = ACB_PW_EXPIRED;
201         }
202
203         s.in.user_handle = handle;
204         s.in.info = &u;
205
206         s2.in.user_handle = handle;
207         s2.in.info = &u;
208
209         q.in.user_handle = handle;
210         q.out.info = &u;
211         q0 = q;
212
213 #define TESTCALL(call, r) \
214                 status = dcerpc_samr_ ##call(p, tctx, &r); \
215                 if (!NT_STATUS_IS_OK(status)) { \
216                         printf(#call " level %u failed - %s (%s)\n", \
217                                r.in.level, nt_errstr(status), __location__); \
218                         ret = false; \
219                         break; \
220                 }
221
222 #define STRING_EQUAL(s1, s2, field) \
223                 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
224                         printf("Failed to set %s to '%s' (%s)\n", \
225                                #field, s2, __location__); \
226                         ret = false; \
227                         break; \
228                 }
229
230 #define INT_EQUAL(i1, i2, field) \
231                 if (i1 != i2) { \
232                         printf("Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
233                                #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
234                         ret = false; \
235                         break; \
236                 }
237
238 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
239                 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
240                 q.in.level = lvl1; \
241                 TESTCALL(QueryUserInfo, q) \
242                 s.in.level = lvl1; \
243                 s2.in.level = lvl1; \
244                 u = *q.out.info; \
245                 if (lvl1 == 21) { \
246                         ZERO_STRUCT(u.info21); \
247                         u.info21.fields_present = fpval; \
248                 } \
249                 init_lsa_String(&u.info ## lvl1.field1, value); \
250                 TESTCALL(SetUserInfo, s) \
251                 TESTCALL(SetUserInfo2, s2) \
252                 init_lsa_String(&u.info ## lvl1.field1, ""); \
253                 TESTCALL(QueryUserInfo, q); \
254                 u = *q.out.info; \
255                 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
256                 q.in.level = lvl2; \
257                 TESTCALL(QueryUserInfo, q) \
258                 u = *q.out.info; \
259                 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
260         } while (0)
261
262 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
263                 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
264                 q.in.level = lvl1; \
265                 TESTCALL(QueryUserInfo, q) \
266                 s.in.level = lvl1; \
267                 s2.in.level = lvl1; \
268                 u = *q.out.info; \
269                 if (lvl1 == 21) { \
270                         uint8_t *bits = u.info21.logon_hours.bits; \
271                         ZERO_STRUCT(u.info21); \
272                         if (fpval == SAMR_FIELD_LOGON_HOURS) { \
273                                 u.info21.logon_hours.units_per_week = 168; \
274                                 u.info21.logon_hours.bits = bits; \
275                         } \
276                         u.info21.fields_present = fpval; \
277                 } \
278                 u.info ## lvl1.field1 = value; \
279                 TESTCALL(SetUserInfo, s) \
280                 TESTCALL(SetUserInfo2, s2) \
281                 u.info ## lvl1.field1 = 0; \
282                 TESTCALL(QueryUserInfo, q); \
283                 u = *q.out.info; \
284                 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
285                 q.in.level = lvl2; \
286                 TESTCALL(QueryUserInfo, q) \
287                 u = *q.out.info; \
288                 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
289         } while (0)
290
291 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
292         TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
293         } while (0)
294
295         q0.in.level = 12;
296         do { TESTCALL(QueryUserInfo, q0) } while (0);
297
298         TEST_USERINFO_STRING(2, comment,  1, comment, "xx2-1 comment", 0);
299         TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
300         TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment", 
301                            SAMR_FIELD_COMMENT);
302
303         test_account_name = talloc_asprintf(tctx, "%sxx7-1", base_account_name);
304         TEST_USERINFO_STRING(7, account_name,  1, account_name, base_account_name, 0);
305         test_account_name = talloc_asprintf(tctx, "%sxx7-3", base_account_name);
306         TEST_USERINFO_STRING(7, account_name,  3, account_name, base_account_name, 0);
307         test_account_name = talloc_asprintf(tctx, "%sxx7-5", base_account_name);
308         TEST_USERINFO_STRING(7, account_name,  5, account_name, base_account_name, 0);
309         test_account_name = talloc_asprintf(tctx, "%sxx7-6", base_account_name);
310         TEST_USERINFO_STRING(7, account_name,  6, account_name, base_account_name, 0);
311         test_account_name = talloc_asprintf(tctx, "%sxx7-7", base_account_name);
312         TEST_USERINFO_STRING(7, account_name,  7, account_name, base_account_name, 0);
313         test_account_name = talloc_asprintf(tctx, "%sxx7-21", base_account_name);
314         TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
315         test_account_name = base_account_name;
316         TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name, 
317                            SAMR_FIELD_ACCOUNT_NAME);
318
319         TEST_USERINFO_STRING(6, full_name,  1, full_name, "xx6-1 full_name", 0);
320         TEST_USERINFO_STRING(6, full_name,  3, full_name, "xx6-3 full_name", 0);
321         TEST_USERINFO_STRING(6, full_name,  5, full_name, "xx6-5 full_name", 0);
322         TEST_USERINFO_STRING(6, full_name,  6, full_name, "xx6-6 full_name", 0);
323         TEST_USERINFO_STRING(6, full_name,  8, full_name, "xx6-8 full_name", 0);
324         TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
325         TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
326         TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name", 
327                            SAMR_FIELD_FULL_NAME);
328
329         TEST_USERINFO_STRING(6, full_name,  1, full_name, "", 0);
330         TEST_USERINFO_STRING(6, full_name,  3, full_name, "", 0);
331         TEST_USERINFO_STRING(6, full_name,  5, full_name, "", 0);
332         TEST_USERINFO_STRING(6, full_name,  6, full_name, "", 0);
333         TEST_USERINFO_STRING(6, full_name,  8, full_name, "", 0);
334         TEST_USERINFO_STRING(6, full_name, 21, full_name, "", 0);
335         TEST_USERINFO_STRING(8, full_name, 21, full_name, "", 0);
336         TEST_USERINFO_STRING(21, full_name, 21, full_name, "", 
337                            SAMR_FIELD_FULL_NAME);
338
339         TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
340         TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
341         TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
342         TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script", 
343                            SAMR_FIELD_LOGON_SCRIPT);
344
345         TEST_USERINFO_STRING(12, profile_path,  3, profile_path, "xx12-3 profile_path", 0);
346         TEST_USERINFO_STRING(12, profile_path,  5, profile_path, "xx12-5 profile_path", 0);
347         TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
348         TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path", 
349                            SAMR_FIELD_PROFILE_PATH);
350
351         TEST_USERINFO_STRING(10, home_directory, 3, home_directory, "xx10-3 home_directory", 0);
352         TEST_USERINFO_STRING(10, home_directory, 5, home_directory, "xx10-5 home_directory", 0);
353         TEST_USERINFO_STRING(10, home_directory, 21, home_directory, "xx10-21 home_directory", 0);
354         TEST_USERINFO_STRING(21, home_directory, 21, home_directory, "xx21-21 home_directory",
355                              SAMR_FIELD_HOME_DIRECTORY);
356         TEST_USERINFO_STRING(21, home_directory, 10, home_directory, "xx21-10 home_directory",
357                              SAMR_FIELD_HOME_DIRECTORY);
358
359         TEST_USERINFO_STRING(10, home_drive, 3, home_drive, "xx10-3 home_drive", 0);
360         TEST_USERINFO_STRING(10, home_drive, 5, home_drive, "xx10-5 home_drive", 0);
361         TEST_USERINFO_STRING(10, home_drive, 21, home_drive, "xx10-21 home_drive", 0);
362         TEST_USERINFO_STRING(21, home_drive, 21, home_drive, "xx21-21 home_drive",
363                              SAMR_FIELD_HOME_DRIVE);
364         TEST_USERINFO_STRING(21, home_drive, 10, home_drive, "xx21-10 home_drive",
365                              SAMR_FIELD_HOME_DRIVE);
366         
367         TEST_USERINFO_STRING(13, description,  1, description, "xx13-1 description", 0);
368         TEST_USERINFO_STRING(13, description,  5, description, "xx13-5 description", 0);
369         TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
370         TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description", 
371                            SAMR_FIELD_DESCRIPTION);
372
373         TEST_USERINFO_STRING(14, workstations,  3, workstations, "14workstation3", 0);
374         TEST_USERINFO_STRING(14, workstations,  5, workstations, "14workstation4", 0);
375         TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
376         TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21", 
377                            SAMR_FIELD_WORKSTATIONS);
378         TEST_USERINFO_STRING(21, workstations, 3, workstations, "21workstation3", 
379                            SAMR_FIELD_WORKSTATIONS);
380         TEST_USERINFO_STRING(21, workstations, 5, workstations, "21workstation5", 
381                            SAMR_FIELD_WORKSTATIONS);
382         TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14", 
383                            SAMR_FIELD_WORKSTATIONS);
384
385         TEST_USERINFO_STRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
386         TEST_USERINFO_STRING(21, parameters, 21, parameters, "xx21-21 parameters", 
387                            SAMR_FIELD_PARAMETERS);
388         TEST_USERINFO_STRING(21, parameters, 20, parameters, "xx21-20 parameters", 
389                            SAMR_FIELD_PARAMETERS);
390
391         TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
392         TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
393         TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__, 
394                           SAMR_FIELD_COUNTRY_CODE);
395         TEST_USERINFO_INT(21, country_code, 2, country_code, __LINE__, 
396                           SAMR_FIELD_COUNTRY_CODE);
397
398         TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
399         TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__, 
400                           SAMR_FIELD_CODE_PAGE);
401         TEST_USERINFO_INT(21, code_page, 2, code_page, __LINE__, 
402                           SAMR_FIELD_CODE_PAGE);
403
404         TEST_USERINFO_INT(17, acct_expiry, 21, acct_expiry, __LINE__, 0);
405         TEST_USERINFO_INT(17, acct_expiry, 5, acct_expiry, __LINE__, 0);
406         TEST_USERINFO_INT(21, acct_expiry, 21, acct_expiry, __LINE__, 
407                           SAMR_FIELD_ACCT_EXPIRY);
408         TEST_USERINFO_INT(21, acct_expiry, 5, acct_expiry, __LINE__, 
409                           SAMR_FIELD_ACCT_EXPIRY);
410         TEST_USERINFO_INT(21, acct_expiry, 17, acct_expiry, __LINE__, 
411                           SAMR_FIELD_ACCT_EXPIRY);
412
413         TEST_USERINFO_INT(4, logon_hours.bits[3],  3, logon_hours.bits[3], 1, 0);
414         TEST_USERINFO_INT(4, logon_hours.bits[3],  5, logon_hours.bits[3], 2, 0);
415         TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
416         TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4, 
417                           SAMR_FIELD_LOGON_HOURS);
418
419         TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags, 
420                               (base_acct_flags  | ACB_DISABLED | ACB_HOMDIRREQ), 
421                               (base_acct_flags  | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags), 
422                               0);
423         TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags, 
424                               (base_acct_flags  | ACB_DISABLED), 
425                               (base_acct_flags  | ACB_DISABLED | user_extra_flags), 
426                               0);
427         
428         /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
429         TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags, 
430                               (base_acct_flags  | ACB_DISABLED | ACB_PWNOEXP), 
431                               (base_acct_flags  | ACB_DISABLED | ACB_PWNOEXP), 
432                               0);
433         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
434                               (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ), 
435                               (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags), 
436                               0);
437
438
439         /* The 'autolock' flag doesn't stick - check this */
440         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
441                               (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK), 
442                               (base_acct_flags | ACB_DISABLED | user_extra_flags), 
443                               0);
444 #if 0
445         /* Removing the 'disabled' flag doesn't stick - check this */
446         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
447                               (base_acct_flags), 
448                               (base_acct_flags | ACB_DISABLED | user_extra_flags), 
449                               0);
450 #endif
451         /* The 'store plaintext' flag does stick */
452         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
453                               (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED), 
454                               (base_acct_flags | ACB_DISABLED | ACB_ENC_TXT_PWD_ALLOWED | user_extra_flags), 
455                               0);
456         /* The 'use DES' flag does stick */
457         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
458                               (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY), 
459                               (base_acct_flags | ACB_DISABLED | ACB_USE_DES_KEY_ONLY | user_extra_flags), 
460                               0);
461         /* The 'don't require kerberos pre-authentication flag does stick */
462         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
463                               (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH), 
464                               (base_acct_flags | ACB_DISABLED | ACB_DONT_REQUIRE_PREAUTH | user_extra_flags), 
465                               0);
466         /* The 'no kerberos PAC required' flag sticks */
467         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
468                               (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD), 
469                               (base_acct_flags | ACB_DISABLED | ACB_NO_AUTH_DATA_REQD | user_extra_flags), 
470                               0);
471
472         TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags, 
473                               (base_acct_flags | ACB_DISABLED), 
474                               (base_acct_flags | ACB_DISABLED | user_extra_flags), 
475                               SAMR_FIELD_ACCT_FLAGS);
476
477 #if 0
478         /* these fail with win2003 - it appears you can't set the primary gid?
479            the set succeeds, but the gid isn't changed. Very weird! */
480         TEST_USERINFO_INT(9, primary_gid,  1, primary_gid, 513);
481         TEST_USERINFO_INT(9, primary_gid,  3, primary_gid, 513);
482         TEST_USERINFO_INT(9, primary_gid,  5, primary_gid, 513);
483         TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
484 #endif
485
486         return ret;
487 }
488
489 /*
490   generate a random password for password change tests
491 */
492 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
493 {
494         size_t len = MAX(8, min_len) + (random() % 6);
495         char *s = generate_random_str(mem_ctx, len);
496         printf("Generated password '%s'\n", s);
497         return s;
498 }
499
500 /*
501   generate a random password for password change tests (fixed length)
502 */
503 static char *samr_rand_pass_fixed_len(TALLOC_CTX *mem_ctx, int len)
504 {
505         char *s = generate_random_str(mem_ctx, len);
506         printf("Generated password '%s'\n", s);
507         return s;
508 }
509
510 static bool test_SetUserPass(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
511                              struct policy_handle *handle, char **password)
512 {
513         NTSTATUS status;
514         struct samr_SetUserInfo s;
515         union samr_UserInfo u;
516         bool ret = true;
517         DATA_BLOB session_key;
518         char *newpass;
519         struct samr_GetUserPwInfo pwp;
520         int policy_min_pw_len = 0;
521         pwp.in.user_handle = handle;
522
523         status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
524         if (NT_STATUS_IS_OK(status)) {
525                 policy_min_pw_len = pwp.out.info.min_password_length;
526         }
527         newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
528
529         s.in.user_handle = handle;
530         s.in.info = &u;
531         s.in.level = 24;
532
533         encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
534         /* w2k3 ignores this length */
535         u.info24.pw_len = strlen_m(newpass) * 2;
536
537         status = dcerpc_fetch_session_key(p, &session_key);
538         if (!NT_STATUS_IS_OK(status)) {
539                 printf("SetUserInfo level %u - no session key - %s\n",
540                        s.in.level, nt_errstr(status));
541                 return false;
542         }
543
544         arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
545
546         printf("Testing SetUserInfo level 24 (set password)\n");
547
548         status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
549         if (!NT_STATUS_IS_OK(status)) {
550                 printf("SetUserInfo level %u failed - %s\n",
551                        s.in.level, nt_errstr(status));
552                 ret = false;
553         } else {
554                 *password = newpass;
555         }
556
557         return ret;
558 }
559
560
561 static bool test_SetUserPass_23(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
562                                 struct policy_handle *handle, uint32_t fields_present,
563                                 char **password)
564 {
565         NTSTATUS status;
566         struct samr_SetUserInfo s;
567         union samr_UserInfo u;
568         bool ret = true;
569         DATA_BLOB session_key;
570         char *newpass;
571         struct samr_GetUserPwInfo pwp;
572         int policy_min_pw_len = 0;
573         pwp.in.user_handle = handle;
574
575         status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
576         if (NT_STATUS_IS_OK(status)) {
577                 policy_min_pw_len = pwp.out.info.min_password_length;
578         }
579         newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
580
581         s.in.user_handle = handle;
582         s.in.info = &u;
583         s.in.level = 23;
584
585         ZERO_STRUCT(u);
586
587         u.info23.info.fields_present = fields_present;
588
589         encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
590
591         status = dcerpc_fetch_session_key(p, &session_key);
592         if (!NT_STATUS_IS_OK(status)) {
593                 printf("SetUserInfo level %u - no session key - %s\n",
594                        s.in.level, nt_errstr(status));
595                 return false;
596         }
597
598         arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
599
600         printf("Testing SetUserInfo level 23 (set password)\n");
601
602         status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
603         if (!NT_STATUS_IS_OK(status)) {
604                 printf("SetUserInfo level %u failed - %s\n",
605                        s.in.level, nt_errstr(status));
606                 ret = false;
607         } else {
608                 *password = newpass;
609         }
610
611         encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
612
613         status = dcerpc_fetch_session_key(p, &session_key);
614         if (!NT_STATUS_IS_OK(status)) {
615                 printf("SetUserInfo level %u - no session key - %s\n",
616                        s.in.level, nt_errstr(status));
617                 return false;
618         }
619
620         /* This should break the key nicely */
621         session_key.length--;
622         arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
623
624         printf("Testing SetUserInfo level 23 (set password) with wrong password\n");
625
626         status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
627         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
628                 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
629                        s.in.level, nt_errstr(status));
630                 ret = false;
631         }
632
633         return ret;
634 }
635
636
637 static bool test_SetUserPassEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
638                                struct policy_handle *handle, bool makeshort, 
639                                char **password)
640 {
641         NTSTATUS status;
642         struct samr_SetUserInfo s;
643         union samr_UserInfo u;
644         bool ret = true;
645         DATA_BLOB session_key;
646         DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
647         uint8_t confounder[16];
648         char *newpass;
649         struct MD5Context ctx;
650         struct samr_GetUserPwInfo pwp;
651         int policy_min_pw_len = 0;
652         pwp.in.user_handle = handle;
653
654         status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
655         if (NT_STATUS_IS_OK(status)) {
656                 policy_min_pw_len = pwp.out.info.min_password_length;
657         }
658         if (makeshort && policy_min_pw_len) {
659                 newpass = samr_rand_pass_fixed_len(mem_ctx, policy_min_pw_len - 1);
660         } else {
661                 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
662         }
663
664         s.in.user_handle = handle;
665         s.in.info = &u;
666         s.in.level = 26;
667
668         encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
669         u.info26.pw_len = strlen(newpass);
670
671         status = dcerpc_fetch_session_key(p, &session_key);
672         if (!NT_STATUS_IS_OK(status)) {
673                 printf("SetUserInfo level %u - no session key - %s\n",
674                        s.in.level, nt_errstr(status));
675                 return false;
676         }
677
678         generate_random_buffer((uint8_t *)confounder, 16);
679
680         MD5Init(&ctx);
681         MD5Update(&ctx, confounder, 16);
682         MD5Update(&ctx, session_key.data, session_key.length);
683         MD5Final(confounded_session_key.data, &ctx);
684
685         arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
686         memcpy(&u.info26.password.data[516], confounder, 16);
687
688         printf("Testing SetUserInfo level 26 (set password ex)\n");
689
690         status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
691         if (!NT_STATUS_IS_OK(status)) {
692                 printf("SetUserInfo level %u failed - %s\n",
693                        s.in.level, nt_errstr(status));
694                 ret = false;
695         } else {
696                 *password = newpass;
697         }
698
699         /* This should break the key nicely */
700         confounded_session_key.data[0]++;
701
702         arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
703         memcpy(&u.info26.password.data[516], confounder, 16);
704
705         printf("Testing SetUserInfo level 26 (set password ex) with wrong session key\n");
706
707         status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
708         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
709                 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD: %s\n",
710                        s.in.level, nt_errstr(status));
711                 ret = false;
712         } else {
713                 *password = newpass;
714         }
715
716         return ret;
717 }
718
719 static bool test_SetUserPass_25(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
720                                 struct policy_handle *handle, uint32_t fields_present,
721                                 char **password)
722 {
723         NTSTATUS status;
724         struct samr_SetUserInfo s;
725         union samr_UserInfo u;
726         bool ret = true;
727         DATA_BLOB session_key;
728         DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
729         struct MD5Context ctx;
730         uint8_t confounder[16];
731         char *newpass;
732         struct samr_GetUserPwInfo pwp;
733         int policy_min_pw_len = 0;
734         pwp.in.user_handle = handle;
735
736         status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
737         if (NT_STATUS_IS_OK(status)) {
738                 policy_min_pw_len = pwp.out.info.min_password_length;
739         }
740         newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
741
742         s.in.user_handle = handle;
743         s.in.info = &u;
744         s.in.level = 25;
745
746         ZERO_STRUCT(u);
747
748         u.info25.info.fields_present = fields_present;
749
750         encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
751
752         status = dcerpc_fetch_session_key(p, &session_key);
753         if (!NT_STATUS_IS_OK(status)) {
754                 printf("SetUserInfo level %u - no session key - %s\n",
755                        s.in.level, nt_errstr(status));
756                 return false;
757         }
758
759         generate_random_buffer((uint8_t *)confounder, 16);
760
761         MD5Init(&ctx);
762         MD5Update(&ctx, confounder, 16);
763         MD5Update(&ctx, session_key.data, session_key.length);
764         MD5Final(confounded_session_key.data, &ctx);
765
766         arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
767         memcpy(&u.info25.password.data[516], confounder, 16);
768
769         printf("Testing SetUserInfo level 25 (set password ex)\n");
770
771         status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
772         if (!NT_STATUS_IS_OK(status)) {
773                 printf("SetUserInfo level %u failed - %s\n",
774                        s.in.level, nt_errstr(status));
775                 ret = false;
776         } else {
777                 *password = newpass;
778         }
779
780         /* This should break the key nicely */
781         confounded_session_key.data[0]++;
782
783         arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
784         memcpy(&u.info25.password.data[516], confounder, 16);
785
786         printf("Testing SetUserInfo level 25 (set password ex) with wrong session key\n");
787
788         status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
789         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
790                 printf("SetUserInfo level %u should have failed with WRONG_PASSWORD- %s\n",
791                        s.in.level, nt_errstr(status));
792                 ret = false;
793         }
794
795         return ret;
796 }
797
798 static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
799                                struct policy_handle *handle)
800 {
801         NTSTATUS status;
802         struct samr_SetAliasInfo r;
803         struct samr_QueryAliasInfo q;
804         uint16_t levels[] = {2, 3};
805         int i;
806         bool ret = true;
807
808         /* Ignoring switch level 1, as that includes the number of members for the alias
809          * and setting this to a wrong value might have negative consequences
810          */
811
812         for (i=0;i<ARRAY_SIZE(levels);i++) {
813                 printf("Testing SetAliasInfo level %u\n", levels[i]);
814
815                 r.in.alias_handle = handle;
816                 r.in.level = levels[i];
817                 r.in.info  = talloc(tctx, union samr_AliasInfo);
818                 switch (r.in.level) {
819                     case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
820                     case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
821                                 "Test Description, should test I18N as well"); break;
822                     case ALIASINFOALL: printf("ALIASINFOALL ignored\n"); break;
823                 }
824
825                 status = dcerpc_samr_SetAliasInfo(p, tctx, &r);
826                 if (!NT_STATUS_IS_OK(status)) {
827                         printf("SetAliasInfo level %u failed - %s\n",
828                                levels[i], nt_errstr(status));
829                         ret = false;
830                 }
831
832                 q.in.alias_handle = handle;
833                 q.in.level = levels[i];
834
835                 status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
836                 if (!NT_STATUS_IS_OK(status)) {
837                         printf("QueryAliasInfo level %u failed - %s\n",
838                                levels[i], nt_errstr(status));
839                         ret = false;
840                 }
841         }
842
843         return ret;
844 }
845
846 static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context *tctx,
847                                   struct policy_handle *user_handle)
848 {
849         struct samr_GetGroupsForUser r;
850         NTSTATUS status;
851         bool ret = true;
852
853         printf("testing GetGroupsForUser\n");
854
855         r.in.user_handle = user_handle;
856
857         status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
858         if (!NT_STATUS_IS_OK(status)) {
859                 printf("GetGroupsForUser failed - %s\n",nt_errstr(status));
860                 ret = false;
861         }
862
863         return ret;
864
865 }
866
867 static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
868                               struct lsa_String *domain_name)
869 {
870         NTSTATUS status;
871         struct samr_GetDomPwInfo r;
872         bool ret = true;
873
874         r.in.domain_name = domain_name;
875         printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
876
877         status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
878         if (!NT_STATUS_IS_OK(status)) {
879                 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
880                 ret = false;
881         }
882
883         r.in.domain_name->string = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
884         printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
885
886         status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
887         if (!NT_STATUS_IS_OK(status)) {
888                 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
889                 ret = false;
890         }
891
892         r.in.domain_name->string = "\\\\__NONAME__";
893         printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
894
895         status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
896         if (!NT_STATUS_IS_OK(status)) {
897                 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
898                 ret = false;
899         }
900
901         r.in.domain_name->string = "\\\\Builtin";
902         printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
903
904         status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
905         if (!NT_STATUS_IS_OK(status)) {
906                 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
907                 ret = false;
908         }
909
910
911         return ret;
912 }
913
914 static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
915                                struct policy_handle *handle)
916 {
917         NTSTATUS status;
918         struct samr_GetUserPwInfo r;
919         bool ret = true;
920
921         printf("Testing GetUserPwInfo\n");
922
923         r.in.user_handle = handle;
924
925         status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
926         if (!NT_STATUS_IS_OK(status)) {
927                 printf("GetUserPwInfo failed - %s\n", nt_errstr(status));
928                 ret = false;
929         }
930
931         return ret;
932 }
933
934 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *tctx,
935                                 struct policy_handle *domain_handle, const char *name,
936                                 uint32_t *rid)
937 {
938         NTSTATUS status;
939         struct samr_LookupNames n;
940         struct lsa_String sname[2];
941
942         init_lsa_String(&sname[0], name);
943
944         n.in.domain_handle = domain_handle;
945         n.in.num_names = 1;
946         n.in.names = sname;
947         status = dcerpc_samr_LookupNames(p, tctx, &n);
948         if (NT_STATUS_IS_OK(status)) {
949                 *rid = n.out.rids.ids[0];
950         } else {
951                 return status;
952         }
953
954         init_lsa_String(&sname[1], "xxNONAMExx");
955         n.in.num_names = 2;
956         status = dcerpc_samr_LookupNames(p, tctx, &n);
957         if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
958                 printf("LookupNames[2] failed - %s\n", nt_errstr(status));              
959                 if (NT_STATUS_IS_OK(status)) {
960                         return NT_STATUS_UNSUCCESSFUL;
961                 }
962                 return status;
963         }
964
965         n.in.num_names = 0;
966         status = dcerpc_samr_LookupNames(p, tctx, &n);
967         if (!NT_STATUS_IS_OK(status)) {
968                 printf("LookupNames[0] failed - %s\n", nt_errstr(status));              
969                 return status;
970         }
971
972         init_lsa_String(&sname[0], "xxNONAMExx");
973         n.in.num_names = 1;
974         status = dcerpc_samr_LookupNames(p, tctx, &n);
975         if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
976                 printf("LookupNames[1 bad name] failed - %s\n", nt_errstr(status));             
977                 if (NT_STATUS_IS_OK(status)) {
978                         return NT_STATUS_UNSUCCESSFUL;
979                 }
980                 return status;
981         }
982
983         init_lsa_String(&sname[0], "xxNONAMExx");
984         init_lsa_String(&sname[1], "xxNONAME2xx");
985         n.in.num_names = 2;
986         status = dcerpc_samr_LookupNames(p, tctx, &n);
987         if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
988                 printf("LookupNames[2 bad names] failed - %s\n", nt_errstr(status));            
989                 if (NT_STATUS_IS_OK(status)) {
990                         return NT_STATUS_UNSUCCESSFUL;
991                 }
992                 return status;
993         }
994
995         return NT_STATUS_OK;
996 }
997
998 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
999                                      struct policy_handle *domain_handle,
1000                                      const char *name, struct policy_handle *user_handle)
1001 {
1002         NTSTATUS status;
1003         struct samr_OpenUser r;
1004         uint32_t rid;
1005
1006         status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1007         if (!NT_STATUS_IS_OK(status)) {
1008                 return status;
1009         }
1010
1011         r.in.domain_handle = domain_handle;
1012         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1013         r.in.rid = rid;
1014         r.out.user_handle = user_handle;
1015         status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1016         if (!NT_STATUS_IS_OK(status)) {
1017                 printf("OpenUser_byname(%s -> %d) failed - %s\n", name, rid, nt_errstr(status));
1018         }
1019
1020         return status;
1021 }
1022
1023 #if 0
1024 static bool test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1025                                    struct policy_handle *handle)
1026 {
1027         NTSTATUS status;
1028         struct samr_ChangePasswordUser r;
1029         bool ret = true;
1030         struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1031         struct policy_handle user_handle;
1032         char *oldpass = "test";
1033         char *newpass = "test2";
1034         uint8_t old_nt_hash[16], new_nt_hash[16];
1035         uint8_t old_lm_hash[16], new_lm_hash[16];
1036
1037         status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
1038         if (!NT_STATUS_IS_OK(status)) {
1039                 return false;
1040         }
1041
1042         printf("Testing ChangePasswordUser for user 'testuser'\n");
1043
1044         printf("old password: %s\n", oldpass);
1045         printf("new password: %s\n", newpass);
1046
1047         E_md4hash(oldpass, old_nt_hash);
1048         E_md4hash(newpass, new_nt_hash);
1049         E_deshash(oldpass, old_lm_hash);
1050         E_deshash(newpass, new_lm_hash);
1051
1052         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1053         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1054         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1055         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1056         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1057         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1058
1059         r.in.handle = &user_handle;
1060         r.in.lm_present = 1;
1061         r.in.old_lm_crypted = &hash1;
1062         r.in.new_lm_crypted = &hash2;
1063         r.in.nt_present = 1;
1064         r.in.old_nt_crypted = &hash3;
1065         r.in.new_nt_crypted = &hash4;
1066         r.in.cross1_present = 1;
1067         r.in.nt_cross = &hash5;
1068         r.in.cross2_present = 1;
1069         r.in.lm_cross = &hash6;
1070
1071         status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1072         if (!NT_STATUS_IS_OK(status)) {
1073                 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1074                 ret = false;
1075         }
1076
1077         if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1078                 ret = false;
1079         }
1080
1081         return ret;
1082 }
1083 #endif
1084
1085 static bool test_ChangePasswordUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1086                                     const char *acct_name, 
1087                                     struct policy_handle *handle, char **password)
1088 {
1089         NTSTATUS status;
1090         struct samr_ChangePasswordUser r;
1091         bool ret = true;
1092         struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
1093         struct policy_handle user_handle;
1094         char *oldpass;
1095         uint8_t old_nt_hash[16], new_nt_hash[16];
1096         uint8_t old_lm_hash[16], new_lm_hash[16];
1097         bool changed = true;
1098
1099         char *newpass;
1100         struct samr_GetUserPwInfo pwp;
1101         int policy_min_pw_len = 0;
1102
1103         status = test_OpenUser_byname(p, mem_ctx, handle, acct_name, &user_handle);
1104         if (!NT_STATUS_IS_OK(status)) {
1105                 return false;
1106         }
1107         pwp.in.user_handle = &user_handle;
1108
1109         status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
1110         if (NT_STATUS_IS_OK(status)) {
1111                 policy_min_pw_len = pwp.out.info.min_password_length;
1112         }
1113         newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1114
1115         printf("Testing ChangePasswordUser\n");
1116
1117         if (!*password) {
1118                 printf("Failing ChangePasswordUser as old password was NULL.  Previous test failed?\n");
1119                 return false;
1120         }
1121
1122         oldpass = *password;
1123
1124         E_md4hash(oldpass, old_nt_hash);
1125         E_md4hash(newpass, new_nt_hash);
1126         E_deshash(oldpass, old_lm_hash);
1127         E_deshash(newpass, new_lm_hash);
1128
1129         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1130         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1131         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1132         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1133         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1134         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1135
1136         r.in.user_handle = &user_handle;
1137         r.in.lm_present = 1;
1138         /* Break the LM hash */
1139         hash1.hash[0]++;
1140         r.in.old_lm_crypted = &hash1;
1141         r.in.new_lm_crypted = &hash2;
1142         r.in.nt_present = 1;
1143         r.in.old_nt_crypted = &hash3;
1144         r.in.new_nt_crypted = &hash4;
1145         r.in.cross1_present = 1;
1146         r.in.nt_cross = &hash5;
1147         r.in.cross2_present = 1;
1148         r.in.lm_cross = &hash6;
1149
1150         status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1151         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1152                 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM hash, got %s\n", nt_errstr(status));
1153                 ret = false;
1154         }
1155
1156         /* Unbreak the LM hash */
1157         hash1.hash[0]--;
1158
1159         r.in.user_handle = &user_handle;
1160         r.in.lm_present = 1;
1161         r.in.old_lm_crypted = &hash1;
1162         r.in.new_lm_crypted = &hash2;
1163         /* Break the NT hash */
1164         hash3.hash[0]--;
1165         r.in.nt_present = 1;
1166         r.in.old_nt_crypted = &hash3;
1167         r.in.new_nt_crypted = &hash4;
1168         r.in.cross1_present = 1;
1169         r.in.nt_cross = &hash5;
1170         r.in.cross2_present = 1;
1171         r.in.lm_cross = &hash6;
1172
1173         status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1174         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1175                 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT hash, got %s\n", nt_errstr(status));
1176                 ret = false;
1177         }
1178
1179         /* Unbreak the NT hash */
1180         hash3.hash[0]--;
1181
1182         r.in.user_handle = &user_handle;
1183         r.in.lm_present = 1;
1184         r.in.old_lm_crypted = &hash1;
1185         r.in.new_lm_crypted = &hash2;
1186         r.in.nt_present = 1;
1187         r.in.old_nt_crypted = &hash3;
1188         r.in.new_nt_crypted = &hash4;
1189         r.in.cross1_present = 1;
1190         r.in.nt_cross = &hash5;
1191         r.in.cross2_present = 1;
1192         /* Break the LM cross */
1193         hash6.hash[0]++;
1194         r.in.lm_cross = &hash6;
1195
1196         status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1197         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1198                 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the LM cross-hash, got %s\n", nt_errstr(status));
1199                 ret = false;
1200         }
1201
1202         /* Unbreak the LM cross */
1203         hash6.hash[0]--;
1204
1205         r.in.user_handle = &user_handle;
1206         r.in.lm_present = 1;
1207         r.in.old_lm_crypted = &hash1;
1208         r.in.new_lm_crypted = &hash2;
1209         r.in.nt_present = 1;
1210         r.in.old_nt_crypted = &hash3;
1211         r.in.new_nt_crypted = &hash4;
1212         r.in.cross1_present = 1;
1213         /* Break the NT cross */
1214         hash5.hash[0]++;
1215         r.in.nt_cross = &hash5;
1216         r.in.cross2_present = 1;
1217         r.in.lm_cross = &hash6;
1218
1219         status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1220         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1221                 printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we broke the NT cross-hash, got %s\n", nt_errstr(status));
1222                 ret = false;
1223         }
1224
1225         /* Unbreak the NT cross */
1226         hash5.hash[0]--;
1227
1228
1229         /* Reset the hashes to not broken values */
1230         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1231         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1232         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1233         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1234         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1235         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1236
1237         r.in.user_handle = &user_handle;
1238         r.in.lm_present = 1;
1239         r.in.old_lm_crypted = &hash1;
1240         r.in.new_lm_crypted = &hash2;
1241         r.in.nt_present = 1;
1242         r.in.old_nt_crypted = &hash3;
1243         r.in.new_nt_crypted = &hash4;
1244         r.in.cross1_present = 1;
1245         r.in.nt_cross = &hash5;
1246         r.in.cross2_present = 0;
1247         r.in.lm_cross = NULL;
1248
1249         status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1250         if (NT_STATUS_IS_OK(status)) {
1251                 changed = true;
1252                 *password = newpass;
1253         } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1254                 printf("ChangePasswordUser failed: expected NT_STATUS_OK, or at least NT_STATUS_PASSWORD_RESTRICTION, got %s\n", nt_errstr(status));
1255                 ret = false;
1256         }
1257
1258         oldpass = newpass;
1259         newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1260
1261         E_md4hash(oldpass, old_nt_hash);
1262         E_md4hash(newpass, new_nt_hash);
1263         E_deshash(oldpass, old_lm_hash);
1264         E_deshash(newpass, new_lm_hash);
1265
1266
1267         /* Reset the hashes to not broken values */
1268         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1269         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1270         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1271         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1272         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1273         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1274
1275         r.in.user_handle = &user_handle;
1276         r.in.lm_present = 1;
1277         r.in.old_lm_crypted = &hash1;
1278         r.in.new_lm_crypted = &hash2;
1279         r.in.nt_present = 1;
1280         r.in.old_nt_crypted = &hash3;
1281         r.in.new_nt_crypted = &hash4;
1282         r.in.cross1_present = 0;
1283         r.in.nt_cross = NULL;
1284         r.in.cross2_present = 1;
1285         r.in.lm_cross = &hash6;
1286
1287         status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1288         if (NT_STATUS_IS_OK(status)) {
1289                 changed = true;
1290                 *password = newpass;
1291         } else if (!NT_STATUS_EQUAL(NT_STATUS_PASSWORD_RESTRICTION, status)) {
1292                 printf("ChangePasswordUser failed: expected NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED, got %s\n", nt_errstr(status));
1293                 ret = false;
1294         }
1295
1296         oldpass = newpass;
1297         newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1298
1299         E_md4hash(oldpass, old_nt_hash);
1300         E_md4hash(newpass, new_nt_hash);
1301         E_deshash(oldpass, old_lm_hash);
1302         E_deshash(newpass, new_lm_hash);
1303
1304
1305         /* Reset the hashes to not broken values */
1306         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
1307         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
1308         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
1309         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
1310         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
1311         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
1312
1313         r.in.user_handle = &user_handle;
1314         r.in.lm_present = 1;
1315         r.in.old_lm_crypted = &hash1;
1316         r.in.new_lm_crypted = &hash2;
1317         r.in.nt_present = 1;
1318         r.in.old_nt_crypted = &hash3;
1319         r.in.new_nt_crypted = &hash4;
1320         r.in.cross1_present = 1;
1321         r.in.nt_cross = &hash5;
1322         r.in.cross2_present = 1;
1323         r.in.lm_cross = &hash6;
1324
1325         status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1326         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1327                 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1328         } else  if (!NT_STATUS_IS_OK(status)) {
1329                 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
1330                 ret = false;
1331         } else {
1332                 changed = true;
1333                 *password = newpass;
1334         }
1335
1336         r.in.user_handle = &user_handle;
1337         r.in.lm_present = 1;
1338         r.in.old_lm_crypted = &hash1;
1339         r.in.new_lm_crypted = &hash2;
1340         r.in.nt_present = 1;
1341         r.in.old_nt_crypted = &hash3;
1342         r.in.new_nt_crypted = &hash4;
1343         r.in.cross1_present = 1;
1344         r.in.nt_cross = &hash5;
1345         r.in.cross2_present = 1;
1346         r.in.lm_cross = &hash6;
1347
1348         if (changed) {
1349                 status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
1350                 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1351                         printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1352                 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1353                         printf("ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD because we already changed the password, got %s\n", nt_errstr(status));
1354                         ret = false;
1355                 }
1356         }
1357
1358         
1359         if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
1360                 ret = false;
1361         }
1362
1363         return ret;
1364 }
1365
1366
1367 static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1368                                         const char *acct_name,
1369                                         struct policy_handle *handle, char **password)
1370 {
1371         NTSTATUS status;
1372         struct samr_OemChangePasswordUser2 r;
1373         bool ret = true;
1374         struct samr_Password lm_verifier;
1375         struct samr_CryptPassword lm_pass;
1376         struct lsa_AsciiString server, account, account_bad;
1377         char *oldpass;
1378         char *newpass;
1379         uint8_t old_lm_hash[16], new_lm_hash[16];
1380
1381         struct samr_GetDomPwInfo dom_pw_info;
1382         int policy_min_pw_len = 0;
1383
1384         struct lsa_String domain_name;
1385
1386         domain_name.string = "";
1387         dom_pw_info.in.domain_name = &domain_name;
1388
1389         printf("Testing OemChangePasswordUser2\n");
1390
1391         if (!*password) {
1392                 printf("Failing OemChangePasswordUser2 as old password was NULL.  Previous test failed?\n");
1393                 return false;
1394         }
1395
1396         oldpass = *password;
1397
1398         status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1399         if (NT_STATUS_IS_OK(status)) {
1400                 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1401         }
1402
1403         newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1404
1405         server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1406         account.string = acct_name;
1407
1408         E_deshash(oldpass, old_lm_hash);
1409         E_deshash(newpass, new_lm_hash);
1410
1411         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1412         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1413         E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1414
1415         r.in.server = &server;
1416         r.in.account = &account;
1417         r.in.password = &lm_pass;
1418         r.in.hash = &lm_verifier;
1419
1420         /* Break the verification */
1421         lm_verifier.hash[0]++;
1422
1423         status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1424
1425         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1426             && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1427                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1428                         nt_errstr(status));
1429                 ret = false;
1430         }
1431
1432         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1433         /* Break the old password */
1434         old_lm_hash[0]++;
1435         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1436         /* unbreak it for the next operation */
1437         old_lm_hash[0]--;
1438         E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1439
1440         r.in.server = &server;
1441         r.in.account = &account;
1442         r.in.password = &lm_pass;
1443         r.in.hash = &lm_verifier;
1444
1445         status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1446
1447         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1448             && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1449                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1450                         nt_errstr(status));
1451                 ret = false;
1452         }
1453
1454         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1455         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1456
1457         r.in.server = &server;
1458         r.in.account = &account;
1459         r.in.password = &lm_pass;
1460         r.in.hash = NULL;
1461
1462         status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1463
1464         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1465             && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1466                 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n",
1467                         nt_errstr(status));
1468                 ret = false;
1469         }
1470
1471         /* This shouldn't be a valid name */
1472         account_bad.string = TEST_ACCOUNT_NAME "XX";
1473         r.in.account = &account_bad;
1474
1475         status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1476
1477         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1478                 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n",
1479                         nt_errstr(status));
1480                 ret = false;
1481         }
1482
1483         /* This shouldn't be a valid name */
1484         account_bad.string = TEST_ACCOUNT_NAME "XX";
1485         r.in.account = &account_bad;
1486         r.in.password = &lm_pass;
1487         r.in.hash = &lm_verifier;
1488
1489         status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1490
1491         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1492                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1493                         nt_errstr(status));
1494                 ret = false;
1495         }
1496
1497         /* This shouldn't be a valid name */
1498         account_bad.string = TEST_ACCOUNT_NAME "XX";
1499         r.in.account = &account_bad;
1500         r.in.password = NULL;
1501         r.in.hash = &lm_verifier;
1502
1503         status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1504
1505         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1506                 printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n",
1507                         nt_errstr(status));
1508                 ret = false;
1509         }
1510
1511         E_deshash(oldpass, old_lm_hash);
1512         E_deshash(newpass, new_lm_hash);
1513
1514         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1515         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1516         E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1517
1518         r.in.server = &server;
1519         r.in.account = &account;
1520         r.in.password = &lm_pass;
1521         r.in.hash = &lm_verifier;
1522
1523         status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1524         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1525                 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1526         } else if (!NT_STATUS_IS_OK(status)) {
1527                 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1528                 ret = false;
1529         } else {
1530                 *password = newpass;
1531         }
1532
1533         return ret;
1534 }
1535
1536
1537 static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1538                                      const char *acct_name,
1539                                      char **password,
1540                                      char *newpass, bool allow_password_restriction)
1541 {
1542         NTSTATUS status;
1543         struct samr_ChangePasswordUser2 r;
1544         bool ret = true;
1545         struct lsa_String server, account;
1546         struct samr_CryptPassword nt_pass, lm_pass;
1547         struct samr_Password nt_verifier, lm_verifier;
1548         char *oldpass;
1549         uint8_t old_nt_hash[16], new_nt_hash[16];
1550         uint8_t old_lm_hash[16], new_lm_hash[16];
1551
1552         struct samr_GetDomPwInfo dom_pw_info;
1553
1554         struct lsa_String domain_name;
1555
1556         domain_name.string = "";
1557         dom_pw_info.in.domain_name = &domain_name;
1558
1559         printf("Testing ChangePasswordUser2 on %s\n", acct_name);
1560
1561         if (!*password) {
1562                 printf("Failing ChangePasswordUser3 as old password was NULL.  Previous test failed?\n");
1563                 return false;
1564         }
1565         oldpass = *password;
1566
1567         if (!newpass) {
1568                 int policy_min_pw_len = 0;
1569                 status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1570                 if (NT_STATUS_IS_OK(status)) {
1571                         policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1572                 }
1573
1574                 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1575         } 
1576
1577         server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1578         init_lsa_String(&account, acct_name);
1579
1580         E_md4hash(oldpass, old_nt_hash);
1581         E_md4hash(newpass, new_nt_hash);
1582
1583         E_deshash(oldpass, old_lm_hash);
1584         E_deshash(newpass, new_lm_hash);
1585
1586         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1587         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1588         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1589
1590         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1591         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1592         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1593
1594         r.in.server = &server;
1595         r.in.account = &account;
1596         r.in.nt_password = &nt_pass;
1597         r.in.nt_verifier = &nt_verifier;
1598         r.in.lm_change = 1;
1599         r.in.lm_password = &lm_pass;
1600         r.in.lm_verifier = &lm_verifier;
1601
1602         status = dcerpc_samr_ChangePasswordUser2(p, mem_ctx, &r);
1603         if (allow_password_restriction && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1604                 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1605         } else if (!NT_STATUS_IS_OK(status)) {
1606                 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1607                 ret = false;
1608         } else {
1609                 *password = newpass;
1610         }
1611
1612         return ret;
1613 }
1614
1615
1616 bool test_ChangePasswordUser3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1617                               const char *account_string,
1618                               int policy_min_pw_len,
1619                               char **password,
1620                               const char *newpass,
1621                               NTTIME last_password_change,
1622                               bool handle_reject_reason)
1623 {
1624         NTSTATUS status;
1625         struct samr_ChangePasswordUser3 r;
1626         bool ret = true;
1627         struct lsa_String server, account, account_bad;
1628         struct samr_CryptPassword nt_pass, lm_pass;
1629         struct samr_Password nt_verifier, lm_verifier;
1630         char *oldpass;
1631         uint8_t old_nt_hash[16], new_nt_hash[16];
1632         uint8_t old_lm_hash[16], new_lm_hash[16];
1633         NTTIME t;
1634
1635         printf("Testing ChangePasswordUser3\n");
1636
1637         if (newpass == NULL) {
1638                 do {
1639                         if (policy_min_pw_len == 0) {
1640                                 newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1641                         } else {
1642                                 newpass = samr_rand_pass_fixed_len(mem_ctx, policy_min_pw_len);
1643                         }
1644                 } while (check_password_quality(newpass) == false);
1645         } else {
1646                 printf("Using password '%s'\n", newpass);
1647         }
1648
1649         if (!*password) {
1650                 printf("Failing ChangePasswordUser3 as old password was NULL.  Previous test failed?\n");
1651                 return false;
1652         }
1653
1654         oldpass = *password;
1655         server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1656         init_lsa_String(&account, account_string);
1657
1658         E_md4hash(oldpass, old_nt_hash);
1659         E_md4hash(newpass, new_nt_hash);
1660
1661         E_deshash(oldpass, old_lm_hash);
1662         E_deshash(newpass, new_lm_hash);
1663
1664         encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1665         arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1666         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1667
1668         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1669         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1670         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1671         
1672         /* Break the verification */
1673         nt_verifier.hash[0]++;
1674
1675         r.in.server = &server;
1676         r.in.account = &account;
1677         r.in.nt_password = &nt_pass;
1678         r.in.nt_verifier = &nt_verifier;
1679         r.in.lm_change = 1;
1680         r.in.lm_password = &lm_pass;
1681         r.in.lm_verifier = &lm_verifier;
1682         r.in.password3 = NULL;
1683
1684         status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1685         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1686             (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1687                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1688                         nt_errstr(status));
1689                 ret = false;
1690         }
1691         
1692         encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1693         arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1694         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1695
1696         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1697         /* Break the NT hash */
1698         old_nt_hash[0]++;
1699         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1700         /* Unbreak it again */
1701         old_nt_hash[0]--;
1702         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1703         
1704         r.in.server = &server;
1705         r.in.account = &account;
1706         r.in.nt_password = &nt_pass;
1707         r.in.nt_verifier = &nt_verifier;
1708         r.in.lm_change = 1;
1709         r.in.lm_password = &lm_pass;
1710         r.in.lm_verifier = &lm_verifier;
1711         r.in.password3 = NULL;
1712
1713         status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1714         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1715             (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1716                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
1717                         nt_errstr(status));
1718                 ret = false;
1719         }
1720         
1721         /* This shouldn't be a valid name */
1722         init_lsa_String(&account_bad, talloc_asprintf(mem_ctx, "%sXX", account_string));
1723
1724         r.in.account = &account_bad;
1725         status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1726         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1727                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
1728                         nt_errstr(status));
1729                 ret = false;
1730         }
1731
1732         E_md4hash(oldpass, old_nt_hash);
1733         E_md4hash(newpass, new_nt_hash);
1734
1735         E_deshash(oldpass, old_lm_hash);
1736         E_deshash(newpass, new_lm_hash);
1737
1738         encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1739         arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1740         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1741
1742         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1743         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1744         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1745
1746         r.in.server = &server;
1747         r.in.account = &account;
1748         r.in.nt_password = &nt_pass;
1749         r.in.nt_verifier = &nt_verifier;
1750         r.in.lm_change = 1;
1751         r.in.lm_password = &lm_pass;
1752         r.in.lm_verifier = &lm_verifier;
1753         r.in.password3 = NULL;
1754
1755         unix_to_nt_time(&t, time(NULL));
1756
1757         status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1758
1759         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1760             && r.out.dominfo
1761             && r.out.reject
1762             && handle_reject_reason
1763             && (!null_nttime(last_password_change) || !r.out.dominfo->min_password_age)) {
1764                 if (r.out.dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
1765
1766                         if (r.out.reject && (r.out.reject->reason != SAMR_REJECT_OTHER)) {
1767                                 printf("expected SAMR_REJECT_OTHER (%d), got %d\n", 
1768                                         SAMR_REJECT_OTHER, r.out.reject->reason);
1769                                 return false;
1770                         }
1771                 }
1772
1773                 /* We tested the order of precendence which is as follows:
1774                 
1775                 * pwd min_age 
1776                 * pwd length
1777                 * pwd complexity
1778                 * pwd history
1779
1780                 Guenther */
1781
1782                 if ((r.out.dominfo->min_password_age > 0) && !null_nttime(last_password_change) && 
1783                            (last_password_change + r.out.dominfo->min_password_age > t)) {
1784
1785                         if (r.out.reject->reason != SAMR_REJECT_OTHER) {
1786                                 printf("expected SAMR_REJECT_OTHER (%d), got %d\n", 
1787                                         SAMR_REJECT_OTHER, r.out.reject->reason);
1788                                 return false;
1789                         }
1790
1791                 } else if ((r.out.dominfo->min_password_length > 0) && 
1792                            (strlen(newpass) < r.out.dominfo->min_password_length)) {
1793
1794                         if (r.out.reject->reason != SAMR_REJECT_TOO_SHORT) {
1795                                 printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n", 
1796                                         SAMR_REJECT_TOO_SHORT, r.out.reject->reason);
1797                                 return false;
1798                         }
1799
1800                 } else if ((r.out.dominfo->password_history_length > 0) && 
1801                             strequal(oldpass, newpass)) {
1802
1803                         if (r.out.reject->reason != SAMR_REJECT_IN_HISTORY) {
1804                                 printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n", 
1805                                         SAMR_REJECT_IN_HISTORY, r.out.reject->reason);
1806                                 return false;
1807                         }
1808                 } else if (r.out.dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
1809
1810                         if (r.out.reject->reason != SAMR_REJECT_COMPLEXITY) {
1811                                 printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n", 
1812                                         SAMR_REJECT_COMPLEXITY, r.out.reject->reason);
1813                                 return false;
1814                         }
1815
1816                 }
1817
1818                 if (r.out.reject->reason == SAMR_REJECT_TOO_SHORT) {
1819                         /* retry with adjusted size */
1820                         return test_ChangePasswordUser3(p, mem_ctx, account_string, 
1821                                                         r.out.dominfo->min_password_length, 
1822                                                         password, NULL, 0, false); 
1823
1824                 }
1825
1826         } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1827                 if (r.out.reject && r.out.reject->reason != SAMR_REJECT_OTHER) {
1828                         printf("expected SAMR_REJECT_OTHER (%d), got %d\n", 
1829                                SAMR_REJECT_OTHER, r.out.reject->reason);
1830                         return false;
1831                 }
1832                 /* Perhaps the server has a 'min password age' set? */
1833
1834         } else if (!NT_STATUS_IS_OK(status)) {
1835                 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1836                 ret = false;
1837         } else {
1838                 *password = talloc_strdup(mem_ctx, newpass);
1839         }
1840
1841         return ret;
1842 }
1843
1844
1845 static bool test_GetMembersInAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1846                                   struct policy_handle *alias_handle)
1847 {
1848         struct samr_GetMembersInAlias r;
1849         struct lsa_SidArray sids;
1850         NTSTATUS status;
1851         bool     ret = true;
1852
1853         printf("Testing GetMembersInAlias\n");
1854
1855         r.in.alias_handle = alias_handle;
1856         r.out.sids = &sids;
1857
1858         status = dcerpc_samr_GetMembersInAlias(p, mem_ctx, &r);
1859         if (!NT_STATUS_IS_OK(status)) {
1860                 printf("GetMembersInAlias failed - %s\n",
1861                        nt_errstr(status));
1862                 ret = false;
1863         }
1864
1865         return ret;
1866 }
1867
1868 static bool test_AddMemberToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1869                                   struct policy_handle *alias_handle,
1870                                   const struct dom_sid *domain_sid)
1871 {
1872         struct samr_AddAliasMember r;
1873         struct samr_DeleteAliasMember d;
1874         NTSTATUS status;
1875         bool ret = true;
1876         struct dom_sid *sid;
1877
1878         sid = dom_sid_add_rid(mem_ctx, domain_sid, 512);
1879
1880         printf("testing AddAliasMember\n");
1881         r.in.alias_handle = alias_handle;
1882         r.in.sid = sid;
1883
1884         status = dcerpc_samr_AddAliasMember(p, mem_ctx, &r);
1885         if (!NT_STATUS_IS_OK(status)) {
1886                 printf("AddAliasMember failed - %s\n", nt_errstr(status));
1887                 ret = false;
1888         }
1889
1890         d.in.alias_handle = alias_handle;
1891         d.in.sid = sid;
1892
1893         status = dcerpc_samr_DeleteAliasMember(p, mem_ctx, &d);
1894         if (!NT_STATUS_IS_OK(status)) {
1895                 printf("DelAliasMember failed - %s\n", nt_errstr(status));
1896                 ret = false;
1897         }
1898
1899         return ret;
1900 }
1901
1902 static bool test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1903                                            struct policy_handle *alias_handle)
1904 {
1905         struct samr_AddMultipleMembersToAlias a;
1906         struct samr_RemoveMultipleMembersFromAlias r;
1907         NTSTATUS status;
1908         bool ret = true;
1909         struct lsa_SidArray sids;
1910
1911         printf("testing AddMultipleMembersToAlias\n");
1912         a.in.alias_handle = alias_handle;
1913         a.in.sids = &sids;
1914
1915         sids.num_sids = 3;
1916         sids.sids = talloc_array(mem_ctx, struct lsa_SidPtr, 3);
1917
1918         sids.sids[0].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-1");
1919         sids.sids[1].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-2");
1920         sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-3");
1921
1922         status = dcerpc_samr_AddMultipleMembersToAlias(p, mem_ctx, &a);
1923         if (!NT_STATUS_IS_OK(status)) {
1924                 printf("AddMultipleMembersToAlias failed - %s\n", nt_errstr(status));
1925                 ret = false;
1926         }
1927
1928
1929         printf("testing RemoveMultipleMembersFromAlias\n");
1930         r.in.alias_handle = alias_handle;
1931         r.in.sids = &sids;
1932
1933         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1934         if (!NT_STATUS_IS_OK(status)) {
1935                 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1936                 ret = false;
1937         }
1938
1939         /* strange! removing twice doesn't give any error */
1940         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1941         if (!NT_STATUS_IS_OK(status)) {
1942                 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1943                 ret = false;
1944         }
1945
1946         /* but removing an alias that isn't there does */
1947         sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-4");
1948
1949         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1950         if (!NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) {
1951                 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1952                 ret = false;
1953         }
1954
1955         return ret;
1956 }
1957
1958 static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1959                                             struct policy_handle *user_handle)
1960 {
1961         struct samr_TestPrivateFunctionsUser r;
1962         NTSTATUS status;
1963         bool ret = true;
1964
1965         printf("Testing TestPrivateFunctionsUser\n");
1966
1967         r.in.user_handle = user_handle;
1968
1969         status = dcerpc_samr_TestPrivateFunctionsUser(p, mem_ctx, &r);
1970         if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
1971                 printf("TestPrivateFunctionsUser failed - %s\n", nt_errstr(status));
1972                 ret = false;
1973         }
1974
1975         return ret;
1976 }
1977
1978
1979 static bool test_user_ops(struct dcerpc_pipe *p, 
1980                           struct torture_context *tctx,
1981                           struct policy_handle *user_handle, 
1982                           struct policy_handle *domain_handle, 
1983                           uint32_t base_acct_flags, 
1984                           const char *base_acct_name, enum torture_samr_choice which_ops)
1985 {
1986         char *password = NULL;
1987         struct samr_QueryUserInfo q;
1988         NTSTATUS status;
1989
1990         bool ret = true;
1991         int i;
1992         uint32_t rid;
1993         const uint32_t password_fields[] = {
1994                 SAMR_FIELD_PASSWORD,
1995                 SAMR_FIELD_PASSWORD2,
1996                 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
1997                 0
1998         };
1999         
2000         status = test_LookupName(p, tctx, domain_handle, base_acct_name, &rid);
2001         if (!NT_STATUS_IS_OK(status)) {
2002                 ret = false;
2003         }
2004
2005         switch (which_ops) {
2006         case TORTURE_SAMR_USER_ATTRIBUTES:
2007                 if (!test_QuerySecurity(p, tctx, user_handle)) {
2008                         ret = false;
2009                 }
2010
2011                 if (!test_QueryUserInfo(p, tctx, user_handle)) {
2012                         ret = false;
2013                 }
2014
2015                 if (!test_QueryUserInfo2(p, tctx, user_handle)) {
2016                         ret = false;
2017                 }
2018
2019                 if (!test_SetUserInfo(p, tctx, user_handle, base_acct_flags,
2020                                       base_acct_name)) {
2021                         ret = false;
2022                 }       
2023
2024                 if (!test_GetUserPwInfo(p, tctx, user_handle)) {
2025                         ret = false;
2026                 }
2027
2028                 if (!test_TestPrivateFunctionsUser(p, tctx, user_handle)) {
2029                         ret = false;
2030                 }
2031
2032                 if (!test_SetUserPass(p, tctx, user_handle, &password)) {
2033                         ret = false;
2034                 }
2035                 break;
2036         case TORTURE_SAMR_PASSWORDS:
2037                 if (base_acct_flags & (ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST)) {
2038                         char simple_pass[9];
2039                         char *v = generate_random_str(tctx, 1);
2040                         
2041                         ZERO_STRUCT(simple_pass);
2042                         memset(simple_pass, *v, sizeof(simple_pass) - 1);
2043
2044                         printf("Testing machine account password policy rules\n");
2045
2046                         /* Workstation trust accounts don't seem to need to honour password quality policy */
2047                         if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
2048                                 ret = false;
2049                         }
2050
2051                         if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, simple_pass, false)) {
2052                                 ret = false;
2053                         }
2054
2055                         /* reset again, to allow another 'user' password change */
2056                         if (!test_SetUserPassEx(p, tctx, user_handle, true, &password)) {
2057                                 ret = false;
2058                         }
2059
2060                         /* Try a 'short' password */
2061                         if (!test_ChangePasswordUser2(p, tctx, base_acct_name, &password, samr_rand_pass(tctx, 4), false)) {
2062                                 ret = false;
2063                         }
2064                         
2065                 }
2066                 
2067                 for (i = 0; password_fields[i]; i++) {
2068                         if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
2069                                 ret = false;
2070                         }       
2071                 
2072                         /* check it was set right */
2073                         if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
2074                                 ret = false;
2075                         }
2076                 }               
2077
2078                 for (i = 0; password_fields[i]; i++) {
2079                         if (!test_SetUserPass_25(p, tctx, user_handle, password_fields[i], &password)) {
2080                                 ret = false;
2081                         }       
2082                 
2083                         /* check it was set right */
2084                         if (!test_ChangePasswordUser3(p, tctx, base_acct_name, 0, &password, NULL, 0, false)) {
2085                                 ret = false;
2086                         }
2087                 }               
2088
2089                 if (!test_SetUserPassEx(p, tctx, user_handle, false, &password)) {
2090                         ret = false;
2091                 }       
2092
2093                 if (!test_ChangePassword(p, tctx, base_acct_name, domain_handle, &password)) {
2094                         ret = false;
2095                 }       
2096
2097                 q.in.user_handle = user_handle;
2098                 q.in.level = 5;
2099                 
2100                 status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
2101                 if (!NT_STATUS_IS_OK(status)) {
2102                         printf("QueryUserInfo level %u failed - %s\n", 
2103                                q.in.level, nt_errstr(status));
2104                         ret = false;
2105                 } else {
2106                         uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
2107                         if ((q.out.info->info5.acct_flags) != expected_flags) {
2108                                 printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2109                                        q.out.info->info5.acct_flags, 
2110                                        expected_flags);
2111                                 ret = false;
2112                         }
2113                         if (q.out.info->info5.rid != rid) {
2114                                 printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
2115                                        q.out.info->info5.rid, rid);
2116
2117                         }
2118                 }
2119
2120                 break;
2121         case TORTURE_SAMR_OTHER:
2122                 /* We just need the account to exist */
2123                 break;
2124         }
2125         return ret;
2126 }
2127
2128 static bool test_alias_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
2129                            struct policy_handle *alias_handle,
2130                            const struct dom_sid *domain_sid)
2131 {
2132         bool ret = true;
2133
2134         if (!test_QuerySecurity(p, tctx, alias_handle)) {
2135                 ret = false;
2136         }
2137
2138         if (!test_QueryAliasInfo(p, tctx, alias_handle)) {
2139                 ret = false;
2140         }
2141
2142         if (!test_SetAliasInfo(p, tctx, alias_handle)) {
2143                 ret = false;
2144         }
2145
2146         if (!test_AddMemberToAlias(p, tctx, alias_handle, domain_sid)) {
2147                 ret = false;
2148         }
2149
2150         if (torture_setting_bool(tctx, "samba4", false)) {
2151                 printf("skipping MultipleMembers Alias tests against Samba4\n");
2152                 return ret;
2153         }
2154
2155         if (!test_AddMultipleMembersToAlias(p, tctx, alias_handle)) {
2156                 ret = false;
2157         }
2158
2159         return ret;
2160 }
2161
2162
2163 static bool test_DeleteUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2164                                      struct policy_handle *user_handle)
2165 {
2166         struct samr_DeleteUser d;
2167         NTSTATUS status;
2168         bool ret = true;
2169         printf("Testing DeleteUser\n");
2170
2171         d.in.user_handle = user_handle;
2172         d.out.user_handle = user_handle;
2173
2174         status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
2175         if (!NT_STATUS_IS_OK(status)) {
2176                 printf("DeleteUser failed - %s\n", nt_errstr(status));
2177                 ret = false;
2178         }
2179
2180         return ret;
2181 }
2182
2183 bool test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2184                             struct policy_handle *handle, const char *name)
2185 {
2186         NTSTATUS status;
2187         struct samr_DeleteUser d;
2188         struct policy_handle user_handle;
2189         uint32_t rid;
2190
2191         status = test_LookupName(p, mem_ctx, handle, name, &rid);
2192         if (!NT_STATUS_IS_OK(status)) {
2193                 goto failed;
2194         }
2195
2196         status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
2197         if (!NT_STATUS_IS_OK(status)) {
2198                 goto failed;
2199         }
2200
2201         d.in.user_handle = &user_handle;
2202         d.out.user_handle = &user_handle;
2203         status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
2204         if (!NT_STATUS_IS_OK(status)) {
2205                 goto failed;
2206         }
2207
2208         return true;
2209
2210 failed:
2211         printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
2212         return false;
2213 }
2214
2215
2216 static bool test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2217                                     struct policy_handle *handle, const char *name)
2218 {
2219         NTSTATUS status;
2220         struct samr_OpenGroup r;
2221         struct samr_DeleteDomainGroup d;
2222         struct policy_handle group_handle;
2223         uint32_t rid;
2224
2225         status = test_LookupName(p, mem_ctx, handle, name, &rid);
2226         if (!NT_STATUS_IS_OK(status)) {
2227                 goto failed;
2228         }
2229
2230         r.in.domain_handle = handle;
2231         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2232         r.in.rid = rid;
2233         r.out.group_handle = &group_handle;
2234         status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2235         if (!NT_STATUS_IS_OK(status)) {
2236                 goto failed;
2237         }
2238
2239         d.in.group_handle = &group_handle;
2240         d.out.group_handle = &group_handle;
2241         status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2242         if (!NT_STATUS_IS_OK(status)) {
2243                 goto failed;
2244         }
2245
2246         return true;
2247
2248 failed:
2249         printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
2250         return false;
2251 }
2252
2253
2254 static bool test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2255                                    struct policy_handle *domain_handle, const char *name)
2256 {
2257         NTSTATUS status;
2258         struct samr_OpenAlias r;
2259         struct samr_DeleteDomAlias d;
2260         struct policy_handle alias_handle;
2261         uint32_t rid;
2262
2263         printf("testing DeleteAlias_byname\n");
2264
2265         status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
2266         if (!NT_STATUS_IS_OK(status)) {
2267                 goto failed;
2268         }
2269
2270         r.in.domain_handle = domain_handle;
2271         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2272         r.in.rid = rid;
2273         r.out.alias_handle = &alias_handle;
2274         status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2275         if (!NT_STATUS_IS_OK(status)) {
2276                 goto failed;
2277         }
2278
2279         d.in.alias_handle = &alias_handle;
2280         d.out.alias_handle = &alias_handle;
2281         status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2282         if (!NT_STATUS_IS_OK(status)) {
2283                 goto failed;
2284         }
2285
2286         return true;
2287
2288 failed:
2289         printf("DeleteAlias_byname(%s) failed - %s\n", name, nt_errstr(status));
2290         return false;
2291 }
2292
2293 static bool test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2294                                      struct policy_handle *alias_handle)
2295 {
2296         struct samr_DeleteDomAlias d;
2297         NTSTATUS status;
2298         bool ret = true;
2299         printf("Testing DeleteAlias\n");
2300
2301         d.in.alias_handle = alias_handle;
2302         d.out.alias_handle = alias_handle;
2303
2304         status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
2305         if (!NT_STATUS_IS_OK(status)) {
2306                 printf("DeleteAlias failed - %s\n", nt_errstr(status));
2307                 ret = false;
2308         }
2309
2310         return ret;
2311 }
2312
2313 static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx,
2314                             struct policy_handle *domain_handle, 
2315                              struct policy_handle *alias_handle, 
2316                              const struct dom_sid *domain_sid)
2317 {
2318         NTSTATUS status;
2319         struct samr_CreateDomAlias r;
2320         struct lsa_String name;
2321         uint32_t rid;
2322         bool ret = true;
2323
2324         init_lsa_String(&name, TEST_ALIASNAME);
2325         r.in.domain_handle = domain_handle;
2326         r.in.alias_name = &name;
2327         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2328         r.out.alias_handle = alias_handle;
2329         r.out.rid = &rid;
2330
2331         printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
2332
2333         status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
2334
2335         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2336                 printf("Server refused create of '%s'\n", r.in.alias_name->string);
2337                 return true;
2338         }
2339
2340         if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
2341                 if (!test_DeleteAlias_byname(p, tctx, domain_handle, r.in.alias_name->string)) {
2342                         return false;
2343                 }
2344                 status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
2345         }
2346
2347         if (!NT_STATUS_IS_OK(status)) {
2348                 printf("CreateAlias failed - %s\n", nt_errstr(status));
2349                 return false;
2350         }
2351
2352         if (!test_alias_ops(p, tctx, alias_handle, domain_sid)) {
2353                 ret = false;
2354         }
2355
2356         return ret;
2357 }
2358
2359 static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2360                                 const char *acct_name,
2361                                 struct policy_handle *domain_handle, char **password)
2362 {
2363         bool ret = true;
2364
2365         if (!*password) {
2366                 return false;
2367         }
2368
2369         if (!test_ChangePasswordUser(p, mem_ctx, acct_name, domain_handle, password)) {
2370                 ret = false;
2371         }
2372
2373         if (!test_ChangePasswordUser2(p, mem_ctx, acct_name, password, 0, true)) {
2374                 ret = false;
2375         }
2376
2377         if (!test_OemChangePasswordUser2(p, mem_ctx, acct_name, domain_handle, password)) {
2378                 ret = false;
2379         }
2380
2381         /* test what happens when setting the old password again */
2382         if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, *password, 0, true)) {
2383                 ret = false;
2384         }
2385
2386         {
2387                 char simple_pass[9];
2388                 char *v = generate_random_str(mem_ctx, 1);
2389
2390                 ZERO_STRUCT(simple_pass);
2391                 memset(simple_pass, *v, sizeof(simple_pass) - 1);
2392
2393                 /* test what happens when picking a simple password */
2394                 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, simple_pass, 0, true)) {
2395                         ret = false;
2396                 }
2397         }
2398
2399         /* set samr_SetDomainInfo level 1 with min_length 5 */
2400         {
2401                 struct samr_QueryDomainInfo r;
2402                 struct samr_SetDomainInfo s;
2403                 uint16_t len_old, len;
2404                 uint32_t pwd_prop_old;
2405                 int64_t min_pwd_age_old;
2406                 NTSTATUS status;
2407
2408                 len = 5;
2409
2410                 r.in.domain_handle = domain_handle;
2411                 r.in.level = 1;
2412
2413                 printf("testing samr_QueryDomainInfo level 1\n");
2414                 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2415                 if (!NT_STATUS_IS_OK(status)) {
2416                         return false;
2417                 }
2418
2419                 s.in.domain_handle = domain_handle;
2420                 s.in.level = 1;
2421                 s.in.info = r.out.info;
2422
2423                 /* remember the old min length, so we can reset it */
2424                 len_old = s.in.info->info1.min_password_length;
2425                 s.in.info->info1.min_password_length = len;
2426                 pwd_prop_old = s.in.info->info1.password_properties;
2427                 /* turn off password complexity checks for this test */
2428                 s.in.info->info1.password_properties &= ~DOMAIN_PASSWORD_COMPLEX;
2429
2430                 min_pwd_age_old = s.in.info->info1.min_password_age;
2431                 s.in.info->info1.min_password_age = 0;
2432
2433                 printf("testing samr_SetDomainInfo level 1\n");
2434                 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2435                 if (!NT_STATUS_IS_OK(status)) {
2436                         return false;
2437                 }
2438
2439                 printf("calling test_ChangePasswordUser3 with too short password\n");
2440
2441                 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, len - 1, password, NULL, 0, true)) {
2442                         ret = false;
2443                 }
2444
2445                 s.in.info->info1.min_password_length = len_old;
2446                 s.in.info->info1.password_properties = pwd_prop_old;
2447                 s.in.info->info1.min_password_age = min_pwd_age_old;
2448                 
2449                 printf("testing samr_SetDomainInfo level 1\n");
2450                 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2451                 if (!NT_STATUS_IS_OK(status)) {
2452                         return false;
2453                 }
2454
2455         }
2456
2457         {
2458                 NTSTATUS status;
2459                 struct samr_OpenUser r;
2460                 struct samr_QueryUserInfo q;
2461                 struct samr_LookupNames n;
2462                 struct policy_handle user_handle;
2463
2464                 n.in.domain_handle = domain_handle;
2465                 n.in.num_names = 1;
2466                 n.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
2467                 n.in.names[0].string = acct_name; 
2468
2469                 status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
2470                 if (!NT_STATUS_IS_OK(status)) {
2471                         printf("LookupNames failed - %s\n", nt_errstr(status));
2472                         return false;
2473                 }
2474
2475                 r.in.domain_handle = domain_handle;
2476                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2477                 r.in.rid = n.out.rids.ids[0];
2478                 r.out.user_handle = &user_handle;
2479
2480                 status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2481                 if (!NT_STATUS_IS_OK(status)) {
2482                         printf("OpenUser(%u) failed - %s\n", n.out.rids.ids[0], nt_errstr(status));
2483                         return false;
2484                 }
2485
2486                 q.in.user_handle = &user_handle;
2487                 q.in.level = 5;
2488
2489                 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
2490                 if (!NT_STATUS_IS_OK(status)) {
2491                         printf("QueryUserInfo failed - %s\n", nt_errstr(status));
2492                         return false;
2493                 }
2494
2495                 printf("calling test_ChangePasswordUser3 with too early password change\n");
2496
2497                 if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 
2498                                               q.out.info->info5.last_password_change, true)) {
2499                         ret = false;
2500                 }
2501         }
2502
2503         /* we change passwords twice - this has the effect of verifying
2504            they were changed correctly for the final call */
2505         if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
2506                 ret = false;
2507         }
2508
2509         if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, 0, true)) {
2510                 ret = false;
2511         }
2512
2513         return ret;
2514 }
2515
2516 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
2517                             struct policy_handle *domain_handle, 
2518                             struct policy_handle *user_handle_out, 
2519                             enum torture_samr_choice which_ops)
2520 {
2521
2522         TALLOC_CTX *user_ctx;
2523
2524         NTSTATUS status;
2525         struct samr_CreateUser r;
2526         struct samr_QueryUserInfo q;
2527         struct samr_DeleteUser d;
2528         uint32_t rid;
2529
2530         /* This call creates a 'normal' account - check that it really does */
2531         const uint32_t acct_flags = ACB_NORMAL;
2532         struct lsa_String name;
2533         bool ret = true;
2534
2535         struct policy_handle user_handle;
2536         user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
2537         init_lsa_String(&name, TEST_ACCOUNT_NAME);
2538
2539         r.in.domain_handle = domain_handle;
2540         r.in.account_name = &name;
2541         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2542         r.out.user_handle = &user_handle;
2543         r.out.rid = &rid;
2544
2545         printf("Testing CreateUser(%s)\n", r.in.account_name->string);
2546
2547         status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2548
2549         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2550                 printf("Server refused create of '%s': %s\n", r.in.account_name->string, nt_errstr(status));
2551                 talloc_free(user_ctx);
2552                 return true;
2553         }
2554
2555         if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2556                 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2557                         talloc_free(user_ctx);
2558                         return false;
2559                 }
2560                 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
2561         }
2562         if (!NT_STATUS_IS_OK(status)) {
2563                 talloc_free(user_ctx);
2564                 printf("CreateUser failed - %s\n", nt_errstr(status));
2565                 return false;
2566         } else {
2567                 q.in.user_handle = &user_handle;
2568                 q.in.level = 16;
2569                 
2570                 status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2571                 if (!NT_STATUS_IS_OK(status)) {
2572                         printf("QueryUserInfo level %u failed - %s\n", 
2573                                q.in.level, nt_errstr(status));
2574                         ret = false;
2575                 } else {
2576                         if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
2577                                 printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2578                                        q.out.info->info16.acct_flags, 
2579                                        acct_flags);
2580                                 ret = false;
2581                         }
2582                 }
2583                 
2584                 if (!test_user_ops(p, tctx, &user_handle, domain_handle, 
2585                                    acct_flags, name.string, which_ops)) {
2586                         ret = false;
2587                 }
2588                 
2589                 if (user_handle_out) {
2590                         *user_handle_out = user_handle;
2591                 } else {
2592                         printf("Testing DeleteUser (createuser test)\n");
2593                         
2594                         d.in.user_handle = &user_handle;
2595                         d.out.user_handle = &user_handle;
2596                         
2597                         status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2598                         if (!NT_STATUS_IS_OK(status)) {
2599                                 printf("DeleteUser failed - %s\n", nt_errstr(status));
2600                                 ret = false;
2601                         }
2602                 }
2603                 
2604         }
2605
2606         talloc_free(user_ctx);
2607         
2608         return ret;
2609 }
2610
2611
2612 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
2613                              struct policy_handle *domain_handle, enum torture_samr_choice which_ops)
2614 {
2615         NTSTATUS status;
2616         struct samr_CreateUser2 r;
2617         struct samr_QueryUserInfo q;
2618         struct samr_DeleteUser d;
2619         struct policy_handle user_handle;
2620         uint32_t rid;
2621         struct lsa_String name;
2622         bool ret = true;
2623         int i;
2624
2625         struct {
2626                 uint32_t acct_flags;
2627                 const char *account_name;
2628                 NTSTATUS nt_status;
2629         } account_types[] = {
2630                 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
2631                 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2632                 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2633                 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2634                 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2635                 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2636                 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
2637                 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2638                 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
2639                 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
2640                 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2641                 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
2642                 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2643                 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
2644                 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
2645         };
2646
2647         for (i = 0; account_types[i].account_name; i++) {
2648                 TALLOC_CTX *user_ctx;
2649                 uint32_t acct_flags = account_types[i].acct_flags;
2650                 uint32_t access_granted;
2651                 user_ctx = talloc_named(tctx, 0, "test_CreateUser2 per-user context");
2652                 init_lsa_String(&name, account_types[i].account_name);
2653
2654                 r.in.domain_handle = domain_handle;
2655                 r.in.account_name = &name;
2656                 r.in.acct_flags = acct_flags;
2657                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2658                 r.out.user_handle = &user_handle;
2659                 r.out.access_granted = &access_granted;
2660                 r.out.rid = &rid;
2661                 
2662                 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
2663                 
2664                 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2665                 
2666                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2667                         talloc_free(user_ctx);
2668                         printf("Server refused create of '%s'\n", r.in.account_name->string);
2669                         continue;
2670
2671                 } else if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2672                         if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
2673                                 talloc_free(user_ctx);
2674                                 ret = false;
2675                                 continue;
2676                         }
2677                         status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
2678
2679                 }
2680                 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
2681                         printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n", 
2682                                nt_errstr(status), nt_errstr(account_types[i].nt_status));
2683                         ret = false;
2684                 }
2685                 
2686                 if (NT_STATUS_IS_OK(status)) {
2687                         q.in.user_handle = &user_handle;
2688                         q.in.level = 5;
2689                         
2690                         status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
2691                         if (!NT_STATUS_IS_OK(status)) {
2692                                 printf("QueryUserInfo level %u failed - %s\n", 
2693                                        q.in.level, nt_errstr(status));
2694                                 ret = false;
2695                         } else {
2696                                 uint32_t expected_flags = (acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
2697                                 if (acct_flags == ACB_NORMAL) {
2698                                         expected_flags |= ACB_PW_EXPIRED;
2699                                 }
2700                                 if ((q.out.info->info5.acct_flags) != expected_flags) {
2701                                         printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
2702                                                q.out.info->info5.acct_flags, 
2703                                                expected_flags);
2704                                         ret = false;
2705                                 } 
2706                                 switch (acct_flags) {
2707                                 case ACB_SVRTRUST:
2708                                         if (q.out.info->info5.primary_gid != DOMAIN_RID_DCS) {
2709                                                 printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n", 
2710                                                        DOMAIN_RID_DCS, q.out.info->info5.primary_gid);
2711                                                 ret = false;
2712                                         }
2713                                         break;
2714                                 case ACB_WSTRUST:
2715                                         if (q.out.info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
2716                                                 printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n", 
2717                                                        DOMAIN_RID_DOMAIN_MEMBERS, q.out.info->info5.primary_gid);
2718                                                 ret = false;
2719                                         }
2720                                         break;
2721                                 case ACB_NORMAL:
2722                                         if (q.out.info->info5.primary_gid != DOMAIN_RID_USERS) {
2723                                                 printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n", 
2724                                                        DOMAIN_RID_USERS, q.out.info->info5.primary_gid);
2725                                                 ret = false;
2726                                         }
2727                                         break;
2728                                 }
2729                         }
2730                 
2731                         if (!test_user_ops(p, tctx, &user_handle, domain_handle, 
2732                                            acct_flags, name.string, which_ops)) {
2733                                 ret = false;
2734                         }
2735
2736                         printf("Testing DeleteUser (createuser2 test)\n");
2737                 
2738                         d.in.user_handle = &user_handle;
2739                         d.out.user_handle = &user_handle;
2740                         
2741                         status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
2742                         if (!NT_STATUS_IS_OK(status)) {
2743                                 printf("DeleteUser failed - %s\n", nt_errstr(status));
2744                                 ret = false;
2745                         }
2746                 }
2747                 talloc_free(user_ctx);
2748         }
2749
2750         return ret;
2751 }
2752
2753 static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2754                                 struct policy_handle *handle)
2755 {
2756         NTSTATUS status;
2757         struct samr_QueryAliasInfo r;
2758         uint16_t levels[] = {1, 2, 3};
2759         int i;
2760         bool ret = true;
2761
2762         for (i=0;i<ARRAY_SIZE(levels);i++) {
2763                 printf("Testing QueryAliasInfo level %u\n", levels[i]);
2764
2765                 r.in.alias_handle = handle;
2766                 r.in.level = levels[i];
2767
2768                 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
2769                 if (!NT_STATUS_IS_OK(status)) {
2770                         printf("QueryAliasInfo level %u failed - %s\n", 
2771                                levels[i], nt_errstr(status));
2772                         ret = false;
2773                 }
2774         }
2775
2776         return ret;
2777 }
2778
2779 static bool test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2780                                 struct policy_handle *handle)
2781 {
2782         NTSTATUS status;
2783         struct samr_QueryGroupInfo r;
2784         uint16_t levels[] = {1, 2, 3, 4, 5};
2785         int i;
2786         bool ret = true;
2787
2788         for (i=0;i<ARRAY_SIZE(levels);i++) {
2789                 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2790
2791                 r.in.group_handle = handle;
2792                 r.in.level = levels[i];
2793
2794                 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2795                 if (!NT_STATUS_IS_OK(status)) {
2796                         printf("QueryGroupInfo level %u failed - %s\n", 
2797                                levels[i], nt_errstr(status));
2798                         ret = false;
2799                 }
2800         }
2801
2802         return ret;
2803 }
2804
2805 static bool test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2806                                   struct policy_handle *handle)
2807 {
2808         NTSTATUS status;
2809         struct samr_QueryGroupMember r;
2810         bool ret = true;
2811
2812         printf("Testing QueryGroupMember\n");
2813
2814         r.in.group_handle = handle;
2815
2816         status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
2817         if (!NT_STATUS_IS_OK(status)) {
2818                 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
2819                 ret = false;
2820         }
2821
2822         return ret;
2823 }
2824
2825
2826 static bool test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2827                               struct policy_handle *handle)
2828 {
2829         NTSTATUS status;
2830         struct samr_QueryGroupInfo r;
2831         struct samr_SetGroupInfo s;
2832         uint16_t levels[] = {1, 2, 3, 4};
2833         uint16_t set_ok[] = {0, 1, 1, 1};
2834         int i;
2835         bool ret = true;
2836
2837         for (i=0;i<ARRAY_SIZE(levels);i++) {
2838                 printf("Testing QueryGroupInfo level %u\n", levels[i]);
2839
2840                 r.in.group_handle = handle;
2841                 r.in.level = levels[i];
2842
2843                 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
2844                 if (!NT_STATUS_IS_OK(status)) {
2845                         printf("QueryGroupInfo level %u failed - %s\n", 
2846                                levels[i], nt_errstr(status));
2847                         ret = false;
2848                 }
2849
2850                 printf("Testing SetGroupInfo level %u\n", levels[i]);
2851
2852                 s.in.group_handle = handle;
2853                 s.in.level = levels[i];
2854                 s.in.info = r.out.info;
2855
2856 #if 0
2857                 /* disabled this, as it changes the name only from the point of view of samr, 
2858                    but leaves the name from the point of view of w2k3 internals (and ldap). This means
2859                    the name is still reserved, so creating the old name fails, but deleting by the old name
2860                    also fails */
2861                 if (s.in.level == 2) {
2862                         init_lsa_String(&s.in.info->string, "NewName");
2863                 }
2864 #endif
2865
2866                 if (s.in.level == 4) {
2867                         init_lsa_String(&s.in.info->description, "test description");
2868                 }
2869
2870                 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
2871                 if (set_ok[i]) {
2872                         if (!NT_STATUS_IS_OK(status)) {
2873                                 printf("SetGroupInfo level %u failed - %s\n", 
2874                                        r.in.level, nt_errstr(status));
2875                                 ret = false;
2876                                 continue;
2877                         }
2878                 } else {
2879                         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
2880                                 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n", 
2881                                        r.in.level, nt_errstr(status));
2882                                 ret = false;
2883                                 continue;
2884                         }
2885                 }
2886         }
2887
2888         return ret;
2889 }
2890
2891 static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2892                                struct policy_handle *handle)
2893 {
2894         NTSTATUS status;
2895         struct samr_QueryUserInfo r;
2896         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2897                            11, 12, 13, 14, 16, 17, 20, 21};
2898         int i;
2899         bool ret = true;
2900
2901         for (i=0;i<ARRAY_SIZE(levels);i++) {
2902                 printf("Testing QueryUserInfo level %u\n", levels[i]);
2903
2904                 r.in.user_handle = handle;
2905                 r.in.level = levels[i];
2906
2907                 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
2908                 if (!NT_STATUS_IS_OK(status)) {
2909                         printf("QueryUserInfo level %u failed - %s\n", 
2910                                levels[i], nt_errstr(status));
2911                         ret = false;
2912                 }
2913         }
2914
2915         return ret;
2916 }
2917
2918 static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2919                                 struct policy_handle *handle)
2920 {
2921         NTSTATUS status;
2922         struct samr_QueryUserInfo2 r;
2923         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2924                            11, 12, 13, 14, 16, 17, 20, 21};
2925         int i;
2926         bool ret = true;
2927
2928         for (i=0;i<ARRAY_SIZE(levels);i++) {
2929                 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
2930
2931                 r.in.user_handle = handle;
2932                 r.in.level = levels[i];
2933
2934                 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
2935                 if (!NT_STATUS_IS_OK(status)) {
2936                         printf("QueryUserInfo2 level %u failed - %s\n", 
2937                                levels[i], nt_errstr(status));
2938                         ret = false;
2939                 }
2940         }
2941
2942         return ret;
2943 }
2944
2945 static bool test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2946                           struct policy_handle *handle, uint32_t rid)
2947 {
2948         NTSTATUS status;
2949         struct samr_OpenUser r;
2950         struct policy_handle user_handle;
2951         bool ret = true;
2952
2953         printf("Testing OpenUser(%u)\n", rid);
2954
2955         r.in.domain_handle = handle;
2956         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2957         r.in.rid = rid;
2958         r.out.user_handle = &user_handle;
2959
2960         status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2961         if (!NT_STATUS_IS_OK(status)) {
2962                 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
2963                 return false;
2964         }
2965
2966         if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
2967                 ret = false;
2968         }
2969
2970         if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
2971                 ret = false;
2972         }
2973
2974         if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
2975                 ret = false;
2976         }
2977
2978         if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
2979                 ret = false;
2980         }
2981
2982         if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
2983                 ret = false;
2984         }
2985
2986         if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
2987                 ret = false;
2988         }
2989
2990         return ret;
2991 }
2992
2993 static bool test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2994                            struct policy_handle *handle, uint32_t rid)
2995 {
2996         NTSTATUS status;
2997         struct samr_OpenGroup r;
2998         struct policy_handle group_handle;
2999         bool ret = true;
3000
3001         printf("Testing OpenGroup(%u)\n", rid);
3002
3003         r.in.domain_handle = handle;
3004         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3005         r.in.rid = rid;
3006         r.out.group_handle = &group_handle;
3007
3008         status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
3009         if (!NT_STATUS_IS_OK(status)) {
3010                 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
3011                 return false;
3012         }
3013
3014         if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
3015                 ret = false;
3016         }
3017
3018         if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
3019                 ret = false;
3020         }
3021
3022         if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
3023                 ret = false;
3024         }
3025
3026         if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
3027                 ret = false;
3028         }
3029
3030         return ret;
3031 }
3032
3033 static bool test_OpenAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3034                            struct policy_handle *handle, uint32_t rid)
3035 {
3036         NTSTATUS status;
3037         struct samr_OpenAlias r;
3038         struct policy_handle alias_handle;
3039         bool ret = true;
3040
3041         printf("Testing OpenAlias(%u)\n", rid);
3042
3043         r.in.domain_handle = handle;
3044         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3045         r.in.rid = rid;
3046         r.out.alias_handle = &alias_handle;
3047
3048         status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
3049         if (!NT_STATUS_IS_OK(status)) {
3050                 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
3051                 return false;
3052         }
3053
3054         if (!test_QuerySecurity(p, mem_ctx, &alias_handle)) {
3055                 ret = false;
3056         }
3057
3058         if (!test_QueryAliasInfo(p, mem_ctx, &alias_handle)) {
3059                 ret = false;
3060         }
3061
3062         if (!test_GetMembersInAlias(p, mem_ctx, &alias_handle)) {
3063                 ret = false;
3064         }
3065
3066         if (!test_samr_handle_Close(p, mem_ctx, &alias_handle)) {
3067                 ret = false;
3068         }
3069
3070         return ret;
3071 }
3072
3073 static bool check_mask(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3074                        struct policy_handle *handle, uint32_t rid, 
3075                        uint32_t acct_flag_mask)
3076 {
3077         NTSTATUS status;
3078         struct samr_OpenUser r;
3079         struct samr_QueryUserInfo q;
3080         struct policy_handle user_handle;
3081         bool ret = true;
3082
3083         printf("Testing OpenUser(%u)\n", rid);
3084
3085         r.in.domain_handle = handle;
3086         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3087         r.in.rid = rid;
3088         r.out.user_handle = &user_handle;
3089
3090         status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3091         if (!NT_STATUS_IS_OK(status)) {
3092                 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
3093                 return false;
3094         }
3095
3096         q.in.user_handle = &user_handle;
3097         q.in.level = 16;
3098         
3099         status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3100         if (!NT_STATUS_IS_OK(status)) {
3101                 printf("QueryUserInfo level 16 failed - %s\n", 
3102                        nt_errstr(status));
3103                 ret = false;
3104         } else {
3105                 if ((acct_flag_mask & q.out.info->info16.acct_flags) == 0) {
3106                         printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
3107                                acct_flag_mask, q.out.info->info16.acct_flags, rid);
3108                         ret = false;
3109                 }
3110         }
3111         
3112         if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3113                 ret = false;
3114         }
3115
3116         return ret;
3117 }
3118
3119 static bool test_EnumDomainUsers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3120                                  struct policy_handle *handle)
3121 {
3122         NTSTATUS status = STATUS_MORE_ENTRIES;
3123         struct samr_EnumDomainUsers r;
3124         uint32_t mask, resume_handle=0;
3125         int i, mask_idx;
3126         bool ret = true;
3127         struct samr_LookupNames n;
3128         struct samr_LookupRids  lr ;
3129         uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST, 
3130                             ACB_DISABLED, ACB_NORMAL | ACB_DISABLED, 
3131                             ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST, 
3132                             ACB_PWNOEXP, 0};
3133
3134         printf("Testing EnumDomainUsers\n");
3135
3136         for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
3137                 r.in.domain_handle = handle;
3138                 r.in.resume_handle = &resume_handle;
3139                 r.in.acct_flags = mask = masks[mask_idx];
3140                 r.in.max_size = (uint32_t)-1;
3141                 r.out.resume_handle = &resume_handle;
3142
3143                 status = dcerpc_samr_EnumDomainUsers(p, mem_ctx, &r);
3144                 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&  
3145                     !NT_STATUS_IS_OK(status)) {
3146                         printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
3147                         return false;
3148                 }
3149         
3150                 if (!r.out.sam) {
3151                         printf("EnumDomainUsers failed: r.out.sam unexpectedly NULL\n");
3152                         return false;
3153                 }
3154
3155                 if (r.out.sam->count == 0) {
3156                         continue;
3157                 }
3158
3159                 for (i=0;i<r.out.sam->count;i++) {
3160                         if (mask) {
3161                                 if (!check_mask(p, mem_ctx, handle, r.out.sam->entries[i].idx, mask)) {
3162                                         ret = false;
3163                                 }
3164                         } else if (!test_OpenUser(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3165                                 ret = false;
3166                         }
3167                 }
3168         }
3169
3170         printf("Testing LookupNames\n");
3171         n.in.domain_handle = handle;
3172         n.in.num_names = r.out.sam->count;
3173         n.in.names = talloc_array(mem_ctx, struct lsa_String, r.out.sam->count);
3174         for (i=0;i<r.out.sam->count;i++) {
3175                 n.in.names[i].string = r.out.sam->entries[i].name.string;
3176         }
3177         status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
3178         if (!NT_STATUS_IS_OK(status)) {
3179                 printf("LookupNames failed - %s\n", nt_errstr(status));
3180                 ret = false;
3181         }
3182
3183
3184         printf("Testing LookupRids\n");
3185         lr.in.domain_handle = handle;
3186         lr.in.num_rids = r.out.sam->count;
3187         lr.in.rids = talloc_array(mem_ctx, uint32_t, r.out.sam->count);
3188         for (i=0;i<r.out.sam->count;i++) {
3189                 lr.in.rids[i] = r.out.sam->entries[i].idx;
3190         }
3191         status = dcerpc_samr_LookupRids(p, mem_ctx, &lr);
3192         if (!NT_STATUS_IS_OK(status)) {
3193                 printf("LookupRids failed - %s\n", nt_errstr(status));
3194                 ret = false;
3195         }
3196
3197         return ret;     
3198 }
3199
3200 /*
3201   try blasting the server with a bunch of sync requests
3202 */
3203 static bool test_EnumDomainUsers_async(struct dcerpc_pipe *p, TALLOC_CTX *tctx, 
3204                                        struct policy_handle *handle)
3205 {
3206         NTSTATUS status;
3207         struct samr_EnumDomainUsers r;
3208         uint32_t resume_handle=0;
3209         int i;
3210 #define ASYNC_COUNT 100
3211         struct rpc_request *req[ASYNC_COUNT];
3212
3213         if (!torture_setting_bool(tctx, "dangerous", false)) {
3214                 printf("samr async test disabled - enable dangerous tests to use\n");
3215                 return true;
3216         }
3217
3218         printf("Testing EnumDomainUsers_async\n");
3219
3220         r.in.domain_handle = handle;
3221         r.in.resume_handle = &resume_handle;
3222         r.in.acct_flags = 0;
3223         r.in.max_size = (uint32_t)-1;
3224         r.out.resume_handle = &resume_handle;
3225
3226         for (i=0;i<ASYNC_COUNT;i++) {
3227                 req[i] = dcerpc_samr_EnumDomainUsers_send(p, tctx, &r);
3228         }
3229
3230         for (i=0;i<ASYNC_COUNT;i++) {
3231                 status = dcerpc_ndr_request_recv(req[i]);
3232                 if (!NT_STATUS_IS_OK(status)) {
3233                         printf("EnumDomainUsers[%d] failed - %s\n", 
3234                                i, nt_errstr(status));
3235                         return false;
3236                 }
3237         }
3238         
3239         printf("%d async requests OK\n", i);
3240
3241         return true;
3242 }
3243
3244 static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3245                                   struct policy_handle *handle)
3246 {
3247         NTSTATUS status;
3248         struct samr_EnumDomainGroups r;
3249         uint32_t resume_handle=0;
3250         int i;
3251         bool ret = true;
3252
3253         printf("Testing EnumDomainGroups\n");
3254
3255         r.in.domain_handle = handle;
3256         r.in.resume_handle = &resume_handle;
3257         r.in.max_size = (uint32_t)-1;
3258         r.out.resume_handle = &resume_handle;
3259
3260         status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
3261         if (!NT_STATUS_IS_OK(status)) {
3262                 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
3263                 return false;
3264         }
3265         
3266         if (!r.out.sam) {
3267                 return false;
3268         }
3269
3270         for (i=0;i<r.out.sam->count;i++) {
3271                 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3272                         ret = false;
3273                 }
3274         }
3275
3276         return ret;
3277 }
3278
3279 static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3280                                    struct policy_handle *handle)
3281 {
3282         NTSTATUS status;
3283         struct samr_EnumDomainAliases r;
3284         uint32_t resume_handle=0;
3285         int i;
3286         bool ret = true;
3287
3288         printf("Testing EnumDomainAliases\n");
3289
3290         r.in.domain_handle = handle;
3291         r.in.resume_handle = &resume_handle;
3292         r.in.acct_flags = (uint32_t)-1;
3293         r.out.resume_handle = &resume_handle;
3294
3295         status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
3296         if (!NT_STATUS_IS_OK(status)) {
3297                 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
3298                 return false;
3299         }
3300         
3301         if (!r.out.sam) {
3302                 return false;
3303         }
3304
3305         for (i=0;i<r.out.sam->count;i++) {
3306                 if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
3307                         ret = false;
3308                 }
3309         }
3310
3311         return ret;     
3312 }
3313
3314 static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3315                                             struct policy_handle *handle)
3316 {
3317         NTSTATUS status;
3318         struct samr_GetDisplayEnumerationIndex r;
3319         bool ret = true;
3320         uint16_t levels[] = {1, 2, 3, 4, 5};
3321         uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3322         int i;
3323
3324         for (i=0;i<ARRAY_SIZE(levels);i++) {
3325                 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
3326
3327                 r.in.domain_handle = handle;
3328                 r.in.level = levels[i];
3329                 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
3330
3331                 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3332
3333                 if (ok_lvl[i] && 
3334                     !NT_STATUS_IS_OK(status) &&
3335                     !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3336                         printf("GetDisplayEnumerationIndex level %u failed - %s\n", 
3337                                levels[i], nt_errstr(status));
3338                         ret = false;
3339                 }
3340
3341                 init_lsa_String(&r.in.name, "zzzzzzzz");
3342
3343                 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
3344                 
3345                 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3346                         printf("GetDisplayEnumerationIndex level %u failed - %s\n", 
3347                                levels[i], nt_errstr(status));
3348                         ret = false;
3349                 }
3350         }
3351         
3352         return ret;     
3353 }
3354
3355 static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3356                                              struct policy_handle *handle)
3357 {
3358         NTSTATUS status;
3359         struct samr_GetDisplayEnumerationIndex2 r;
3360         bool ret = true;
3361         uint16_t levels[] = {1, 2, 3, 4, 5};
3362         uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
3363         int i;
3364
3365         for (i=0;i<ARRAY_SIZE(levels);i++) {
3366                 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
3367
3368                 r.in.domain_handle = handle;
3369                 r.in.level = levels[i];
3370                 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
3371
3372                 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3373                 if (ok_lvl[i] && 
3374                     !NT_STATUS_IS_OK(status) && 
3375                     !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3376                         printf("GetDisplayEnumerationIndex2 level %u failed - %s\n", 
3377                                levels[i], nt_errstr(status));
3378                         ret = false;
3379                 }
3380
3381                 init_lsa_String(&r.in.name, "zzzzzzzz");
3382
3383                 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
3384                 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
3385                         printf("GetDisplayEnumerationIndex2 level %u failed - %s\n", 
3386                                levels[i], nt_errstr(status));
3387                         ret = false;
3388                 }
3389         }
3390         
3391         return ret;     
3392 }
3393
3394 #define STRING_EQUAL_QUERY(s1, s2, user)                                        \
3395         if (s1.string == NULL && s2.string != NULL && s2.string[0] == '\0') { \
3396                 /* odd, but valid */                                            \
3397         } else if ((s1.string && !s2.string) || (s2.string && !s1.string) || strcmp(s1.string, s2.string)) { \
3398                         printf("%s mismatch for %s: %s != %s (%s)\n", \
3399                                #s1, user.string,  s1.string, s2.string, __location__);   \
3400                         ret = false; \
3401         }
3402 #define INT_EQUAL_QUERY(s1, s2, user)           \
3403                 if (s1 != s2) { \
3404                         printf("%s mismatch for %s: 0x%llx != 0x%llx (%s)\n", \
3405                                #s1, user.string, (unsigned long long)s1, (unsigned long long)s2, __location__); \
3406                         ret = false; \
3407                 }
3408
3409 static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3410                                        struct samr_QueryDisplayInfo *querydisplayinfo,
3411                                        bool *seen_testuser) 
3412 {
3413         struct samr_OpenUser r;
3414         struct samr_QueryUserInfo q;
3415         struct policy_handle user_handle;
3416         int i, ret = true;
3417         NTSTATUS status;
3418         r.in.domain_handle = querydisplayinfo->in.domain_handle;
3419         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3420         for (i = 0; ; i++) {
3421                 switch (querydisplayinfo->in.level) {
3422                 case 1:
3423                         if (i >= querydisplayinfo->out.info.info1.count) {
3424                                 return ret;
3425                         }
3426                         r.in.rid = querydisplayinfo->out.info.info1.entries[i].rid;
3427                         break;
3428                 case 2:
3429                         if (i >= querydisplayinfo->out.info.info2.count) {
3430                                 return ret;
3431                         }
3432                         r.in.rid = querydisplayinfo->out.info.info2.entries[i].rid;
3433                         break;
3434                 case 3:
3435                         /* Groups */
3436                 case 4:
3437                 case 5:
3438                         /* Not interested in validating just the account name */
3439                         return true;
3440                 }
3441                         
3442                 r.out.user_handle = &user_handle;
3443                 
3444                 switch (querydisplayinfo->in.level) {
3445                 case 1:
3446                 case 2:
3447                         status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
3448                         if (!NT_STATUS_IS_OK(status)) {
3449                                 printf("OpenUser(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3450                                 return false;
3451                         }
3452                 }
3453                 
3454                 q.in.user_handle = &user_handle;
3455                 q.in.level = 21;
3456                 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
3457                 if (!NT_STATUS_IS_OK(status)) {
3458                         printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
3459                         return false;
3460                 }
3461                 
3462                 switch (querydisplayinfo->in.level) {
3463                 case 1:
3464                         if (seen_testuser && strcmp(q.out.info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
3465                                 *seen_testuser = true;
3466                         }
3467                         STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].full_name, 
3468                                            q.out.info->info21.full_name, q.out.info->info21.account_name);
3469                         STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].account_name, 
3470                                            q.out.info->info21.account_name, q.out.info->info21.account_name);
3471                         STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].description, 
3472                                            q.out.info->info21.description, q.out.info->info21.account_name);
3473                         INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].rid, 
3474                                         q.out.info->info21.rid, q.out.info->info21.account_name);
3475                         INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].acct_flags, 
3476                                         q.out.info->info21.acct_flags, q.out.info->info21.account_name);
3477                         
3478                         break;
3479                 case 2:
3480                         STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].account_name, 
3481                                            q.out.info->info21.account_name, q.out.info->info21.account_name);
3482                         STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].description, 
3483                                            q.out.info->info21.description, q.out.info->info21.account_name);
3484                         INT_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].rid, 
3485                                         q.out.info->info21.rid, q.out.info->info21.account_name);
3486                         INT_EQUAL_QUERY((querydisplayinfo->out.info.info2.entries[i].acct_flags & ~ACB_NORMAL), 
3487                                         q.out.info->info21.acct_flags, q.out.info->info21.account_name);
3488                         
3489                         if (!(querydisplayinfo->out.info.info2.entries[i].acct_flags & ACB_NORMAL)) {
3490                                 printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n", 
3491                                        q.out.info->info21.account_name.string);
3492                         }
3493
3494                         if (!(q.out.info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
3495                                 printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
3496                                        q.out.info->info21.account_name.string,
3497                                        querydisplayinfo->out.info.info2.entries[i].acct_flags,
3498                                        q.out.info->info21.acct_flags);
3499                                 return false;
3500                         }
3501                         
3502                         break;
3503                 }
3504                 
3505                 if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
3506                         return false;
3507                 }
3508         }
3509         return ret;
3510 }
3511
3512 static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3513                                   struct policy_handle *handle)
3514 {
3515         NTSTATUS status;
3516         struct samr_QueryDisplayInfo r;
3517         struct samr_QueryDomainInfo dom_info;
3518         bool ret = true;
3519         uint16_t levels[] = {1, 2, 3, 4, 5};
3520         int i;
3521         bool seen_testuser = false;
3522
3523         for (i=0;i<ARRAY_SIZE(levels);i++) {
3524                 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
3525
3526                 r.in.start_idx = 0;
3527                 status = STATUS_MORE_ENTRIES;
3528                 while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3529                         r.in.domain_handle = handle;
3530                         r.in.level = levels[i];
3531                         r.in.max_entries = 2;
3532                         r.in.buf_size = (uint32_t)-1;
3533                         
3534                         status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3535                         if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
3536                                 printf("QueryDisplayInfo level %u failed - %s\n", 
3537                                        levels[i], nt_errstr(status));
3538                                 ret = false;
3539                         }
3540                         switch (r.in.level) {
3541                         case 1:
3542                                 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, &seen_testuser)) {
3543                                         ret = false;
3544                                 }
3545                                 r.in.start_idx += r.out.info.info1.count;
3546                                 break;
3547                         case 2:
3548                                 if (!test_each_DisplayInfo_user(p, mem_ctx, &r, NULL)) {
3549                                         ret = false;
3550                                 }
3551                                 r.in.start_idx += r.out.info.info2.count;
3552                                 break;
3553                         case 3:
3554                                 r.in.start_idx += r.out.info.info3.count;
3555                                 break;
3556                         case 4:
3557                                 r.in.start_idx += r.out.info.info4.count;
3558                                 break;
3559                         case 5:
3560                                 r.in.start_idx += r.out.info.info5.count;
3561                                 break;
3562                         }
3563                 }
3564                 dom_info.in.domain_handle = handle;
3565                 dom_info.in.level = 2;
3566                 /* Check number of users returned is correct */
3567                 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &dom_info);
3568                 if (!NT_STATUS_IS_OK(status)) {
3569                         printf("QueryDomainInfo level %u failed - %s\n", 
3570                                r.in.level, nt_errstr(status));
3571                                 ret = false;
3572                                 break;
3573                 }
3574                 switch (r.in.level) {
3575                 case 1:
3576                 case 4:
3577                         if (dom_info.out.info->info2.num_users < r.in.start_idx) {
3578                                 printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
3579                                        r.in.start_idx, dom_info.out.info->info2.num_groups,
3580                                        dom_info.out.info->info2.domain_name.string);
3581                                 ret = false;
3582                         }
3583                         if (!seen_testuser) {
3584                                 struct policy_handle user_handle;
3585                                 if (NT_STATUS_IS_OK(test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
3586                                         printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n", 
3587                                                dom_info.out.info->info2.domain_name.string);
3588                                         ret = false;
3589                                         test_samr_handle_Close(p, mem_ctx, &user_handle);
3590                                 }
3591                         }
3592                         break;
3593                 case 3:
3594                 case 5:
3595                         if (dom_info.out.info->info2.num_groups != r.in.start_idx) {
3596                                 printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
3597                                        r.in.start_idx, dom_info.out.info->info2.num_groups,
3598                                        dom_info.out.info->info2.domain_name.string);
3599                                 ret = false;
3600                         }
3601                         
3602                         break;
3603                 }
3604
3605         }
3606         
3607         return ret;     
3608 }
3609
3610 static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3611                                   struct policy_handle *handle)
3612 {
3613         NTSTATUS status;
3614         struct samr_QueryDisplayInfo2 r;
3615         bool ret = true;
3616         uint16_t levels[] = {1, 2, 3, 4, 5};
3617         int i;
3618
3619         for (i=0;i<ARRAY_SIZE(levels);i++) {
3620                 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
3621
3622                 r.in.domain_handle = handle;
3623                 r.in.level = levels[i];
3624                 r.in.start_idx = 0;
3625                 r.in.max_entries = 1000;
3626                 r.in.buf_size = (uint32_t)-1;
3627
3628                 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
3629                 if (!NT_STATUS_IS_OK(status)) {
3630                         printf("QueryDisplayInfo2 level %u failed - %s\n", 
3631                                levels[i], nt_errstr(status));
3632                         ret = false;
3633                 }
3634         }
3635         
3636         return ret;     
3637 }
3638
3639 static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3640                                   struct policy_handle *handle)
3641 {
3642         NTSTATUS status;
3643         struct samr_QueryDisplayInfo3 r;
3644         bool ret = true;
3645         uint16_t levels[] = {1, 2, 3, 4, 5};
3646         int i;
3647
3648         for (i=0;i<ARRAY_SIZE(levels);i++) {
3649                 printf("Testing QueryDisplayInfo3 level %u\n", levels[i]);
3650
3651                 r.in.domain_handle = handle;
3652                 r.in.level = levels[i];
3653                 r.in.start_idx = 0;
3654                 r.in.max_entries = 1000;
3655                 r.in.buf_size = (uint32_t)-1;
3656
3657                 status = dcerpc_samr_QueryDisplayInfo3(p, mem_ctx, &r);
3658                 if (!NT_STATUS_IS_OK(status)) {
3659                         printf("QueryDisplayInfo3 level %u failed - %s\n", 
3660                                levels[i], nt_errstr(status));
3661                         ret = false;
3662                 }
3663         }
3664         
3665         return ret;     
3666 }
3667
3668
3669 static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3670                                            struct policy_handle *handle)
3671 {
3672         NTSTATUS status;
3673         struct samr_QueryDisplayInfo r;
3674         bool ret = true;
3675
3676         printf("Testing QueryDisplayInfo continuation\n");
3677
3678         r.in.domain_handle = handle;
3679         r.in.level = 1;
3680         r.in.start_idx = 0;
3681         r.in.max_entries = 1;
3682         r.in.buf_size = (uint32_t)-1;
3683
3684         do {
3685                 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
3686                 if (NT_STATUS_IS_OK(status) && r.out.returned_size != 0) {
3687                         if (r.out.info.info1.entries[0].idx != r.in.start_idx + 1) {
3688                                 printf("expected idx %d but got %d\n",
3689                                        r.in.start_idx + 1,
3690                                        r.out.info.info1.entries[0].idx);
3691                                 break;
3692                         }
3693                 }
3694                 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
3695                     !NT_STATUS_IS_OK(status)) {
3696                         printf("QueryDisplayInfo level %u failed - %s\n", 
3697                                r.in.level, nt_errstr(status));
3698                         ret = false;
3699                         break;
3700                 }
3701                 r.in.start_idx++;
3702         } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
3703                   NT_STATUS_IS_OK(status)) &&
3704                  r.out.returned_size != 0);
3705         
3706         return ret;     
3707 }
3708
3709 static bool test_QueryDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3710                                  struct policy_handle *handle)
3711 {
3712         NTSTATUS status;
3713         struct samr_QueryDomainInfo r;
3714         struct samr_SetDomainInfo s;
3715         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
3716         uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1,  0,  1,  0};
3717         int i;
3718         bool ret = true;
3719         const char *domain_comment = talloc_asprintf(mem_ctx, 
3720                                   "Tortured by Samba4 RPC-SAMR: %s", 
3721                                   timestring(mem_ctx, time(NULL)));
3722
3723         s.in.domain_handle = handle;
3724         s.in.level = 4;
3725         s.in.info = talloc(mem_ctx, union samr_DomainInfo);
3726         
3727         s.in.info->info4.comment.string = domain_comment;
3728         status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3729         if (!NT_STATUS_IS_OK(status)) {
3730                 printf("SetDomainInfo level %u (set comment) failed - %s\n", 
3731                        r.in.level, nt_errstr(status));
3732                 return false;
3733         }
3734
3735         for (i=0;i<ARRAY_SIZE(levels);i++) {
3736                 printf("Testing QueryDomainInfo level %u\n", levels[i]);
3737
3738                 r.in.domain_handle = handle;
3739                 r.in.level = levels[i];
3740
3741                 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
3742                 if (!NT_STATUS_IS_OK(status)) {
3743                         printf("QueryDomainInfo level %u failed - %s\n", 
3744                                r.in.level, nt_errstr(status));
3745                         ret = false;
3746                         continue;
3747                 }
3748
3749                 switch (levels[i]) {
3750                 case 2:
3751                         if (strcmp(r.out.info->info2.comment.string, domain_comment) != 0) {
3752                                 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
3753                                        levels[i], r.out.info->info2.comment.string, domain_comment);
3754                                 ret = false;
3755                         }
3756                         if (!r.out.info->info2.primary.string) {
3757                                 printf("QueryDomainInfo level %u returned no PDC name\n",
3758                                        levels[i]);
3759                                 ret = false;
3760                         } else if (r.out.info->info2.role == SAMR_ROLE_DOMAIN_PDC) {
3761                                 if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), r.out.info->info2.primary.string) != 0) {
3762                                         printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
3763                                                levels[i], r.out.info->info2.primary.string, dcerpc_server_name(p));
3764                                 }
3765                         }
3766                         break;
3767                 case 4:
3768                         if (strcmp(r.out.info->info4.comment.string, domain_comment) != 0) {
3769                                 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
3770                                        levels[i], r.out.info->info4.comment.string, domain_comment);
3771                                 ret = false;
3772                         }
3773                         break;
3774                 case 6:
3775                         if (!r.out.info->info6.primary.string) {
3776                                 printf("QueryDomainInfo level %u returned no PDC name\n",
3777                                        levels[i]);
3778                                 ret = false;
3779                         }
3780                         break;
3781                 case 11:
3782                         if (strcmp(r.out.info->info11.info2.comment.string, domain_comment) != 0) {
3783                                 printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
3784                                        levels[i], r.out.info->info11.info2.comment.string, domain_comment);
3785                                 ret = false;
3786                         }
3787                         break;
3788                 }
3789
3790                 printf("Testing SetDomainInfo level %u\n", levels[i]);
3791
3792                 s.in.domain_handle = handle;
3793                 s.in.level = levels[i];
3794                 s.in.info = r.out.info;
3795
3796                 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
3797                 if (set_ok[i]) {
3798                         if (!NT_STATUS_IS_OK(status)) {
3799                                 printf("SetDomainInfo level %u failed - %s\n", 
3800                                        r.in.level, nt_errstr(status));
3801                                 ret = false;
3802                                 continue;
3803                         }
3804                 } else {
3805                         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
3806                                 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n", 
3807                                        r.in.level, nt_errstr(status));
3808                                 ret = false;
3809                                 continue;
3810                         }
3811                 }
3812
3813                 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
3814                 if (!NT_STATUS_IS_OK(status)) {
3815                         printf("QueryDomainInfo level %u failed - %s\n", 
3816                                r.in.level, nt_errstr(status));
3817                         ret = false;
3818                         continue;
3819                 }
3820         }
3821
3822         return ret;     
3823 }
3824
3825
3826 static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3827                                   struct policy_handle *handle)
3828 {
3829         NTSTATUS status;
3830         struct samr_QueryDomainInfo2 r;
3831         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
3832         int i;
3833         bool ret = true;
3834
3835         for (i=0;i<ARRAY_SIZE(levels);i++) {
3836                 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
3837
3838                 r.in.domain_handle = handle;
3839                 r.in.level = levels[i];
3840
3841                 status = dcerpc_samr_QueryDomainInfo2(p, mem_ctx, &r);
3842                 if (!NT_STATUS_IS_OK(status)) {
3843                         printf("QueryDomainInfo2 level %u failed - %s\n", 
3844                                r.in.level, nt_errstr(status));
3845                         ret = false;
3846                         continue;
3847                 }
3848         }
3849
3850         return true;    
3851 }
3852
3853 /* Test whether querydispinfo level 5 and enumdomgroups return the same
3854    set of group names. */
3855 static bool test_GroupList(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3856                            struct policy_handle *handle)
3857 {
3858         struct samr_EnumDomainGroups q1;
3859         struct samr_QueryDisplayInfo q2;
3860         NTSTATUS status;
3861         uint32_t resume_handle=0;
3862         int i;
3863         bool ret = true;
3864
3865         int num_names = 0;
3866         const char **names = NULL;
3867
3868         printf("Testing coherency of querydispinfo vs enumdomgroups\n");
3869
3870         q1.in.domain_handle = handle;
3871         q1.in.resume_handle = &resume_handle;
3872         q1.in.max_size = 5;
3873         q1.out.resume_handle = &resume_handle;
3874
3875         status = STATUS_MORE_ENTRIES;
3876         while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3877                 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &q1);
3878
3879                 if (!NT_STATUS_IS_OK(status) &&
3880                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
3881                         break;
3882
3883                 for (i=0; i<q1.out.num_entries; i++) {
3884                         add_string_to_array(mem_ctx,
3885                                             q1.out.sam->entries[i].name.string,
3886                                             &names, &num_names);
3887                 }
3888         }
3889
3890         if (!NT_STATUS_IS_OK(status)) {
3891                 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
3892                 return false;
3893         }
3894         
3895         if (!q1.out.sam) {
3896                 return false;
3897         }
3898
3899         q2.in.domain_handle = handle;
3900         q2.in.level = 5;
3901         q2.in.start_idx = 0;
3902         q2.in.max_entries = 5;
3903         q2.in.buf_size = (uint32_t)-1;
3904
3905         status = STATUS_MORE_ENTRIES;
3906         while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
3907                 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &q2);
3908
3909                 if (!NT_STATUS_IS_OK(status) &&
3910                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
3911                         break;
3912
3913                 for (i=0; i<q2.out.info.info5.count; i++) {
3914                         int j;
3915                         const char *name = q2.out.info.info5.entries[i].account_name.string;
3916                         bool found = false;
3917                         for (j=0; j<num_names; j++) {
3918                                 if (names[j] == NULL)
3919                                         continue;
3920                                 if (strequal(names[j], name)) {
3921                                         names[j] = NULL;
3922                                         found = true;
3923                                         break;
3924                                 }
3925                         }
3926
3927                         if (!found) {
3928                                 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
3929                                        name);
3930                                 ret = false;
3931                         }
3932                 }
3933                 q2.in.start_idx += q2.out.info.info5.count;
3934         }
3935
3936         if (!NT_STATUS_IS_OK(status)) {
3937                 printf("QueryDisplayInfo level 5 failed - %s\n",
3938                        nt_errstr(status));
3939                 ret = false;
3940         }
3941
3942         for (i=0; i<num_names; i++) {
3943                 if (names[i] != NULL) {
3944                         printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
3945                                names[i]);
3946                         ret = false;
3947                 }
3948         }
3949
3950         return ret;
3951 }
3952
3953 static bool test_DeleteDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3954                                    struct policy_handle *group_handle)
3955 {
3956         struct samr_DeleteDomainGroup d;
3957         NTSTATUS status;
3958         bool ret = true;
3959
3960         printf("Testing DeleteDomainGroup\n");
3961
3962         d.in.group_handle = group_handle;
3963         d.out.group_handle = group_handle;
3964
3965         status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
3966         if (!NT_STATUS_IS_OK(status)) {
3967                 printf("DeleteDomainGroup failed - %s\n", nt_errstr(status));
3968                 ret = false;
3969         }
3970
3971         return ret;
3972 }
3973
3974 static bool test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3975                                             struct policy_handle *domain_handle)
3976 {
3977         struct samr_TestPrivateFunctionsDomain r;
3978         NTSTATUS status;
3979         bool ret = true;
3980
3981         printf("Testing TestPrivateFunctionsDomain\n");
3982
3983         r.in.domain_handle = domain_handle;
3984
3985         status = dcerpc_samr_TestPrivateFunctionsDomain(p, mem_ctx, &r);
3986         if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
3987                 printf("TestPrivateFunctionsDomain failed - %s\n", nt_errstr(status));
3988                 ret = false;
3989         }
3990
3991         return ret;
3992 }
3993
3994 static bool test_RidToSid(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
3995                           struct dom_sid *domain_sid,
3996                           struct policy_handle *domain_handle)
3997 {
3998         struct samr_RidToSid r;
3999         NTSTATUS status;
4000         bool ret = true;
4001         struct dom_sid *calc_sid;
4002         int rids[] = { 0, 42, 512, 10200 };
4003         int i;
4004
4005         for (i=0;i<ARRAY_SIZE(rids);i++) {
4006         
4007                 printf("Testing RidToSid\n");
4008                 
4009                 calc_sid = dom_sid_dup(mem_ctx, domain_sid);
4010                 r.in.domain_handle = domain_handle;
4011                 r.in.rid = rids[i];
4012                 
4013                 status = dcerpc_samr_RidToSid(p, mem_ctx, &r);
4014                 if (!NT_STATUS_IS_OK(status)) {
4015                         printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
4016                         ret = false;
4017                 } else {
4018                         calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
4019
4020                         if (!dom_sid_equal(calc_sid, r.out.sid)) {
4021                                 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i], 
4022                                        dom_sid_string(mem_ctx, r.out.sid), 
4023                                        dom_sid_string(mem_ctx, calc_sid));
4024                                 ret = false;
4025                         }
4026                 }
4027         }
4028
4029         return ret;
4030 }
4031
4032 static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
4033                                        struct policy_handle *domain_handle)
4034 {
4035         struct samr_GetBootKeyInformation r;
4036         NTSTATUS status;
4037         bool ret = true;
4038
4039         printf("Testing GetBootKeyInformation\n");
4040
4041         r.in.domain_handle = domain_handle;
4042
4043         status = dcerpc_samr_GetBootKeyInformation(p, mem_ctx, &r);
4044         if (!NT_STATUS_IS_OK(status)) {
4045                 /* w2k3 seems to fail this sometimes and pass it sometimes */
4046                 printf("GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
4047         }
4048
4049         return ret;
4050 }
4051
4052 static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *tctx, 
4053                                 struct policy_handle *domain_handle,
4054                                 struct policy_handle *group_handle)
4055 {
4056         NTSTATUS status;
4057         struct samr_AddGroupMember r;
4058         struct samr_DeleteGroupMember d;
4059         struct samr_QueryGroupMember q;
4060         struct samr_SetMemberAttributesOfGroup s;
4061         bool ret = true;
4062         uint32_t rid;
4063
4064         status = test_LookupName(p, tctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
4065         if (!NT_STATUS_IS_OK(status)) {
4066                 printf("test_AddGroupMember looking up name " TEST_ACCOUNT_NAME " failed - %s\n", nt_errstr(status));
4067                 return false;
4068         }
4069
4070         r.in.group_handle = group_handle;
4071         r.in.rid = rid;
4072         r.in.flags = 0; /* ??? */
4073
4074         printf("Testing AddGroupMember and DeleteGroupMember\n");
4075
4076         d.in.group_handle = group_handle;
4077         d.in.rid = rid;
4078
4079         status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
4080         if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_NOT_IN_GROUP, status)) {
4081                 printf("DeleteGroupMember gave %s - should be NT_STATUS_MEMBER_NOT_IN_GROUP\n", 
4082                        nt_errstr(status));
4083                 return false;
4084         }
4085
4086         status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4087         if (!NT_STATUS_IS_OK(status)) {
4088                 printf("AddGroupMember failed - %s\n", nt_errstr(status));
4089                 return false;
4090         }
4091
4092         status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4093         if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_IN_GROUP, status)) {
4094                 printf("AddGroupMember gave %s - should be NT_STATUS_MEMBER_IN_GROUP\n", 
4095                        nt_errstr(status));
4096                 return false;
4097         }
4098
4099         if (torture_setting_bool(tctx, "samba4", false)) {
4100                 printf("skipping SetMemberAttributesOfGroup test against Samba4\n");
4101         } else {
4102                 /* this one is quite strange. I am using random inputs in the
4103                    hope of triggering an error that might give us a clue */
4104
4105                 s.in.group_handle = group_handle;
4106                 s.in.unknown1 = random();
4107                 s.in.unknown2 = random();
4108
4109                 status = dcerpc_samr_SetMemberAttributesOfGroup(p, tctx, &s);
4110                 if (!NT_STATUS_IS_OK(status)) {
4111                         printf("SetMemberAttributesOfGroup failed - %s\n", nt_errstr(status));
4112                         return false;
4113                 }
4114         }
4115
4116         q.in.group_handle = group_handle;
4117
4118         status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
4119         if (!NT_STATUS_IS_OK(status)) {
4120                 printf("QueryGroupMember failed - %s\n", nt_errstr(status));
4121                 return false;
4122         }
4123
4124         status = dcerpc_samr_DeleteGroupMember(p, tctx, &d);
4125         if (!NT_STATUS_IS_OK(status)) {
4126                 printf("DeleteGroupMember failed - %s\n", nt_errstr(status));
4127                 return false;
4128         }
4129
4130         status = dcerpc_samr_AddGroupMember(p, tctx, &r);
4131         if (!NT_STATUS_IS_OK(status)) {
4132                 printf("AddGroupMember failed - %s\n", nt_errstr(status));
4133                 return false;
4134         }
4135
4136         return ret;
4137 }
4138
4139
4140 static bool test_CreateDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
4141                                    struct policy_handle *domain_handle, struct policy_handle *group_handle)
4142 {
4143         NTSTATUS status;
4144         struct samr_CreateDomainGroup r;
4145         uint32_t rid;
4146         struct lsa_String name;
4147         bool ret = true;
4148
4149         init_lsa_String(&name, TEST_GROUPNAME);
4150
4151         r.in.domain_handle = domain_handle;
4152         r.in.name = &name;
4153         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4154         r.out.group_handle = group_handle;
4155         r.out.rid = &rid;
4156
4157         printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
4158
4159         status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
4160
4161         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4162                 printf("Server refused create of '%s'\n", r.in.name->string);
4163                 ZERO_STRUCTP(group_handle);
4164                 return true;
4165         }
4166
4167         if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
4168                 if (!test_DeleteGroup_byname(p, mem_ctx, domain_handle, r.in.name->string)) {
4169                         
4170                         printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string, 
4171                                nt_errstr(status));
4172                         return false;
4173                 }
4174                 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
4175         }
4176         if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
4177                 if (!test_DeleteUser_byname(p, mem_ctx, domain_handle, r.in.name->string)) {
4178                         
4179                         printf("CreateDomainGroup failed: Could not delete user %s - %s\n", r.in.name->string, 
4180                                nt_errstr(status));
4181                         return false;
4182                 }
4183                 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
4184         }
4185         if (!NT_STATUS_IS_OK(status)) {
4186                 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
4187                 return false;
4188         }
4189
4190         if (!test_AddGroupMember(p, mem_ctx, domain_handle, group_handle)) {
4191                 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
4192                 ret = false;
4193         }
4194
4195         if (!test_SetGroupInfo(p, mem_ctx, group_handle)) {
4196                 ret = false;
4197         }
4198
4199         return ret;
4200 }
4201
4202
4203 /*
4204   its not totally clear what this does. It seems to accept any sid you like.
4205 */
4206 static bool test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p, 
4207                                                TALLOC_CTX *mem_ctx, 
4208                                                struct policy_handle *domain_handle)
4209 {
4210         NTSTATUS status;
4211         struct samr_RemoveMemberFromForeignDomain r;
4212
4213         r.in.domain_handle = domain_handle;
4214         r.in.sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-12-34-56-78");
4215
4216         status = dcerpc_samr_RemoveMemberFromForeignDomain(p, mem_ctx, &r);
4217         if (!NT_STATUS_IS_OK(status)) {
4218                 printf("RemoveMemberFromForeignDomain failed - %s\n", nt_errstr(status));
4219                 return false;
4220         }
4221
4222         return true;
4223 }
4224
4225
4226
4227 static bool test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
4228                          struct policy_handle *handle);
4229
4230 static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx, 
4231                             struct policy_handle *handle, struct dom_sid *sid,
4232                             enum torture_samr_choice which_ops)
4233 {
4234         NTSTATUS status;
4235         struct samr_OpenDomain r;
4236         struct policy_handle domain_handle;
4237         struct policy_handle alias_handle;
4238         struct policy_handle user_handle;
4239         struct policy_handle group_handle;
4240         bool ret = true;
4241
4242         ZERO_STRUCT(alias_handle);
4243         ZERO_STRUCT(user_handle);
4244         ZERO_STRUCT(group_handle);
4245         ZERO_STRUCT(domain_handle);
4246
4247         printf("Testing OpenDomain\n");
4248
4249         r.in.connect_handle = handle;
4250         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4251         r.in.sid = sid;
4252         r.out.domain_handle = &domain_handle;
4253
4254         status = dcerpc_samr_OpenDomain(p, tctx, &r);
4255         if (!NT_STATUS_IS_OK(status)) {
4256                 printf("OpenDomain failed - %s\n", nt_errstr(status));
4257                 return false;
4258         }
4259
4260         /* run the domain tests with the main handle closed - this tests
4261            the servers reference counting */
4262         ret &= test_samr_handle_Close(p, tctx, handle);
4263
4264         switch (which_ops) {
4265         case TORTURE_SAMR_USER_ATTRIBUTES:
4266         case TORTURE_SAMR_PASSWORDS:
4267                 ret &= test_CreateUser2(p, tctx, &domain_handle, which_ops);
4268                 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, which_ops);
4269                 /* This test needs 'complex' users to validate */
4270                 ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
4271                 break;
4272         case TORTURE_SAMR_OTHER:
4273                 ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, which_ops);
4274                 ret &= test_QuerySecurity(p, tctx, &domain_handle);
4275                 ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
4276                 ret &= test_CreateAlias(p, tctx, &domain_handle, &alias_handle, sid);
4277                 ret &= test_CreateDomainGroup(p, tctx, &domain_handle, &group_handle);
4278                 ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
4279                 ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
4280                 ret &= test_EnumDomainUsers(p, tctx, &domain_handle);
4281                 ret &= test_EnumDomainUsers_async(p, tctx, &domain_handle);
4282                 ret &= test_EnumDomainGroups(p, tctx, &domain_handle);
4283                 ret &= test_EnumDomainAliases(p, tctx, &domain_handle);
4284                 ret &= test_QueryDisplayInfo2(p, tctx, &domain_handle);
4285                 ret &= test_QueryDisplayInfo3(p, tctx, &domain_handle);
4286                 ret &= test_QueryDisplayInfo_continue(p, tctx, &domain_handle);
4287                 
4288                 if (torture_setting_bool(tctx, "samba4", false)) {
4289                         printf("skipping GetDisplayEnumerationIndex test against Samba4\n");
4290                 } else {
4291                         ret &= test_GetDisplayEnumerationIndex(p, tctx, &domain_handle);
4292                         ret &= test_GetDisplayEnumerationIndex2(p, tctx, &domain_handle);
4293                 }
4294                 ret &= test_GroupList(p, tctx, &domain_handle);
4295                 ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
4296                 ret &= test_RidToSid(p, tctx, sid, &domain_handle);
4297                 ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
4298                 break;
4299         }
4300
4301         if (!policy_handle_empty(&user_handle) &&
4302             !test_DeleteUser(p, tctx, &user_handle)) {
4303                 ret = false;
4304         }
4305
4306         if (!policy_handle_empty(&alias_handle) &&
4307             !test_DeleteAlias(p, tctx, &alias_handle)) {
4308                 ret = false;
4309         }
4310
4311         if (!policy_handle_empty(&group_handle) &&
4312             !test_DeleteDomainGroup(p, tctx, &group_handle)) {
4313                 ret = false;
4314         }
4315
4316         ret &= test_samr_handle_Close(p, tctx, &domain_handle);
4317
4318         /* reconnect the main handle */
4319         ret &= test_Connect(p, tctx, handle);
4320
4321         if (!ret) {
4322                 printf("Testing domain %s failed!\n", dom_sid_string(tctx, sid));
4323         }
4324
4325         return ret;
4326 }
4327
4328 static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
4329                               struct policy_handle *handle, const char *domain,
4330                               enum torture_samr_choice which_ops)
4331 {
4332         NTSTATUS status;
4333         struct samr_LookupDomain r;
4334         struct lsa_String n1;
4335         struct lsa_String n2;
4336         bool ret = true;
4337
4338         printf("Testing LookupDomain(%s)\n", domain);
4339
4340         /* check for correct error codes */
4341         r.in.connect_handle = handle;
4342         r.in.domain_name = &n2;
4343         n2.string = NULL;
4344
4345         status = dcerpc_samr_LookupDomain(p, tctx, &r);
4346         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_PARAMETER, status)) {
4347                 printf("failed: LookupDomain expected NT_STATUS_INVALID_PARAMETER - %s\n", nt_errstr(status));
4348                 ret = false;
4349         }
4350
4351         init_lsa_String(&n2, "xxNODOMAINxx");
4352
4353         status = dcerpc_samr_LookupDomain(p, tctx, &r);
4354         if (!NT_STATUS_EQUAL(NT_STATUS_NO_SUCH_DOMAIN, status)) {
4355                 printf("failed: LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN - %s\n", nt_errstr(status));
4356                 ret = false;
4357         }
4358
4359         r.in.connect_handle = handle;
4360
4361         init_lsa_String(&n1, domain);
4362         r.in.domain_name = &n1;
4363
4364         status = dcerpc_samr_LookupDomain(p, tctx, &r);
4365         if (!NT_STATUS_IS_OK(status)) {
4366                 printf("LookupDomain failed - %s\n", nt_errstr(status));
4367                 ret = false;
4368         }
4369
4370         if (!test_GetDomPwInfo(p, tctx, &n1)) {
4371                 ret = false;
4372         }
4373
4374         if (!test_OpenDomain(p, tctx, handle, r.out.sid, which_ops)) {
4375                 ret = false;
4376         }
4377
4378         return ret;
4379 }
4380
4381
4382 static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx,
4383                              struct policy_handle *handle, enum torture_samr_choice which_ops)
4384 {
4385         NTSTATUS status;
4386         struct samr_EnumDomains r;
4387         uint32_t resume_handle = 0;
4388         int i;
4389         bool ret = true;
4390
4391         r.in.connect_handle = handle;
4392         r.in.resume_handle = &resume_handle;
4393         r.in.buf_size = (uint32_t)-1;
4394         r.out.resume_handle = &resume_handle;
4395
4396         status = dcerpc_samr_EnumDomains(p, tctx, &r);
4397         if (!NT_STATUS_IS_OK(status)) {
4398                 printf("EnumDomains failed - %s\n", nt_errstr(status));
4399                 return false;
4400         }
4401
4402         if (!r.out.sam) {
4403                 return false;
4404         }
4405
4406         for (i=0;i<r.out.sam->count;i++) {
4407                 if (!test_LookupDomain(p, tctx, handle, 
4408                                        r.out.sam->entries[i].name.string, which_ops)) {
4409                         ret = false;
4410                 }
4411         }
4412
4413         status = dcerpc_samr_EnumDomains(p, tctx, &r);
4414         if (!NT_STATUS_IS_OK(status)) {
4415                 printf("EnumDomains failed - %s\n", nt_errstr(status));
4416                 return false;
4417         }
4418
4419         return ret;
4420 }
4421
4422
4423 static bool test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
4424                          struct policy_handle *handle)
4425 {
4426         NTSTATUS status;
4427         struct samr_Connect r;
4428         struct samr_Connect2 r2;
4429         struct samr_Connect3 r3;
4430         struct samr_Connect4 r4;
4431         struct samr_Connect5 r5;
4432         union samr_ConnectInfo info;
4433         struct policy_handle h;
4434         bool ret = true, got_handle = false;
4435
4436         printf("testing samr_Connect\n");
4437
4438         r.in.system_name = 0;
4439         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4440         r.out.connect_handle = &h;
4441
4442         status = dcerpc_samr_Connect(p, mem_ctx, &r);
4443         if (!NT_STATUS_IS_OK(status)) {
4444                 printf("Connect failed - %s\n", nt_errstr(status));
4445                 ret = false;
4446         } else {
4447                 got_handle = true;
4448                 *handle = h;
4449         }
4450
4451         printf("testing samr_Connect2\n");
4452
4453         r2.in.system_name = NULL;
4454         r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4455         r2.out.connect_handle = &h;
4456
4457         status = dcerpc_samr_Connect2(p, mem_ctx, &r2);
4458         if (!NT_STATUS_IS_OK(status)) {
4459                 printf("Connect2 failed - %s\n", nt_errstr(status));
4460                 ret = false;
4461         } else {
4462                 if (got_handle) {
4463                         test_samr_handle_Close(p, mem_ctx, handle);
4464                 }
4465                 got_handle = true;
4466                 *handle = h;
4467         }
4468
4469         printf("testing samr_Connect3\n");
4470
4471         r3.in.system_name = NULL;
4472         r3.in.unknown = 0;
4473         r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4474         r3.out.connect_handle = &h;
4475
4476         status = dcerpc_samr_Connect3(p, mem_ctx, &r3);
4477         if (!NT_STATUS_IS_OK(status)) {
4478                 printf("Connect3 failed - %s\n", nt_errstr(status));
4479                 ret = false;
4480         } else {
4481                 if (got_handle) {
4482                         test_samr_handle_Close(p, mem_ctx, handle);
4483                 }
4484                 got_handle = true;
4485                 *handle = h;
4486         }
4487
4488         printf("testing samr_Connect4\n");
4489
4490         r4.in.system_name = "";
4491         r4.in.unknown = 0;
4492         r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4493         r4.out.connect_handle = &h;
4494
4495         status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
4496         if (!NT_STATUS_IS_OK(status)) {
4497                 printf("Connect4 failed - %s\n", nt_errstr(status));
4498                 ret = false;
4499         } else {
4500                 if (got_handle) {
4501                         test_samr_handle_Close(p, mem_ctx, handle);
4502                 }
4503                 got_handle = true;
4504                 *handle = h;
4505         }
4506
4507         printf("testing samr_Connect5\n");
4508
4509         info.info1.unknown1 = 0;
4510         info.info1.unknown2 = 0;
4511
4512         r5.in.system_name = "";
4513         r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4514         r5.in.level = 1;
4515         r5.in.info = &info;
4516         r5.out.info = &info;
4517         r5.out.connect_handle = &h;
4518
4519         status = dcerpc_samr_Connect5(p, mem_ctx, &r5);
4520         if (!NT_STATUS_IS_OK(status)) {
4521                 printf("Connect5 failed - %s\n", nt_errstr(status));
4522                 ret = false;
4523         } else {
4524                 if (got_handle) {
4525                         test_samr_handle_Close(p, mem_ctx, handle);
4526                 }
4527                 got_handle = true;
4528                 *handle = h;
4529         }
4530
4531         return ret;
4532 }
4533
4534
4535 bool torture_rpc_samr(struct torture_context *torture)
4536 {
4537         NTSTATUS status;
4538         struct dcerpc_pipe *p;
4539         bool ret = true;
4540         struct policy_handle handle;
4541
4542         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4543         if (!NT_STATUS_IS_OK(status)) {
4544                 return false;
4545         }
4546
4547         ret &= test_Connect(p, torture, &handle);
4548
4549         ret &= test_QuerySecurity(p, torture, &handle);
4550
4551         ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_OTHER);
4552
4553         ret &= test_SetDsrmPassword(p, torture, &handle);
4554
4555         ret &= test_Shutdown(p, torture, &handle);
4556
4557         ret &= test_samr_handle_Close(p, torture, &handle);
4558
4559         return ret;
4560 }
4561
4562
4563 bool torture_rpc_samr_users(struct torture_context *torture)
4564 {
4565         NTSTATUS status;
4566         struct dcerpc_pipe *p;
4567         bool ret = true;
4568         struct policy_handle handle;
4569
4570         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4571         if (!NT_STATUS_IS_OK(status)) {
4572                 return false;
4573         }
4574
4575         ret &= test_Connect(p, torture, &handle);
4576
4577         ret &= test_QuerySecurity(p, torture, &handle);
4578
4579         ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_USER_ATTRIBUTES);
4580
4581         ret &= test_SetDsrmPassword(p, torture, &handle);
4582
4583         ret &= test_Shutdown(p, torture, &handle);
4584
4585         ret &= test_samr_handle_Close(p, torture, &handle);
4586
4587         return ret;
4588 }
4589
4590
4591 bool torture_rpc_samr_passwords(struct torture_context *torture)
4592 {
4593         NTSTATUS status;
4594         struct dcerpc_pipe *p;
4595         bool ret = true;
4596         struct policy_handle handle;
4597
4598         status = torture_rpc_connection(torture, &p, &ndr_table_samr);
4599         if (!NT_STATUS_IS_OK(status)) {
4600                 return false;
4601         }
4602
4603         ret &= test_Connect(p, torture, &handle);
4604
4605         ret &= test_EnumDomains(p, torture, &handle, TORTURE_SAMR_PASSWORDS);
4606
4607         ret &= test_samr_handle_Close(p, torture, &handle);
4608
4609         return ret;
4610 }
4611