r14363: Remove credentials.h from the global includes.
[samba.git] / source4 / torture / rpc / samr.c
1 /* 
2    Unix SMB/CIFS implementation.
3    test suite for samr rpc operations
4
5    Copyright (C) Andrew Tridgell 2003
6    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
7    
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 2 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, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "includes.h"
24 #include "torture/torture.h"
25 #include "librpc/gen_ndr/ndr_lsa.h"
26 #include "librpc/gen_ndr/ndr_samr.h"
27 #include "smb.h"
28 #include "lib/crypto/crypto.h"
29 #include "auth/credentials/credentials.h"
30 #include "libcli/auth/proto.h"
31 #include "libcli/security/proto.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
40 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
41                                struct policy_handle *handle);
42
43 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
44                                 struct policy_handle *handle);
45
46 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
47                                struct policy_handle *handle);
48
49 static void init_lsa_String(struct lsa_String *string, const char *s)
50 {
51         string->string = s;
52 }
53
54 BOOL test_samr_handle_Close(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
55                                    struct policy_handle *handle)
56 {
57         NTSTATUS status;
58         struct samr_Close r;
59
60         r.in.handle = handle;
61         r.out.handle = handle;
62
63         status = dcerpc_samr_Close(p, mem_ctx, &r);
64         if (!NT_STATUS_IS_OK(status)) {
65                 printf("Close handle failed - %s\n", nt_errstr(status));
66                 return False;
67         }
68
69         return True;
70 }
71
72 static BOOL test_Shutdown(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
73                        struct policy_handle *handle)
74 {
75         NTSTATUS status;
76         struct samr_Shutdown r;
77
78         if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
79                 printf("samr_Shutdown disabled - enable dangerous tests to use\n");
80                 return True;
81         }
82
83         r.in.connect_handle = handle;
84
85         printf("testing samr_Shutdown\n");
86
87         status = dcerpc_samr_Shutdown(p, mem_ctx, &r);
88         if (!NT_STATUS_IS_OK(status)) {
89                 printf("samr_Shutdown failed - %s\n", nt_errstr(status));
90                 return False;
91         }
92
93         return True;
94 }
95
96 static BOOL test_SetDsrmPassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
97                                  struct policy_handle *handle)
98 {
99         NTSTATUS status;
100         struct samr_SetDsrmPassword r;
101         struct lsa_String string;
102         struct samr_Password hash;
103
104         if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
105                 printf("samr_SetDsrmPassword disabled - enable dangerous tests to use\n");
106                 return True;
107         }
108
109         E_md4hash("TeSTDSRM123", hash.hash);
110
111         init_lsa_String(&string, "Administrator");
112
113         r.in.name = &string;
114         r.in.unknown = 0;
115         r.in.hash = &hash;
116
117         printf("testing samr_SetDsrmPassword\n");
118
119         status = dcerpc_samr_SetDsrmPassword(p, mem_ctx, &r);
120         if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
121                 printf("samr_SetDsrmPassword failed - %s\n", nt_errstr(status));
122                 return False;
123         }
124
125         return True;
126 }
127
128
129 static BOOL test_QuerySecurity(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
130                                struct policy_handle *handle)
131 {
132         NTSTATUS status;
133         struct samr_QuerySecurity r;
134         struct samr_SetSecurity s;
135
136         r.in.handle = handle;
137         r.in.sec_info = 7;
138
139         status = dcerpc_samr_QuerySecurity(p, mem_ctx, &r);
140         if (!NT_STATUS_IS_OK(status)) {
141                 printf("QuerySecurity failed - %s\n", nt_errstr(status));
142                 return False;
143         }
144
145         if (r.out.sdbuf == NULL) {
146                 return False;
147         }
148
149         s.in.handle = handle;
150         s.in.sec_info = 7;
151         s.in.sdbuf = r.out.sdbuf;
152
153         status = dcerpc_samr_SetSecurity(p, mem_ctx, &s);
154         if (!NT_STATUS_IS_OK(status)) {
155                 printf("SetSecurity failed - %s\n", nt_errstr(status));
156                 return False;
157         }
158
159         status = dcerpc_samr_QuerySecurity(p, mem_ctx, &r);
160         if (!NT_STATUS_IS_OK(status)) {
161                 printf("QuerySecurity failed - %s\n", nt_errstr(status));
162                 return False;
163         }
164
165         return True;
166 }
167
168
169 static BOOL test_SetUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
170                              struct policy_handle *handle, uint32_t base_acct_flags,
171                              const char *base_account_name)
172 {
173         NTSTATUS status;
174         struct samr_SetUserInfo s;
175         struct samr_SetUserInfo2 s2;
176         struct samr_QueryUserInfo q;
177         struct samr_QueryUserInfo q0;
178         union samr_UserInfo u;
179         BOOL ret = True;
180         const char *test_account_name;
181
182         uint32_t user_extra_flags = 0;
183         if (base_acct_flags == ACB_NORMAL) {
184                 /* When created, accounts are expired by default */
185                 user_extra_flags = ACB_PW_EXPIRED;
186         }
187
188         s.in.user_handle = handle;
189         s.in.info = &u;
190
191         s2.in.user_handle = handle;
192         s2.in.info = &u;
193
194         q.in.user_handle = handle;
195         q.out.info = &u;
196         q0 = q;
197
198 #define TESTCALL(call, r) \
199                 status = dcerpc_samr_ ##call(p, mem_ctx, &r); \
200                 if (!NT_STATUS_IS_OK(status)) { \
201                         printf(#call " level %u failed - %s (%s)\n", \
202                                r.in.level, nt_errstr(status), __location__); \
203                         ret = False; \
204                         break; \
205                 }
206
207 #define STRING_EQUAL(s1, s2, field) \
208                 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
209                         printf("Failed to set %s to '%s' (%s)\n", \
210                                #field, s2, __location__); \
211                         ret = False; \
212                         break; \
213                 }
214
215 #define INT_EQUAL(i1, i2, field) \
216                 if (i1 != i2) { \
217                         printf("Failed to set %s to 0x%x - got 0x%x (%s)\n", \
218                                #field, i2, i1, __location__); \
219                         ret = False; \
220                         break; \
221                 }
222
223 #define TEST_USERINFO_STRING(lvl1, field1, lvl2, field2, value, fpval) do { \
224                 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
225                 q.in.level = lvl1; \
226                 TESTCALL(QueryUserInfo, q) \
227                 s.in.level = lvl1; \
228                 s2.in.level = lvl1; \
229                 u = *q.out.info; \
230                 if (lvl1 == 21) { \
231                         ZERO_STRUCT(u.info21); \
232                         u.info21.fields_present = fpval; \
233                 } \
234                 init_lsa_String(&u.info ## lvl1.field1, value); \
235                 TESTCALL(SetUserInfo, s) \
236                 TESTCALL(SetUserInfo2, s2) \
237                 init_lsa_String(&u.info ## lvl1.field1, ""); \
238                 TESTCALL(QueryUserInfo, q); \
239                 u = *q.out.info; \
240                 STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
241                 q.in.level = lvl2; \
242                 TESTCALL(QueryUserInfo, q) \
243                 u = *q.out.info; \
244                 STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
245         } while (0)
246
247 #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
248                 printf("field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
249                 q.in.level = lvl1; \
250                 TESTCALL(QueryUserInfo, q) \
251                 s.in.level = lvl1; \
252                 s2.in.level = lvl1; \
253                 u = *q.out.info; \
254                 if (lvl1 == 21) { \
255                         uint8_t *bits = u.info21.logon_hours.bits; \
256                         ZERO_STRUCT(u.info21); \
257                         if (fpval == SAMR_FIELD_LOGON_HOURS) { \
258                                 u.info21.logon_hours.units_per_week = 168; \
259                                 u.info21.logon_hours.bits = bits; \
260                         } \
261                         u.info21.fields_present = fpval; \
262                 } \
263                 u.info ## lvl1.field1 = value; \
264                 TESTCALL(SetUserInfo, s) \
265                 TESTCALL(SetUserInfo2, s2) \
266                 u.info ## lvl1.field1 = 0; \
267                 TESTCALL(QueryUserInfo, q); \
268                 u = *q.out.info; \
269                 INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
270                 q.in.level = lvl2; \
271                 TESTCALL(QueryUserInfo, q) \
272                 u = *q.out.info; \
273                 INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
274         } while (0)
275
276 #define TEST_USERINFO_INT(lvl1, field1, lvl2, field2, value, fpval) do { \
277         TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value, fpval); \
278         } while (0)
279
280         q0.in.level = 12;
281         do { TESTCALL(QueryUserInfo, q0) } while (0);
282
283         TEST_USERINFO_STRING(2, comment,  1, comment, "xx2-1 comment", 0);
284         TEST_USERINFO_STRING(2, comment, 21, comment, "xx2-21 comment", 0);
285         TEST_USERINFO_STRING(21, comment, 21, comment, "xx21-21 comment", 
286                            SAMR_FIELD_COMMENT);
287
288         test_account_name = talloc_asprintf(mem_ctx, "%sxx7-1", base_account_name);
289         TEST_USERINFO_STRING(7, account_name,  1, account_name, base_account_name, 0);
290         test_account_name = talloc_asprintf(mem_ctx, "%sxx7-3", base_account_name);
291         TEST_USERINFO_STRING(7, account_name,  3, account_name, base_account_name, 0);
292         test_account_name = talloc_asprintf(mem_ctx, "%sxx7-5", base_account_name);
293         TEST_USERINFO_STRING(7, account_name,  5, account_name, base_account_name, 0);
294         test_account_name = talloc_asprintf(mem_ctx, "%sxx7-6", base_account_name);
295         TEST_USERINFO_STRING(7, account_name,  6, account_name, base_account_name, 0);
296         test_account_name = talloc_asprintf(mem_ctx, "%sxx7-7", base_account_name);
297         TEST_USERINFO_STRING(7, account_name,  7, account_name, base_account_name, 0);
298         test_account_name = talloc_asprintf(mem_ctx, "%sxx7-21", base_account_name);
299         TEST_USERINFO_STRING(7, account_name, 21, account_name, base_account_name, 0);
300         test_account_name = base_account_name;
301         TEST_USERINFO_STRING(21, account_name, 21, account_name, base_account_name, 
302                            SAMR_FIELD_ACCOUNT_NAME);
303
304         TEST_USERINFO_STRING(6, full_name,  1, full_name, "xx6-1 full_name", 0);
305         TEST_USERINFO_STRING(6, full_name,  3, full_name, "xx6-3 full_name", 0);
306         TEST_USERINFO_STRING(6, full_name,  5, full_name, "xx6-5 full_name", 0);
307         TEST_USERINFO_STRING(6, full_name,  6, full_name, "xx6-6 full_name", 0);
308         TEST_USERINFO_STRING(6, full_name,  8, full_name, "xx6-8 full_name", 0);
309         TEST_USERINFO_STRING(6, full_name, 21, full_name, "xx6-21 full_name", 0);
310         TEST_USERINFO_STRING(8, full_name, 21, full_name, "xx8-21 full_name", 0);
311         TEST_USERINFO_STRING(21, full_name, 21, full_name, "xx21-21 full_name", 
312                            SAMR_FIELD_FULL_NAME);
313
314         TEST_USERINFO_STRING(11, logon_script, 3, logon_script, "xx11-3 logon_script", 0);
315         TEST_USERINFO_STRING(11, logon_script, 5, logon_script, "xx11-5 logon_script", 0);
316         TEST_USERINFO_STRING(11, logon_script, 21, logon_script, "xx11-21 logon_script", 0);
317         TEST_USERINFO_STRING(21, logon_script, 21, logon_script, "xx21-21 logon_script", 
318                            SAMR_FIELD_LOGON_SCRIPT);
319
320         TEST_USERINFO_STRING(12, profile_path,  3, profile_path, "xx12-3 profile_path", 0);
321         TEST_USERINFO_STRING(12, profile_path,  5, profile_path, "xx12-5 profile_path", 0);
322         TEST_USERINFO_STRING(12, profile_path, 21, profile_path, "xx12-21 profile_path", 0);
323         TEST_USERINFO_STRING(21, profile_path, 21, profile_path, "xx21-21 profile_path", 
324                            SAMR_FIELD_PROFILE_PATH);
325
326         TEST_USERINFO_STRING(13, description,  1, description, "xx13-1 description", 0);
327         TEST_USERINFO_STRING(13, description,  5, description, "xx13-5 description", 0);
328         TEST_USERINFO_STRING(13, description, 21, description, "xx13-21 description", 0);
329         TEST_USERINFO_STRING(21, description, 21, description, "xx21-21 description", 
330                            SAMR_FIELD_DESCRIPTION);
331
332         TEST_USERINFO_STRING(14, workstations,  3, workstations, "14workstation3", 0);
333         TEST_USERINFO_STRING(14, workstations,  5, workstations, "14workstation4", 0);
334         TEST_USERINFO_STRING(14, workstations, 21, workstations, "14workstation21", 0);
335         TEST_USERINFO_STRING(21, workstations, 21, workstations, "21workstation21", 
336                            SAMR_FIELD_WORKSTATIONS);
337
338         TEST_USERINFO_STRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
339         TEST_USERINFO_STRING(21, parameters, 21, parameters, "xx21-21 parameters", 
340                            SAMR_FIELD_PARAMETERS);
341
342         TEST_USERINFO_INT(2, country_code, 21, country_code, __LINE__, 0);
343         TEST_USERINFO_INT(21, country_code, 21, country_code, __LINE__, 
344                           SAMR_FIELD_COUNTRY_CODE);
345
346         TEST_USERINFO_INT(2, code_page, 21, code_page, __LINE__, 0);
347         TEST_USERINFO_INT(21, code_page, 21, code_page, __LINE__, 
348                           SAMR_FIELD_CODE_PAGE);
349
350         TEST_USERINFO_INT(4, logon_hours.bits[3],  3, logon_hours.bits[3], 1, 0);
351         TEST_USERINFO_INT(4, logon_hours.bits[3],  5, logon_hours.bits[3], 2, 0);
352         TEST_USERINFO_INT(4, logon_hours.bits[3], 21, logon_hours.bits[3], 3, 0);
353         TEST_USERINFO_INT(21, logon_hours.bits[3], 21, logon_hours.bits[3], 4, 
354                           SAMR_FIELD_LOGON_HOURS);
355
356         TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags, 
357                           (base_acct_flags  | ACB_DISABLED | ACB_HOMDIRREQ), 
358                           (base_acct_flags  | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags), 
359                           0);
360         TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags, 
361                           (base_acct_flags  | ACB_DISABLED), 
362                           (base_acct_flags  | ACB_DISABLED | user_extra_flags), 
363                           0);
364         
365         /* Setting PWNOEXP clears the magic ACB_PW_EXPIRED flag */
366         TEST_USERINFO_INT_EXP(16, acct_flags, 5, acct_flags, 
367                           (base_acct_flags  | ACB_DISABLED | ACB_PWNOEXP), 
368                           (base_acct_flags  | ACB_DISABLED | ACB_PWNOEXP), 
369                           0);
370         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
371                           (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ), 
372                           (base_acct_flags | ACB_DISABLED | ACB_HOMDIRREQ | user_extra_flags), 
373                           0);
374
375         /* The 'autolock' flag doesn't stick - check this */
376         TEST_USERINFO_INT_EXP(16, acct_flags, 21, acct_flags, 
377                           (base_acct_flags | ACB_DISABLED | ACB_AUTOLOCK), 
378                           (base_acct_flags | ACB_DISABLED | user_extra_flags), 
379                           0);
380         TEST_USERINFO_INT_EXP(21, acct_flags, 21, acct_flags, 
381                           (base_acct_flags | ACB_DISABLED), 
382                           (base_acct_flags | ACB_DISABLED | user_extra_flags), 
383                           SAMR_FIELD_ACCT_FLAGS);
384
385 #if 0
386         /* these fail with win2003 - it appears you can't set the primary gid?
387            the set succeeds, but the gid isn't changed. Very weird! */
388         TEST_USERINFO_INT(9, primary_gid,  1, primary_gid, 513);
389         TEST_USERINFO_INT(9, primary_gid,  3, primary_gid, 513);
390         TEST_USERINFO_INT(9, primary_gid,  5, primary_gid, 513);
391         TEST_USERINFO_INT(9, primary_gid, 21, primary_gid, 513);
392 #endif
393
394         return ret;
395 }
396
397 /*
398   generate a random password for password change tests
399 */
400 static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
401 {
402         size_t len = MAX(8, min_len) + (random() % 6);
403         char *s = generate_random_str(mem_ctx, len);
404         printf("Generated password '%s'\n", s);
405         return s;
406 }
407
408 static BOOL test_SetUserPass(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
409                              struct policy_handle *handle, char **password)
410 {
411         NTSTATUS status;
412         struct samr_SetUserInfo s;
413         union samr_UserInfo u;
414         BOOL ret = True;
415         DATA_BLOB session_key;
416         char *newpass;
417         struct samr_GetUserPwInfo pwp;
418         int policy_min_pw_len = 0;
419         pwp.in.user_handle = handle;
420
421         status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
422         if (NT_STATUS_IS_OK(status)) {
423                 policy_min_pw_len = pwp.out.info.min_password_length;
424         }
425         newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
426
427         s.in.user_handle = handle;
428         s.in.info = &u;
429         s.in.level = 24;
430
431         encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
432         /* w2k3 ignores this length */
433         u.info24.pw_len = strlen_m(newpass) * 2;
434
435         status = dcerpc_fetch_session_key(p, &session_key);
436         if (!NT_STATUS_IS_OK(status)) {
437                 printf("SetUserInfo level %u - no session key - %s\n",
438                        s.in.level, nt_errstr(status));
439                 return False;
440         }
441
442         arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
443
444         printf("Testing SetUserInfo level 24 (set password)\n");
445
446         status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
447         if (!NT_STATUS_IS_OK(status)) {
448                 printf("SetUserInfo level %u failed - %s\n",
449                        s.in.level, nt_errstr(status));
450                 ret = False;
451         } else {
452                 *password = newpass;
453         }
454
455         return ret;
456 }
457
458
459 static BOOL test_SetUserPass_23(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
460                                 struct policy_handle *handle, uint32_t fields_present,
461                                 char **password)
462 {
463         NTSTATUS status;
464         struct samr_SetUserInfo s;
465         union samr_UserInfo u;
466         BOOL ret = True;
467         DATA_BLOB session_key;
468         char *newpass;
469         struct samr_GetUserPwInfo pwp;
470         int policy_min_pw_len = 0;
471         pwp.in.user_handle = handle;
472
473         status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
474         if (NT_STATUS_IS_OK(status)) {
475                 policy_min_pw_len = pwp.out.info.min_password_length;
476         }
477         newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
478
479         s.in.user_handle = handle;
480         s.in.info = &u;
481         s.in.level = 23;
482
483         ZERO_STRUCT(u);
484
485         u.info23.info.fields_present = fields_present;
486
487         encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
488
489         status = dcerpc_fetch_session_key(p, &session_key);
490         if (!NT_STATUS_IS_OK(status)) {
491                 printf("SetUserInfo level %u - no session key - %s\n",
492                        s.in.level, nt_errstr(status));
493                 return False;
494         }
495
496         arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
497
498         printf("Testing SetUserInfo level 23 (set password)\n");
499
500         status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
501         if (!NT_STATUS_IS_OK(status)) {
502                 printf("SetUserInfo level %u failed - %s\n",
503                        s.in.level, nt_errstr(status));
504                 ret = False;
505         } else {
506                 *password = newpass;
507         }
508
509         return ret;
510 }
511
512
513 static BOOL test_SetUserPassEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
514                                struct policy_handle *handle, char **password)
515 {
516         NTSTATUS status;
517         struct samr_SetUserInfo s;
518         union samr_UserInfo u;
519         BOOL ret = True;
520         DATA_BLOB session_key;
521         DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
522         uint8_t confounder[16];
523         char *newpass;
524         struct MD5Context ctx;
525         struct samr_GetUserPwInfo pwp;
526         int policy_min_pw_len = 0;
527         pwp.in.user_handle = handle;
528
529         status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
530         if (NT_STATUS_IS_OK(status)) {
531                 policy_min_pw_len = pwp.out.info.min_password_length;
532         }
533         newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
534
535         s.in.user_handle = handle;
536         s.in.info = &u;
537         s.in.level = 26;
538
539         encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
540         u.info26.pw_len = strlen(newpass);
541
542         status = dcerpc_fetch_session_key(p, &session_key);
543         if (!NT_STATUS_IS_OK(status)) {
544                 printf("SetUserInfo level %u - no session key - %s\n",
545                        s.in.level, nt_errstr(status));
546                 return False;
547         }
548
549         generate_random_buffer((uint8_t *)confounder, 16);
550
551         MD5Init(&ctx);
552         MD5Update(&ctx, confounder, 16);
553         MD5Update(&ctx, session_key.data, session_key.length);
554         MD5Final(confounded_session_key.data, &ctx);
555
556         arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
557         memcpy(&u.info26.password.data[516], confounder, 16);
558
559         printf("Testing SetUserInfo level 26 (set password ex)\n");
560
561         status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
562         if (!NT_STATUS_IS_OK(status)) {
563                 printf("SetUserInfo level %u failed - %s\n",
564                        s.in.level, nt_errstr(status));
565                 ret = False;
566         } else {
567                 *password = newpass;
568         }
569
570         return ret;
571 }
572
573 static BOOL test_SetUserPass_25(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
574                                 struct policy_handle *handle, uint32_t fields_present,
575                                 char **password)
576 {
577         NTSTATUS status;
578         struct samr_SetUserInfo s;
579         union samr_UserInfo u;
580         BOOL ret = True;
581         DATA_BLOB session_key;
582         DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
583         struct MD5Context ctx;
584         uint8_t confounder[16];
585         char *newpass;
586         struct samr_GetUserPwInfo pwp;
587         int policy_min_pw_len = 0;
588         pwp.in.user_handle = handle;
589
590         status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
591         if (NT_STATUS_IS_OK(status)) {
592                 policy_min_pw_len = pwp.out.info.min_password_length;
593         }
594         newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
595
596         s.in.user_handle = handle;
597         s.in.info = &u;
598         s.in.level = 25;
599
600         ZERO_STRUCT(u);
601
602         u.info25.info.fields_present = fields_present;
603
604         encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
605
606         status = dcerpc_fetch_session_key(p, &session_key);
607         if (!NT_STATUS_IS_OK(status)) {
608                 printf("SetUserInfo level %u - no session key - %s\n",
609                        s.in.level, nt_errstr(status));
610                 return False;
611         }
612
613         generate_random_buffer((uint8_t *)confounder, 16);
614
615         MD5Init(&ctx);
616         MD5Update(&ctx, confounder, 16);
617         MD5Update(&ctx, session_key.data, session_key.length);
618         MD5Final(confounded_session_key.data, &ctx);
619
620         arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
621         memcpy(&u.info25.password.data[516], confounder, 16);
622
623         printf("Testing SetUserInfo level 25 (set password ex)\n");
624
625         status = dcerpc_samr_SetUserInfo(p, mem_ctx, &s);
626         if (!NT_STATUS_IS_OK(status)) {
627                 printf("SetUserInfo level %u failed - %s\n",
628                        s.in.level, nt_errstr(status));
629                 ret = False;
630         } else {
631                 *password = newpass;
632         }
633
634         return ret;
635 }
636
637 static BOOL test_SetAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
638                                struct policy_handle *handle)
639 {
640         NTSTATUS status;
641         struct samr_SetAliasInfo r;
642         struct samr_QueryAliasInfo q;
643         uint16_t levels[] = {2, 3};
644         int i;
645         BOOL ret = True;
646
647         /* Ignoring switch level 1, as that includes the number of members for the alias
648          * and setting this to a wrong value might have negative consequences
649          */
650
651         for (i=0;i<ARRAY_SIZE(levels);i++) {
652                 printf("Testing SetAliasInfo level %u\n", levels[i]);
653
654                 r.in.alias_handle = handle;
655                 r.in.level = levels[i];
656                 r.in.info  = talloc(mem_ctx, union samr_AliasInfo);
657                 switch (r.in.level) {
658                     case ALIASINFONAME: init_lsa_String(&r.in.info->name,TEST_ALIASNAME); break;
659                     case ALIASINFODESCRIPTION: init_lsa_String(&r.in.info->description,
660                                 "Test Description, should test I18N as well"); break;
661                 }
662
663                 status = dcerpc_samr_SetAliasInfo(p, mem_ctx, &r);
664                 if (!NT_STATUS_IS_OK(status)) {
665                         printf("SetAliasInfo level %u failed - %s\n",
666                                levels[i], nt_errstr(status));
667                         ret = False;
668                 }
669
670                 q.in.alias_handle = handle;
671                 q.in.level = levels[i];
672
673                 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &q);
674                 if (!NT_STATUS_IS_OK(status)) {
675                         printf("QueryAliasInfo level %u failed - %s\n",
676                                levels[i], nt_errstr(status));
677                         ret = False;
678                 }
679         }
680
681         return ret;
682 }
683
684 static BOOL test_GetGroupsForUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
685                                   struct policy_handle *user_handle)
686 {
687         struct samr_GetGroupsForUser r;
688         NTSTATUS status;
689         BOOL ret = True;
690
691         printf("testing GetGroupsForUser\n");
692
693         r.in.user_handle = user_handle;
694
695         status = dcerpc_samr_GetGroupsForUser(p, mem_ctx, &r);
696         if (!NT_STATUS_IS_OK(status)) {
697                 printf("GetGroupsForUser failed - %s\n",nt_errstr(status));
698                 ret = False;
699         }
700
701         return ret;
702
703 }
704
705 static BOOL test_GetDomPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
706                               struct lsa_String *domain_name)
707 {
708         NTSTATUS status;
709         struct samr_GetDomPwInfo r;
710         BOOL ret = True;
711
712         r.in.domain_name = domain_name;
713         printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
714
715         status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
716         if (!NT_STATUS_IS_OK(status)) {
717                 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
718                 ret = False;
719         }
720
721         r.in.domain_name->string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
722         printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
723
724         status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
725         if (!NT_STATUS_IS_OK(status)) {
726                 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
727                 ret = False;
728         }
729
730         r.in.domain_name->string = "\\\\__NONAME__";
731         printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
732
733         status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
734         if (!NT_STATUS_IS_OK(status)) {
735                 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
736                 ret = False;
737         }
738
739         r.in.domain_name->string = "\\\\Builtin";
740         printf("Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
741
742         status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &r);
743         if (!NT_STATUS_IS_OK(status)) {
744                 printf("GetDomPwInfo failed - %s\n", nt_errstr(status));
745                 ret = False;
746         }
747
748
749         return ret;
750 }
751
752 static BOOL test_GetUserPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
753                                struct policy_handle *handle)
754 {
755         NTSTATUS status;
756         struct samr_GetUserPwInfo r;
757         BOOL ret = True;
758
759         printf("Testing GetUserPwInfo\n");
760
761         r.in.user_handle = handle;
762
763         status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &r);
764         if (!NT_STATUS_IS_OK(status)) {
765                 printf("GetUserPwInfo failed - %s\n", nt_errstr(status));
766                 ret = False;
767         }
768
769         return ret;
770 }
771
772 static NTSTATUS test_LookupName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
773                                 struct policy_handle *domain_handle, const char *name,
774                                 uint32_t *rid)
775 {
776         NTSTATUS status;
777         struct samr_LookupNames n;
778         struct lsa_String sname[2];
779
780         init_lsa_String(&sname[0], name);
781
782         n.in.domain_handle = domain_handle;
783         n.in.num_names = 1;
784         n.in.names = sname;
785         status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
786         if (NT_STATUS_IS_OK(status)) {
787                 *rid = n.out.rids.ids[0];
788         } else {
789                 return status;
790         }
791
792         init_lsa_String(&sname[1], "xxNONAMExx");
793         n.in.num_names = 2;
794         status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
795         if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
796                 printf("LookupNames[2] failed - %s\n", nt_errstr(status));              
797                 return status;
798         }
799
800         init_lsa_String(&sname[1], "xxNONAMExx");
801         n.in.num_names = 0;
802         status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
803         if (!NT_STATUS_IS_OK(status)) {
804                 printf("LookupNames[0] failed - %s\n", nt_errstr(status));              
805         }
806
807         return status;
808 }
809
810 static NTSTATUS test_OpenUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
811                                      struct policy_handle *domain_handle,
812                                      const char *name, struct policy_handle *user_handle)
813 {
814         NTSTATUS status;
815         struct samr_OpenUser r;
816         uint32_t rid;
817
818         status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
819         if (!NT_STATUS_IS_OK(status)) {
820                 return status;
821         }
822
823         r.in.domain_handle = domain_handle;
824         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
825         r.in.rid = rid;
826         r.out.user_handle = user_handle;
827         status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
828         if (!NT_STATUS_IS_OK(status)) {
829                 printf("OpenUser_byname(%s) failed - %s\n", name, nt_errstr(status));
830         }
831
832         return status;
833 }
834
835 #if 0
836 static BOOL test_ChangePasswordNT3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
837                                    struct policy_handle *handle)
838 {
839         NTSTATUS status;
840         struct samr_ChangePasswordUser r;
841         BOOL ret = True;
842         struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
843         struct policy_handle user_handle;
844         char *oldpass = "test";
845         char *newpass = "test2";
846         uint8_t old_nt_hash[16], new_nt_hash[16];
847         uint8_t old_lm_hash[16], new_lm_hash[16];
848
849         status = test_OpenUser_byname(p, mem_ctx, handle, "testuser", &user_handle);
850         if (!NT_STATUS_IS_OK(status)) {
851                 return False;
852         }
853
854         printf("Testing ChangePasswordUser for user 'testuser'\n");
855
856         printf("old password: %s\n", oldpass);
857         printf("new password: %s\n", newpass);
858
859         E_md4hash(oldpass, old_nt_hash);
860         E_md4hash(newpass, new_nt_hash);
861         E_deshash(oldpass, old_lm_hash);
862         E_deshash(newpass, new_lm_hash);
863
864         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
865         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
866         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
867         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
868         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
869         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
870
871         r.in.handle = &user_handle;
872         r.in.lm_present = 1;
873         r.in.old_lm_crypted = &hash1;
874         r.in.new_lm_crypted = &hash2;
875         r.in.nt_present = 1;
876         r.in.old_nt_crypted = &hash3;
877         r.in.new_nt_crypted = &hash4;
878         r.in.cross1_present = 1;
879         r.in.nt_cross = &hash5;
880         r.in.cross2_present = 1;
881         r.in.lm_cross = &hash6;
882
883         status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
884         if (!NT_STATUS_IS_OK(status)) {
885                 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
886                 ret = False;
887         }
888
889         if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
890                 ret = False;
891         }
892
893         return ret;
894 }
895 #endif
896
897 static BOOL test_ChangePasswordUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
898                                     struct policy_handle *handle, char **password)
899 {
900         NTSTATUS status;
901         struct samr_ChangePasswordUser r;
902         BOOL ret = True;
903         struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
904         struct policy_handle user_handle;
905         char *oldpass = *password;
906         uint8_t old_nt_hash[16], new_nt_hash[16];
907         uint8_t old_lm_hash[16], new_lm_hash[16];
908
909         char *newpass;
910         struct samr_GetUserPwInfo pwp;
911         int policy_min_pw_len = 0;
912
913         status = test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle);
914         if (!NT_STATUS_IS_OK(status)) {
915                 return False;
916         }
917         pwp.in.user_handle = &user_handle;
918
919         status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &pwp);
920         if (NT_STATUS_IS_OK(status)) {
921                 policy_min_pw_len = pwp.out.info.min_password_length;
922         }
923         newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
924
925         printf("Testing ChangePasswordUser\n");
926
927         E_md4hash(oldpass, old_nt_hash);
928         E_md4hash(newpass, new_nt_hash);
929         E_deshash(oldpass, old_lm_hash);
930         E_deshash(newpass, new_lm_hash);
931
932         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
933         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
934         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
935         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
936         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
937         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
938
939         r.in.user_handle = &user_handle;
940         r.in.lm_present = 1;
941         r.in.old_lm_crypted = &hash1;
942         r.in.new_lm_crypted = &hash2;
943         r.in.nt_present = 1;
944         r.in.old_nt_crypted = &hash3;
945         r.in.new_nt_crypted = &hash4;
946         r.in.cross1_present = 1;
947         r.in.nt_cross = &hash5;
948         r.in.cross2_present = 1;
949         r.in.lm_cross = &hash6;
950
951         status = dcerpc_samr_ChangePasswordUser(p, mem_ctx, &r);
952         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
953                 printf("ChangePasswordUser returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
954         } else  if (!NT_STATUS_IS_OK(status)) {
955                 printf("ChangePasswordUser failed - %s\n", nt_errstr(status));
956                 ret = False;
957         } else {
958                 *password = newpass;
959         }
960
961         if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
962                 ret = False;
963         }
964
965         return ret;
966 }
967
968
969 static BOOL test_OemChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
970                                         struct policy_handle *handle, char **password)
971 {
972         NTSTATUS status;
973         struct samr_OemChangePasswordUser2 r;
974         BOOL ret = True;
975         struct samr_Password lm_verifier;
976         struct samr_CryptPassword lm_pass;
977         struct lsa_AsciiString server, account, account_bad;
978         char *oldpass = *password;
979         char *newpass;
980         uint8_t old_lm_hash[16], new_lm_hash[16];
981
982         struct samr_GetDomPwInfo dom_pw_info;
983         int policy_min_pw_len = 0;
984
985         struct lsa_String domain_name;
986         domain_name.string = "";
987         dom_pw_info.in.domain_name = &domain_name;
988
989         printf("Testing OemChangePasswordUser2\n");
990
991         status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
992         if (NT_STATUS_IS_OK(status)) {
993                 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
994         }
995
996         newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
997
998         server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
999         account.string = TEST_ACCOUNT_NAME;
1000
1001         E_deshash(oldpass, old_lm_hash);
1002         E_deshash(newpass, new_lm_hash);
1003
1004         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1005         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1006         E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1007
1008         r.in.server = &server;
1009         r.in.account = &account;
1010         r.in.password = &lm_pass;
1011         r.in.hash = &lm_verifier;
1012
1013         /* Break the verification */
1014         lm_verifier.hash[0]++;
1015
1016         status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1017
1018         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
1019             && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1020                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1021                         nt_errstr(status));
1022                 ret = False;
1023         }
1024
1025         /* This shouldn't be a valid name */
1026         account_bad.string = TEST_ACCOUNT_NAME "XX";
1027         r.in.account = &account_bad;
1028
1029         status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1030
1031         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1032                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid user - %s\n",
1033                         nt_errstr(status));
1034                 ret = False;
1035         }
1036
1037         E_deshash(oldpass, old_lm_hash);
1038         E_deshash(newpass, new_lm_hash);
1039
1040         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII);
1041         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1042         E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
1043
1044         r.in.server = &server;
1045         r.in.account = &account;
1046         r.in.password = &lm_pass;
1047         r.in.hash = &lm_verifier;
1048
1049         status = dcerpc_samr_OemChangePasswordUser2(p, mem_ctx, &r);
1050         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1051                 printf("OemChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1052         } else if (!NT_STATUS_IS_OK(status)) {
1053                 printf("OemChangePasswordUser2 failed - %s\n", nt_errstr(status));
1054                 ret = False;
1055         } else {
1056                 *password = newpass;
1057         }
1058
1059         return ret;
1060 }
1061
1062
1063 static BOOL test_ChangePasswordUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1064                                      struct policy_handle *handle, char **password)
1065 {
1066         NTSTATUS status;
1067         struct samr_ChangePasswordUser2 r;
1068         BOOL ret = True;
1069         struct lsa_String server, account;
1070         struct samr_CryptPassword nt_pass, lm_pass;
1071         struct samr_Password nt_verifier, lm_verifier;
1072         char *oldpass = *password;
1073         char *newpass;
1074         uint8_t old_nt_hash[16], new_nt_hash[16];
1075         uint8_t old_lm_hash[16], new_lm_hash[16];
1076
1077         struct samr_GetDomPwInfo dom_pw_info;
1078         int policy_min_pw_len = 0;
1079
1080         struct lsa_String domain_name;
1081         domain_name.string = "";
1082         dom_pw_info.in.domain_name = &domain_name;
1083
1084         printf("Testing ChangePasswordUser2\n");
1085
1086         status = dcerpc_samr_GetDomPwInfo(p, mem_ctx, &dom_pw_info);
1087         if (NT_STATUS_IS_OK(status)) {
1088                 policy_min_pw_len = dom_pw_info.out.info.min_password_length;
1089         }
1090
1091         newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);
1092
1093         server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1094         init_lsa_String(&account, TEST_ACCOUNT_NAME);
1095
1096         E_md4hash(oldpass, old_nt_hash);
1097         E_md4hash(newpass, new_nt_hash);
1098
1099         E_deshash(oldpass, old_lm_hash);
1100         E_deshash(newpass, new_lm_hash);
1101
1102         encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
1103         arcfour_crypt(lm_pass.data, old_lm_hash, 516);
1104         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1105
1106         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1107         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1108         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1109
1110         r.in.server = &server;
1111         r.in.account = &account;
1112         r.in.nt_password = &nt_pass;
1113         r.in.nt_verifier = &nt_verifier;
1114         r.in.lm_change = 1;
1115         r.in.lm_password = &lm_pass;
1116         r.in.lm_verifier = &lm_verifier;
1117
1118         status = dcerpc_samr_ChangePasswordUser2(p, mem_ctx, &r);
1119         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1120                 printf("ChangePasswordUser2 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1121         } else if (!NT_STATUS_IS_OK(status)) {
1122                 printf("ChangePasswordUser2 failed - %s\n", nt_errstr(status));
1123                 ret = False;
1124         } else {
1125                 *password = newpass;
1126         }
1127
1128         return ret;
1129 }
1130
1131
1132 BOOL test_ChangePasswordUser3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1133                               const char *account_string,
1134                               int policy_min_pw_len,
1135                               char **password)
1136 {
1137         NTSTATUS status;
1138         struct samr_ChangePasswordUser3 r;
1139         BOOL ret = True;
1140         struct lsa_String server, account, account_bad;
1141         struct samr_CryptPassword nt_pass, lm_pass;
1142         struct samr_Password nt_verifier, lm_verifier;
1143         char *oldpass = *password;
1144         char *newpass = samr_rand_pass(mem_ctx, policy_min_pw_len);     
1145         uint8_t old_nt_hash[16], new_nt_hash[16];
1146         uint8_t old_lm_hash[16], new_lm_hash[16];
1147
1148         printf("Testing ChangePasswordUser3\n");
1149
1150         server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1151         init_lsa_String(&account, account_string);
1152
1153         E_md4hash(oldpass, old_nt_hash);
1154         E_md4hash(newpass, new_nt_hash);
1155
1156         E_deshash(oldpass, old_lm_hash);
1157         E_deshash(newpass, new_lm_hash);
1158
1159         encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1160         arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1161         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1162
1163         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1164         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1165         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1166         
1167         /* Break the verification */
1168         nt_verifier.hash[0]++;
1169
1170         r.in.server = &server;
1171         r.in.account = &account;
1172         r.in.nt_password = &nt_pass;
1173         r.in.nt_verifier = &nt_verifier;
1174         r.in.lm_change = 1;
1175         r.in.lm_password = &lm_pass;
1176         r.in.lm_verifier = &lm_verifier;
1177         r.in.password3 = NULL;
1178
1179         status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1180         if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
1181             (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD))) {
1182                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n",
1183                         nt_errstr(status));
1184                 ret = False;
1185         }
1186         
1187         /* This shouldn't be a valid name */
1188         init_lsa_String(&account_bad, talloc_asprintf(mem_ctx, "%sXX", account_string));
1189
1190         r.in.account = &account_bad;
1191         status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1192         if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
1193                 printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid username - %s\n",
1194                         nt_errstr(status));
1195                 ret = False;
1196         }
1197
1198         E_md4hash(oldpass, old_nt_hash);
1199         E_md4hash(newpass, new_nt_hash);
1200
1201         E_deshash(oldpass, old_lm_hash);
1202         E_deshash(newpass, new_lm_hash);
1203
1204         encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
1205         arcfour_crypt(lm_pass.data, old_nt_hash, 516);
1206         E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
1207
1208         encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
1209         arcfour_crypt(nt_pass.data, old_nt_hash, 516);
1210         E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
1211
1212         r.in.server = &server;
1213         r.in.account = &account;
1214         r.in.nt_password = &nt_pass;
1215         r.in.nt_verifier = &nt_verifier;
1216         r.in.lm_change = 1;
1217         r.in.lm_password = &lm_pass;
1218         r.in.lm_verifier = &lm_verifier;
1219         r.in.password3 = NULL;
1220
1221         status = dcerpc_samr_ChangePasswordUser3(p, mem_ctx, &r);
1222         if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) 
1223             && !policy_min_pw_len) {
1224                 if (r.out.dominfo) {
1225                         policy_min_pw_len = r.out.dominfo->min_password_length;
1226                 }
1227                 if (policy_min_pw_len) /* try again with the right min password length */ {
1228                         ret = test_ChangePasswordUser3(p, mem_ctx, account_string, policy_min_pw_len, password);
1229                 } else {
1230                         printf("ChangePasswordUser3 failed (no min length known) - %s\n", nt_errstr(status));
1231                         ret = False;
1232                 }
1233         } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
1234                 printf("ChangePasswordUser3 returned: %s perhaps min password age? (not fatal)\n", nt_errstr(status));
1235         } else if (!NT_STATUS_IS_OK(status)) {
1236                 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1237                 ret = False;
1238         } else {
1239                 *password = newpass;
1240         }
1241
1242         return ret;
1243 }
1244
1245
1246 static BOOL test_GetMembersInAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1247                                   struct policy_handle *alias_handle)
1248 {
1249         struct samr_GetMembersInAlias r;
1250         struct lsa_SidArray sids;
1251         NTSTATUS status;
1252         BOOL     ret = True;
1253
1254         printf("Testing GetMembersInAlias\n");
1255
1256         r.in.alias_handle = alias_handle;
1257         r.out.sids = &sids;
1258
1259         status = dcerpc_samr_GetMembersInAlias(p, mem_ctx, &r);
1260         if (!NT_STATUS_IS_OK(status)) {
1261                 printf("GetMembersInAlias failed - %s\n",
1262                        nt_errstr(status));
1263                 ret = False;
1264         }
1265
1266         return ret;
1267 }
1268
1269 static BOOL test_AddMemberToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1270                                   struct policy_handle *alias_handle,
1271                                   const struct dom_sid *domain_sid)
1272 {
1273         struct samr_AddAliasMember r;
1274         struct samr_DeleteAliasMember d;
1275         NTSTATUS status;
1276         BOOL ret = True;
1277         struct dom_sid *sid;
1278
1279         sid = dom_sid_add_rid(mem_ctx, domain_sid, 512);
1280
1281         printf("testing AddAliasMember\n");
1282         r.in.alias_handle = alias_handle;
1283         r.in.sid = sid;
1284
1285         status = dcerpc_samr_AddAliasMember(p, mem_ctx, &r);
1286         if (!NT_STATUS_IS_OK(status)) {
1287                 printf("AddAliasMember failed - %s\n", nt_errstr(status));
1288                 ret = False;
1289         }
1290
1291         d.in.alias_handle = alias_handle;
1292         d.in.sid = sid;
1293
1294         status = dcerpc_samr_DeleteAliasMember(p, mem_ctx, &d);
1295         if (!NT_STATUS_IS_OK(status)) {
1296                 printf("DelAliasMember failed - %s\n", nt_errstr(status));
1297                 ret = False;
1298         }
1299
1300         return ret;
1301 }
1302
1303 static BOOL test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1304                                            struct policy_handle *alias_handle)
1305 {
1306         struct samr_AddMultipleMembersToAlias a;
1307         struct samr_RemoveMultipleMembersFromAlias r;
1308         NTSTATUS status;
1309         BOOL ret = True;
1310         struct lsa_SidArray sids;
1311
1312         printf("testing AddMultipleMembersToAlias\n");
1313         a.in.alias_handle = alias_handle;
1314         a.in.sids = &sids;
1315
1316         sids.num_sids = 3;
1317         sids.sids = talloc_array(mem_ctx, struct lsa_SidPtr, 3);
1318
1319         sids.sids[0].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-1");
1320         sids.sids[1].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-2");
1321         sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-3");
1322
1323         status = dcerpc_samr_AddMultipleMembersToAlias(p, mem_ctx, &a);
1324         if (!NT_STATUS_IS_OK(status)) {
1325                 printf("AddMultipleMembersToAlias failed - %s\n", nt_errstr(status));
1326                 ret = False;
1327         }
1328
1329
1330         printf("testing RemoveMultipleMembersFromAlias\n");
1331         r.in.alias_handle = alias_handle;
1332         r.in.sids = &sids;
1333
1334         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1335         if (!NT_STATUS_IS_OK(status)) {
1336                 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1337                 ret = False;
1338         }
1339
1340         /* strange! removing twice doesn't give any error */
1341         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1342         if (!NT_STATUS_IS_OK(status)) {
1343                 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1344                 ret = False;
1345         }
1346
1347         /* but removing an alias that isn't there does */
1348         sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-4");
1349
1350         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1351         if (!NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) {
1352                 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1353                 ret = False;
1354         }
1355
1356         return ret;
1357 }
1358
1359 static BOOL test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1360                                             struct policy_handle *user_handle)
1361 {
1362         struct samr_TestPrivateFunctionsUser r;
1363         NTSTATUS status;
1364         BOOL ret = True;
1365
1366         printf("Testing TestPrivateFunctionsUser\n");
1367
1368         r.in.user_handle = user_handle;
1369
1370         status = dcerpc_samr_TestPrivateFunctionsUser(p, mem_ctx, &r);
1371         if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
1372                 printf("TestPrivateFunctionsUser failed - %s\n", nt_errstr(status));
1373                 ret = False;
1374         }
1375
1376         return ret;
1377 }
1378
1379
1380 static BOOL test_user_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1381                           struct policy_handle *handle, uint32_t base_acct_flags, 
1382                           const char *base_acct_name)
1383 {
1384         BOOL ret = True;
1385
1386         if (!test_QuerySecurity(p, mem_ctx, handle)) {
1387                 ret = False;
1388         }
1389
1390         if (!test_QueryUserInfo(p, mem_ctx, handle)) {
1391                 ret = False;
1392         }
1393
1394         if (!test_QueryUserInfo2(p, mem_ctx, handle)) {
1395                 ret = False;
1396         }
1397
1398         if (!test_SetUserInfo(p, mem_ctx, handle, base_acct_flags,
1399                               base_acct_name)) {
1400                 ret = False;
1401         }       
1402
1403         if (!test_GetUserPwInfo(p, mem_ctx, handle)) {
1404                 ret = False;
1405         }
1406
1407         if (!test_TestPrivateFunctionsUser(p, mem_ctx, handle)) {
1408                 ret = False;
1409         }
1410
1411         return ret;
1412 }
1413
1414 static BOOL test_alias_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1415                            struct policy_handle *alias_handle,
1416                            const struct dom_sid *domain_sid)
1417 {
1418         BOOL ret = True;
1419
1420         if (!test_QuerySecurity(p, mem_ctx, alias_handle)) {
1421                 ret = False;
1422         }
1423
1424         if (!test_QueryAliasInfo(p, mem_ctx, alias_handle)) {
1425                 ret = False;
1426         }
1427
1428         if (!test_SetAliasInfo(p, mem_ctx, alias_handle)) {
1429                 ret = False;
1430         }
1431
1432         if (!test_AddMemberToAlias(p, mem_ctx, alias_handle, domain_sid)) {
1433                 ret = False;
1434         }
1435
1436         if (!test_AddMultipleMembersToAlias(p, mem_ctx, alias_handle)) {
1437                 ret = False;
1438         }
1439
1440         return ret;
1441 }
1442
1443
1444 BOOL test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1445                             struct policy_handle *handle, const char *name)
1446 {
1447         NTSTATUS status;
1448         struct samr_DeleteUser d;
1449         struct policy_handle user_handle;
1450         uint32_t rid;
1451
1452         status = test_LookupName(p, mem_ctx, handle, name, &rid);
1453         if (!NT_STATUS_IS_OK(status)) {
1454                 goto failed;
1455         }
1456
1457         status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
1458         if (!NT_STATUS_IS_OK(status)) {
1459                 goto failed;
1460         }
1461
1462         d.in.user_handle = &user_handle;
1463         d.out.user_handle = &user_handle;
1464         status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
1465         if (!NT_STATUS_IS_OK(status)) {
1466                 goto failed;
1467         }
1468
1469         return True;
1470
1471 failed:
1472         printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
1473         return False;
1474 }
1475
1476
1477 static BOOL test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1478                                     struct policy_handle *handle, const char *name)
1479 {
1480         NTSTATUS status;
1481         struct samr_OpenGroup r;
1482         struct samr_DeleteDomainGroup d;
1483         struct policy_handle group_handle;
1484         uint32_t rid;
1485
1486         status = test_LookupName(p, mem_ctx, handle, name, &rid);
1487         if (!NT_STATUS_IS_OK(status)) {
1488                 goto failed;
1489         }
1490
1491         r.in.domain_handle = handle;
1492         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1493         r.in.rid = rid;
1494         r.out.group_handle = &group_handle;
1495         status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
1496         if (!NT_STATUS_IS_OK(status)) {
1497                 goto failed;
1498         }
1499
1500         d.in.group_handle = &group_handle;
1501         d.out.group_handle = &group_handle;
1502         status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
1503         if (!NT_STATUS_IS_OK(status)) {
1504                 goto failed;
1505         }
1506
1507         return True;
1508
1509 failed:
1510         printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
1511         return False;
1512 }
1513
1514
1515 static BOOL test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1516                                    struct policy_handle *domain_handle, const char *name)
1517 {
1518         NTSTATUS status;
1519         struct samr_OpenAlias r;
1520         struct samr_DeleteDomAlias d;
1521         struct policy_handle alias_handle;
1522         uint32_t rid;
1523
1524         printf("testing DeleteAlias_byname\n");
1525
1526         status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1527         if (!NT_STATUS_IS_OK(status)) {
1528                 goto failed;
1529         }
1530
1531         r.in.domain_handle = domain_handle;
1532         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1533         r.in.rid = rid;
1534         r.out.alias_handle = &alias_handle;
1535         status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
1536         if (!NT_STATUS_IS_OK(status)) {
1537                 goto failed;
1538         }
1539
1540         d.in.alias_handle = &alias_handle;
1541         d.out.alias_handle = &alias_handle;
1542         status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
1543         if (!NT_STATUS_IS_OK(status)) {
1544                 goto failed;
1545         }
1546
1547         return True;
1548
1549 failed:
1550         printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
1551         return False;
1552 }
1553
1554 static BOOL test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1555                                      struct policy_handle *alias_handle)
1556 {
1557         struct samr_DeleteDomAlias d;
1558         NTSTATUS status;
1559         BOOL ret = True;
1560         printf("Testing DeleteAlias\n");
1561
1562         d.in.alias_handle = alias_handle;
1563         d.out.alias_handle = alias_handle;
1564
1565         status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
1566         if (!NT_STATUS_IS_OK(status)) {
1567                 printf("DeleteAlias failed - %s\n", nt_errstr(status));
1568                 ret = False;
1569         }
1570
1571         return ret;
1572 }
1573
1574 static BOOL test_CreateAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1575                             struct policy_handle *domain_handle, 
1576                              struct policy_handle *alias_handle, 
1577                              const struct dom_sid *domain_sid)
1578 {
1579         NTSTATUS status;
1580         struct samr_CreateDomAlias r;
1581         struct lsa_String name;
1582         uint32_t rid;
1583         BOOL ret = True;
1584
1585         init_lsa_String(&name, TEST_ALIASNAME);
1586         r.in.domain_handle = domain_handle;
1587         r.in.alias_name = &name;
1588         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1589         r.out.alias_handle = alias_handle;
1590         r.out.rid = &rid;
1591
1592         printf("Testing CreateAlias (%s)\n", r.in.alias_name->string);
1593
1594         status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
1595
1596         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1597                 printf("Server refused create of '%s'\n", r.in.alias_name->string);
1598                 return True;
1599         }
1600
1601         if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
1602                 if (!test_DeleteAlias_byname(p, mem_ctx, domain_handle, r.in.alias_name->string)) {
1603                         return False;
1604                 }
1605                 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
1606         }
1607
1608         if (!NT_STATUS_IS_OK(status)) {
1609                 printf("CreateAlias failed - %s\n", nt_errstr(status));
1610                 return False;
1611         }
1612
1613         if (!test_alias_ops(p, mem_ctx, alias_handle, domain_sid)) {
1614                 ret = False;
1615         }
1616
1617         return ret;
1618 }
1619
1620 static BOOL test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1621                                 struct policy_handle *domain_handle, char **password)
1622 {
1623         BOOL ret = True;
1624
1625         if (!*password) {
1626                 return False;
1627         }
1628
1629         if (!test_ChangePasswordUser(p, mem_ctx, domain_handle, password)) {
1630                 ret = False;
1631         }
1632
1633         if (!test_ChangePasswordUser2(p, mem_ctx, domain_handle, password)) {
1634                 ret = False;
1635         }
1636
1637         if (!test_OemChangePasswordUser2(p, mem_ctx, domain_handle, password)) {
1638                 ret = False;
1639         }
1640
1641         /* we change passwords twice - this has the effect of verifying
1642            they were changed correctly for the final call */
1643         if (!test_ChangePasswordUser3(p, mem_ctx, TEST_ACCOUNT_NAME, 0, password)) {
1644                 ret = False;
1645         }
1646
1647         if (!test_ChangePasswordUser3(p, mem_ctx, TEST_ACCOUNT_NAME, 0, password)) {
1648                 ret = False;
1649         }
1650
1651         return ret;
1652 }
1653
1654 static BOOL test_CreateUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1655                             struct policy_handle *domain_handle, struct policy_handle *user_handle)
1656 {
1657         NTSTATUS status;
1658         struct samr_CreateUser r;
1659         struct samr_QueryUserInfo q;
1660         uint32_t rid;
1661         char *password = NULL;
1662
1663         int i;
1664         const uint32_t password_fields[] = {
1665                 SAMR_FIELD_PASSWORD,
1666                 SAMR_FIELD_PASSWORD2,
1667                 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
1668                 0
1669         };
1670         
1671         TALLOC_CTX *user_ctx;
1672
1673         /* This call creates a 'normal' account - check that it really does */
1674         const uint32_t acct_flags = ACB_NORMAL;
1675         struct lsa_String name;
1676         BOOL ret = True;
1677
1678         user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
1679         init_lsa_String(&name, TEST_ACCOUNT_NAME);
1680
1681         r.in.domain_handle = domain_handle;
1682         r.in.account_name = &name;
1683         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1684         r.out.user_handle = user_handle;
1685         r.out.rid = &rid;
1686
1687         printf("Testing CreateUser(%s)\n", r.in.account_name->string);
1688
1689         status = dcerpc_samr_CreateUser(p, user_ctx, &r);
1690
1691         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1692                 printf("Server refused create of '%s'\n", r.in.account_name->string);
1693                 ZERO_STRUCTP(user_handle);
1694                 talloc_free(user_ctx);
1695                 return True;
1696         }
1697
1698         if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
1699                 if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
1700                         talloc_free(user_ctx);
1701                         return False;
1702                 }
1703                 status = dcerpc_samr_CreateUser(p, user_ctx, &r);
1704         }
1705         if (!NT_STATUS_IS_OK(status)) {
1706                 talloc_free(user_ctx);
1707                 printf("CreateUser failed - %s\n", nt_errstr(status));
1708                 return False;
1709         }
1710
1711         q.in.user_handle = user_handle;
1712         q.in.level = 16;
1713
1714         status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
1715         if (!NT_STATUS_IS_OK(status)) {
1716                 printf("QueryUserInfo level %u failed - %s\n", 
1717                        q.in.level, nt_errstr(status));
1718                 ret = False;
1719         } else {
1720                 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
1721                         printf("QuerUserInfo level 16 failed, it returned 0x%08x (%u) when we expected flags of 0x%08x (%u)\n",
1722                                q.out.info->info16.acct_flags, q.out.info->info16.acct_flags, 
1723                                acct_flags, acct_flags);
1724                         ret = False;
1725                 }
1726         }
1727
1728         if (!test_user_ops(p, user_ctx, user_handle, acct_flags, name.string)) {
1729                 ret = False;
1730         }
1731
1732         if (!test_SetUserPass(p, user_ctx, user_handle, &password)) {
1733                 ret = False;
1734         }       
1735
1736         for (i = 0; password_fields[i]; i++) {
1737                 if (!test_SetUserPass_23(p, user_ctx, user_handle, password_fields[i], &password)) {
1738                         ret = False;
1739                 }       
1740                 
1741                 /* check it was set right */
1742                 if (!test_ChangePasswordUser3(p, user_ctx, TEST_ACCOUNT_NAME, 0, &password)) {
1743                         ret = False;
1744                 }
1745         }               
1746
1747         for (i = 0; password_fields[i]; i++) {
1748                 if (!test_SetUserPass_25(p, user_ctx, user_handle, password_fields[i], &password)) {
1749                         ret = False;
1750                 }       
1751                 
1752                 /* check it was set right */
1753                 if (!test_ChangePasswordUser3(p, user_ctx, TEST_ACCOUNT_NAME, 0, &password)) {
1754                         ret = False;
1755                 }
1756         }               
1757
1758         if (!test_SetUserPassEx(p, user_ctx, user_handle, &password)) {
1759                 ret = False;
1760         }       
1761
1762         if (!test_ChangePassword(p, user_ctx, domain_handle, &password)) {
1763                 ret = False;
1764         }       
1765
1766         talloc_free(user_ctx);
1767         
1768         return ret;
1769 }
1770
1771
1772 static BOOL test_DeleteUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1773                             struct policy_handle *user_handle)
1774 {
1775         struct samr_DeleteUser d;
1776         NTSTATUS status;
1777         BOOL ret = True;
1778
1779         printf("Testing DeleteUser\n");
1780
1781         d.in.user_handle = user_handle;
1782         d.out.user_handle = user_handle;
1783
1784         status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
1785         if (!NT_STATUS_IS_OK(status)) {
1786                 printf("DeleteUser failed - %s\n", nt_errstr(status));
1787                 ret = False;
1788         }
1789
1790         return ret;
1791 }
1792
1793 static BOOL test_CreateUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1794                              struct policy_handle *handle)
1795 {
1796         NTSTATUS status;
1797         struct samr_CreateUser2 r;
1798         struct samr_QueryUserInfo q;
1799         struct samr_DeleteUser d;
1800         struct policy_handle user_handle;
1801         uint32_t rid;
1802         struct lsa_String name;
1803         BOOL ret = True;
1804         int i;
1805
1806         struct {
1807                 uint32_t acct_flags;
1808                 const char *account_name;
1809                 NTSTATUS nt_status;
1810         } account_types[] = {
1811                 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
1812                 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1813                 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1814                 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
1815                 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1816                 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1817                 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
1818                 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1819                 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1820                 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
1821                 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
1822                 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
1823                 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1824                 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1825                 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
1826         };
1827
1828         for (i = 0; account_types[i].account_name; i++) {
1829                 TALLOC_CTX *user_ctx;
1830                 uint32_t acct_flags = account_types[i].acct_flags;
1831                 uint32_t access_granted;
1832                 user_ctx = talloc_named(mem_ctx, 0, "test_CreateUser2 per-user context");
1833                 init_lsa_String(&name, account_types[i].account_name);
1834
1835                 r.in.domain_handle = handle;
1836                 r.in.account_name = &name;
1837                 r.in.acct_flags = acct_flags;
1838                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1839                 r.out.user_handle = &user_handle;
1840                 r.out.access_granted = &access_granted;
1841                 r.out.rid = &rid;
1842                 
1843                 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
1844                 
1845                 status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
1846                 
1847                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1848                         talloc_free(user_ctx);
1849                         printf("Server refused create of '%s'\n", r.in.account_name->string);
1850                         continue;
1851
1852                 } else if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
1853                         if (!test_DeleteUser_byname(p, user_ctx, handle, r.in.account_name->string)) {
1854                                 talloc_free(user_ctx);
1855                                 ret = False;
1856                                 continue;
1857                         }
1858                         status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
1859
1860                 }
1861                 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
1862                         printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n", 
1863                                nt_errstr(status), nt_errstr(account_types[i].nt_status));
1864                         ret = False;
1865                 }
1866                 
1867                 if (NT_STATUS_IS_OK(status)) {
1868                         q.in.user_handle = &user_handle;
1869                         q.in.level = 16;
1870                         
1871                         status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
1872                         if (!NT_STATUS_IS_OK(status)) {
1873                                 printf("QueryUserInfo level %u failed - %s\n", 
1874                                        q.in.level, nt_errstr(status));
1875                                 ret = False;
1876                         } else {
1877                                 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
1878                                         printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
1879                                                q.out.info->info16.acct_flags, 
1880                                                acct_flags);
1881                                         ret = False;
1882                                 }
1883                         }
1884                 
1885                         if (!test_user_ops(p, user_ctx, &user_handle, acct_flags, name.string)) {
1886                                 ret = False;
1887                         }
1888
1889                         printf("Testing DeleteUser (createuser2 test)\n");
1890                 
1891                         d.in.user_handle = &user_handle;
1892                         d.out.user_handle = &user_handle;
1893                         
1894                         status = dcerpc_samr_DeleteUser(p, user_ctx, &d);
1895                         if (!NT_STATUS_IS_OK(status)) {
1896                                 printf("DeleteUser failed - %s\n", nt_errstr(status));
1897                                 ret = False;
1898                         }
1899                 }
1900                 talloc_free(user_ctx);
1901         }
1902
1903         return ret;
1904 }
1905
1906 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1907                                 struct policy_handle *handle)
1908 {
1909         NTSTATUS status;
1910         struct samr_QueryAliasInfo r;
1911         uint16_t levels[] = {1, 2, 3};
1912         int i;
1913         BOOL ret = True;
1914
1915         for (i=0;i<ARRAY_SIZE(levels);i++) {
1916                 printf("Testing QueryAliasInfo level %u\n", levels[i]);
1917
1918                 r.in.alias_handle = handle;
1919                 r.in.level = levels[i];
1920
1921                 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
1922                 if (!NT_STATUS_IS_OK(status)) {
1923                         printf("QueryAliasInfo level %u failed - %s\n", 
1924                                levels[i], nt_errstr(status));
1925                         ret = False;
1926                 }
1927         }
1928
1929         return ret;
1930 }
1931
1932 static BOOL test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1933                                 struct policy_handle *handle)
1934 {
1935         NTSTATUS status;
1936         struct samr_QueryGroupInfo r;
1937         uint16_t levels[] = {1, 2, 3, 4, 5};
1938         int i;
1939         BOOL ret = True;
1940
1941         for (i=0;i<ARRAY_SIZE(levels);i++) {
1942                 printf("Testing QueryGroupInfo level %u\n", levels[i]);
1943
1944                 r.in.group_handle = handle;
1945                 r.in.level = levels[i];
1946
1947                 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
1948                 if (!NT_STATUS_IS_OK(status)) {
1949                         printf("QueryGroupInfo level %u failed - %s\n", 
1950                                levels[i], nt_errstr(status));
1951                         ret = False;
1952                 }
1953         }
1954
1955         return ret;
1956 }
1957
1958 static BOOL test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1959                                   struct policy_handle *handle)
1960 {
1961         NTSTATUS status;
1962         struct samr_QueryGroupMember r;
1963         BOOL ret = True;
1964
1965         printf("Testing QueryGroupMember\n");
1966
1967         r.in.group_handle = handle;
1968
1969         status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
1970         if (!NT_STATUS_IS_OK(status)) {
1971                 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
1972                 ret = False;
1973         }
1974
1975         return ret;
1976 }
1977
1978
1979 static BOOL test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1980                               struct policy_handle *handle)
1981 {
1982         NTSTATUS status;
1983         struct samr_QueryGroupInfo r;
1984         struct samr_SetGroupInfo s;
1985         uint16_t levels[] = {1, 2, 3, 4};
1986         uint16_t set_ok[] = {0, 1, 1, 1};
1987         int i;
1988         BOOL ret = True;
1989
1990         for (i=0;i<ARRAY_SIZE(levels);i++) {
1991                 printf("Testing QueryGroupInfo level %u\n", levels[i]);
1992
1993                 r.in.group_handle = handle;
1994                 r.in.level = levels[i];
1995
1996                 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
1997                 if (!NT_STATUS_IS_OK(status)) {
1998                         printf("QueryGroupInfo level %u failed - %s\n", 
1999                                levels[i], nt_errstr(status));
2000                         ret = False;
2001                 }
2002
2003                 printf("Testing SetGroupInfo level %u\n", levels[i]);
2004
2005                 s.in.group_handle = handle;
2006                 s.in.level = levels[i];
2007                 s.in.info = r.out.info;
2008
2009 #if 0
2010                 /* disabled this, as it changes the name only from the point of view of samr, 
2011                    but leaves the name from the point of view of w2k3 internals (and ldap). This means
2012                    the name is still reserved, so creating the old name fails, but deleting by the old name
2013                    also fails */
2014                 if (s.in.level == 2) {
2015                         init_lsa_String(&s.in.info->string, "NewName");
2016                 }
2017 #endif
2018
2019                 if (s.in.level == 4) {
2020                         init_lsa_String(&s.in.info->description, "test description");
2021                 }
2022
2023                 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
2024                 if (set_ok[i]) {
2025                         if (!NT_STATUS_IS_OK(status)) {
2026                                 printf("SetGroupInfo level %u failed - %s\n", 
2027                                        r.in.level, nt_errstr(status));
2028                                 ret = False;
2029                                 continue;
2030                         }
2031                 } else {
2032                         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
2033                                 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n", 
2034                                        r.in.level, nt_errstr(status));
2035                                 ret = False;
2036                                 continue;
2037                         }
2038                 }
2039         }
2040
2041         return ret;
2042 }
2043
2044 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2045                                struct policy_handle *handle)
2046 {
2047         NTSTATUS status;
2048         struct samr_QueryUserInfo r;
2049         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2050                            11, 12, 13, 14, 16, 17, 20, 21};
2051         int i;
2052         BOOL ret = True;
2053
2054         for (i=0;i<ARRAY_SIZE(levels);i++) {
2055                 printf("Testing QueryUserInfo level %u\n", levels[i]);
2056
2057                 r.in.user_handle = handle;
2058                 r.in.level = levels[i];
2059
2060                 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
2061                 if (!NT_STATUS_IS_OK(status)) {
2062                         printf("QueryUserInfo level %u failed - %s\n", 
2063                                levels[i], nt_errstr(status));
2064                         ret = False;
2065                 }
2066         }
2067
2068         return ret;
2069 }
2070
2071 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2072                                 struct policy_handle *handle)
2073 {
2074         NTSTATUS status;
2075         struct samr_QueryUserInfo2 r;
2076         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
2077                            11, 12, 13, 14, 16, 17, 20, 21};
2078         int i;
2079         BOOL ret = True;
2080
2081         for (i=0;i<ARRAY_SIZE(levels);i++) {
2082                 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
2083
2084                 r.in.user_handle = handle;
2085                 r.in.level = levels[i];
2086
2087                 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
2088                 if (!NT_STATUS_IS_OK(status)) {
2089                         printf("QueryUserInfo2 level %u failed - %s\n", 
2090                                levels[i], nt_errstr(status));
2091                         ret = False;
2092                 }
2093         }
2094
2095         return ret;
2096 }
2097
2098 static BOOL test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2099                           struct policy_handle *handle, uint32_t rid)
2100 {
2101         NTSTATUS status;
2102         struct samr_OpenUser r;
2103         struct policy_handle user_handle;
2104         BOOL ret = True;
2105
2106         printf("Testing OpenUser(%u)\n", rid);
2107
2108         r.in.domain_handle = handle;
2109         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2110         r.in.rid = rid;
2111         r.out.user_handle = &user_handle;
2112
2113         status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2114         if (!NT_STATUS_IS_OK(status)) {
2115                 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
2116                 return False;
2117         }
2118
2119         if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
2120                 ret = False;
2121         }
2122
2123         if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
2124                 ret = False;
2125         }
2126
2127         if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
2128                 ret = False;
2129         }
2130
2131         if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
2132                 ret = False;
2133         }
2134
2135         if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
2136                 ret = False;
2137         }
2138
2139         if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
2140                 ret = False;
2141         }
2142
2143         return ret;
2144 }
2145
2146 static BOOL test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2147                            struct policy_handle *handle, uint32_t rid)
2148 {
2149         NTSTATUS status;
2150         struct samr_OpenGroup r;
2151         struct policy_handle group_handle;
2152         BOOL ret = True;
2153
2154         printf("Testing OpenGroup(%u)\n", rid);
2155
2156         r.in.domain_handle = handle;
2157         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2158         r.in.rid = rid;
2159         r.out.group_handle = &group_handle;
2160
2161         status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2162         if (!NT_STATUS_IS_OK(status)) {
2163                 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
2164                 return False;
2165         }
2166
2167         if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
2168                 ret = False;
2169         }
2170
2171         if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
2172                 ret = False;
2173         }
2174
2175         if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
2176                 ret = False;
2177         }
2178
2179         if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
2180                 ret = False;
2181         }
2182
2183         return ret;
2184 }
2185
2186 static BOOL test_OpenAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2187                            struct policy_handle *handle, uint32_t rid)
2188 {
2189         NTSTATUS status;
2190         struct samr_OpenAlias r;
2191         struct policy_handle alias_handle;
2192         BOOL ret = True;
2193
2194         printf("Testing OpenAlias(%u)\n", rid);
2195
2196         r.in.domain_handle = handle;
2197         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2198         r.in.rid = rid;
2199         r.out.alias_handle = &alias_handle;
2200
2201         status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2202         if (!NT_STATUS_IS_OK(status)) {
2203                 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
2204                 return False;
2205         }
2206
2207         if (!test_QuerySecurity(p, mem_ctx, &alias_handle)) {
2208                 ret = False;
2209         }
2210
2211         if (!test_QueryAliasInfo(p, mem_ctx, &alias_handle)) {
2212                 ret = False;
2213         }
2214
2215         if (!test_GetMembersInAlias(p, mem_ctx, &alias_handle)) {
2216                 ret = False;
2217         }
2218
2219         if (!test_samr_handle_Close(p, mem_ctx, &alias_handle)) {
2220                 ret = False;
2221         }
2222
2223         return ret;
2224 }
2225
2226 static BOOL test_EnumDomainUsers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2227                                  struct policy_handle *handle)
2228 {
2229         NTSTATUS status;
2230         struct samr_EnumDomainUsers r;
2231         uint32_t resume_handle=0;
2232         int i;
2233         BOOL ret = True;
2234         struct samr_LookupNames n;
2235         struct samr_LookupRids  lr ;
2236
2237         printf("Testing EnumDomainUsers\n");
2238
2239         r.in.domain_handle = handle;
2240         r.in.resume_handle = &resume_handle;
2241         r.in.acct_flags = 0;
2242         r.in.max_size = (uint32_t)-1;
2243         r.out.resume_handle = &resume_handle;
2244
2245         status = dcerpc_samr_EnumDomainUsers(p, mem_ctx, &r);
2246         if (!NT_STATUS_IS_OK(status)) {
2247                 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
2248                 return False;
2249         }
2250         
2251         if (!r.out.sam) {
2252                 return False;
2253         }
2254
2255         if (r.out.sam->count == 0) {
2256                 return True;
2257         }
2258
2259         for (i=0;i<r.out.sam->count;i++) {
2260                 if (!test_OpenUser(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2261                         ret = False;
2262                 }
2263         }
2264
2265         printf("Testing LookupNames\n");
2266         n.in.domain_handle = handle;
2267         n.in.num_names = r.out.sam->count;
2268         n.in.names = talloc_array(mem_ctx, struct lsa_String, r.out.sam->count);
2269         for (i=0;i<r.out.sam->count;i++) {
2270                 n.in.names[i].string = r.out.sam->entries[i].name.string;
2271         }
2272         status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
2273         if (!NT_STATUS_IS_OK(status)) {
2274                 printf("LookupNames failed - %s\n", nt_errstr(status));
2275                 ret = False;
2276         }
2277
2278
2279         printf("Testing LookupRids\n");
2280         lr.in.domain_handle = handle;
2281         lr.in.num_rids = r.out.sam->count;
2282         lr.in.rids = talloc_array(mem_ctx, uint32_t, r.out.sam->count);
2283         for (i=0;i<r.out.sam->count;i++) {
2284                 lr.in.rids[i] = r.out.sam->entries[i].idx;
2285         }
2286         status = dcerpc_samr_LookupRids(p, mem_ctx, &lr);
2287         if (!NT_STATUS_IS_OK(status)) {
2288                 printf("LookupRids failed - %s\n", nt_errstr(status));
2289                 ret = False;
2290         }
2291
2292         return ret;     
2293 }
2294
2295 /*
2296   try blasting the server with a bunch of sync requests
2297 */
2298 static BOOL test_EnumDomainUsers_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2299                                        struct policy_handle *handle)
2300 {
2301         NTSTATUS status;
2302         struct samr_EnumDomainUsers r;
2303         uint32_t resume_handle=0;
2304         int i;
2305 #define ASYNC_COUNT 100
2306         struct rpc_request *req[ASYNC_COUNT];
2307
2308         if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
2309                 printf("samr async test disabled - enable dangerous tests to use\n");
2310                 return True;
2311         }
2312
2313         printf("Testing EnumDomainUsers_async\n");
2314
2315         r.in.domain_handle = handle;
2316         r.in.resume_handle = &resume_handle;
2317         r.in.acct_flags = 0;
2318         r.in.max_size = (uint32_t)-1;
2319         r.out.resume_handle = &resume_handle;
2320
2321         for (i=0;i<ASYNC_COUNT;i++) {
2322                 req[i] = dcerpc_samr_EnumDomainUsers_send(p, mem_ctx, &r);
2323         }
2324
2325         for (i=0;i<ASYNC_COUNT;i++) {
2326                 status = dcerpc_ndr_request_recv(req[i]);
2327                 if (!NT_STATUS_IS_OK(status)) {
2328                         printf("EnumDomainUsers[%d] failed - %s\n", 
2329                                i, nt_errstr(status));
2330                         return False;
2331                 }
2332         }
2333         
2334         printf("%d async requests OK\n", i);
2335
2336         return True;
2337 }
2338
2339 static BOOL test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2340                                   struct policy_handle *handle)
2341 {
2342         NTSTATUS status;
2343         struct samr_EnumDomainGroups r;
2344         uint32_t resume_handle=0;
2345         int i;
2346         BOOL ret = True;
2347
2348         printf("Testing EnumDomainGroups\n");
2349
2350         r.in.domain_handle = handle;
2351         r.in.resume_handle = &resume_handle;
2352         r.in.max_size = (uint32_t)-1;
2353         r.out.resume_handle = &resume_handle;
2354
2355         status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
2356         if (!NT_STATUS_IS_OK(status)) {
2357                 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
2358                 return False;
2359         }
2360         
2361         if (!r.out.sam) {
2362                 return False;
2363         }
2364
2365         for (i=0;i<r.out.sam->count;i++) {
2366                 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2367                         ret = False;
2368                 }
2369         }
2370
2371         return ret;
2372 }
2373
2374 static BOOL test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2375                                    struct policy_handle *handle)
2376 {
2377         NTSTATUS status;
2378         struct samr_EnumDomainAliases r;
2379         uint32_t resume_handle=0;
2380         int i;
2381         BOOL ret = True;
2382
2383         printf("Testing EnumDomainAliases\n");
2384
2385         r.in.domain_handle = handle;
2386         r.in.resume_handle = &resume_handle;
2387         r.in.acct_flags = (uint32_t)-1;
2388         r.out.resume_handle = &resume_handle;
2389
2390         status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
2391         if (!NT_STATUS_IS_OK(status)) {
2392                 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
2393                 return False;
2394         }
2395         
2396         if (!r.out.sam) {
2397                 return False;
2398         }
2399
2400         for (i=0;i<r.out.sam->count;i++) {
2401                 if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2402                         ret = False;
2403                 }
2404         }
2405
2406         return ret;     
2407 }
2408
2409 static BOOL test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2410                                             struct policy_handle *handle)
2411 {
2412         NTSTATUS status;
2413         struct samr_GetDisplayEnumerationIndex r;
2414         BOOL ret = True;
2415         uint16_t levels[] = {1, 2, 3, 4, 5};
2416         uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
2417         int i;
2418
2419         for (i=0;i<ARRAY_SIZE(levels);i++) {
2420                 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
2421
2422                 r.in.domain_handle = handle;
2423                 r.in.level = levels[i];
2424                 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
2425
2426                 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
2427
2428                 if (ok_lvl[i] && 
2429                     !NT_STATUS_IS_OK(status) &&
2430                     !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2431                         printf("GetDisplayEnumerationIndex level %u failed - %s\n", 
2432                                levels[i], nt_errstr(status));
2433                         ret = False;
2434                 }
2435
2436                 init_lsa_String(&r.in.name, "zzzzzzzz");
2437
2438                 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
2439                 
2440                 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2441                         printf("GetDisplayEnumerationIndex level %u failed - %s\n", 
2442                                levels[i], nt_errstr(status));
2443                         ret = False;
2444                 }
2445         }
2446         
2447         return ret;     
2448 }
2449
2450 static BOOL test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2451                                              struct policy_handle *handle)
2452 {
2453         NTSTATUS status;
2454         struct samr_GetDisplayEnumerationIndex2 r;
2455         BOOL ret = True;
2456         uint16_t levels[] = {1, 2, 3, 4, 5};
2457         uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
2458         int i;
2459
2460         for (i=0;i<ARRAY_SIZE(levels);i++) {
2461                 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
2462
2463                 r.in.domain_handle = handle;
2464                 r.in.level = levels[i];
2465                 init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
2466
2467                 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
2468                 if (ok_lvl[i] && 
2469                     !NT_STATUS_IS_OK(status) && 
2470                     !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2471                         printf("GetDisplayEnumerationIndex2 level %u failed - %s\n", 
2472                                levels[i], nt_errstr(status));
2473                         ret = False;
2474                 }
2475
2476                 init_lsa_String(&r.in.name, "zzzzzzzz");
2477
2478                 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
2479                 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2480                         printf("GetDisplayEnumerationIndex2 level %u failed - %s\n", 
2481                                levels[i], nt_errstr(status));
2482                         ret = False;
2483                 }
2484         }
2485         
2486         return ret;     
2487 }
2488
2489 static BOOL test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2490                                   struct policy_handle *handle)
2491 {
2492         NTSTATUS status;
2493         struct samr_QueryDisplayInfo r;
2494         BOOL ret = True;
2495         uint16_t levels[] = {1, 2, 3, 4, 5};
2496         int i;
2497
2498         for (i=0;i<ARRAY_SIZE(levels);i++) {
2499                 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
2500
2501                 r.in.domain_handle = handle;
2502                 r.in.level = levels[i];
2503                 r.in.start_idx = 0;
2504                 r.in.max_entries = 1000;
2505                 r.in.buf_size = (uint32_t)-1;
2506
2507                 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
2508                 if (!NT_STATUS_IS_OK(status)) {
2509                         printf("QueryDisplayInfo level %u failed - %s\n", 
2510                                levels[i], nt_errstr(status));
2511                         ret = False;
2512                 }
2513         }
2514         
2515         return ret;     
2516 }
2517
2518 static BOOL test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2519                                   struct policy_handle *handle)
2520 {
2521         NTSTATUS status;
2522         struct samr_QueryDisplayInfo2 r;
2523         BOOL ret = True;
2524         uint16_t levels[] = {1, 2, 3, 4, 5};
2525         int i;
2526
2527         for (i=0;i<ARRAY_SIZE(levels);i++) {
2528                 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
2529
2530                 r.in.domain_handle = handle;
2531                 r.in.level = levels[i];
2532                 r.in.start_idx = 0;
2533                 r.in.max_entries = 1000;
2534                 r.in.buf_size = (uint32_t)-1;
2535
2536                 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
2537                 if (!NT_STATUS_IS_OK(status)) {
2538                         printf("QueryDisplayInfo2 level %u failed - %s\n", 
2539                                levels[i], nt_errstr(status));
2540                         ret = False;
2541                 }
2542         }
2543         
2544         return ret;     
2545 }
2546
2547 static BOOL test_QueryDisplayInfo3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2548                                   struct policy_handle *handle)
2549 {
2550         NTSTATUS status;
2551         struct samr_QueryDisplayInfo3 r;
2552         BOOL ret = True;
2553         uint16_t levels[] = {1, 2, 3, 4, 5};
2554         int i;
2555
2556         for (i=0;i<ARRAY_SIZE(levels);i++) {
2557                 printf("Testing QueryDisplayInfo3 level %u\n", levels[i]);
2558
2559                 r.in.domain_handle = handle;
2560                 r.in.level = levels[i];
2561                 r.in.start_idx = 0;
2562                 r.in.max_entries = 1000;
2563                 r.in.buf_size = (uint32_t)-1;
2564
2565                 status = dcerpc_samr_QueryDisplayInfo3(p, mem_ctx, &r);
2566                 if (!NT_STATUS_IS_OK(status)) {
2567                         printf("QueryDisplayInfo3 level %u failed - %s\n", 
2568                                levels[i], nt_errstr(status));
2569                         ret = False;
2570                 }
2571         }
2572         
2573         return ret;     
2574 }
2575
2576
2577 static BOOL test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2578                                            struct policy_handle *handle)
2579 {
2580         NTSTATUS status;
2581         struct samr_QueryDisplayInfo r;
2582         BOOL ret = True;
2583
2584         printf("Testing QueryDisplayInfo continuation\n");
2585
2586         r.in.domain_handle = handle;
2587         r.in.level = 1;
2588         r.in.start_idx = 0;
2589         r.in.max_entries = 1;
2590         r.in.buf_size = (uint32_t)-1;
2591
2592         do {
2593                 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
2594                 if (NT_STATUS_IS_OK(status) && r.out.returned_size != 0) {
2595                         if (r.out.info.info1.entries[0].idx != r.in.start_idx + 1) {
2596                                 printf("failed: expected idx %d but got %d\n",
2597                                        r.in.start_idx + 1,
2598                                        r.out.info.info1.entries[0].idx);
2599                                 ret = False;
2600                                 break;
2601                         }
2602                 }
2603                 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
2604                     !NT_STATUS_IS_OK(status)) {
2605                         printf("QueryDisplayInfo level %u failed - %s\n", 
2606                                r.in.level, nt_errstr(status));
2607                         ret = False;
2608                         break;
2609                 }
2610                 r.in.start_idx++;
2611         } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
2612                   NT_STATUS_IS_OK(status)) &&
2613                  r.out.returned_size != 0);
2614         
2615         return ret;     
2616 }
2617
2618 static BOOL test_QueryDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2619                                  struct policy_handle *handle)
2620 {
2621         NTSTATUS status;
2622         struct samr_QueryDomainInfo r;
2623         struct samr_SetDomainInfo s;
2624         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
2625         uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1,  0,  1,  0};
2626         int i;
2627         BOOL ret = True;
2628
2629         for (i=0;i<ARRAY_SIZE(levels);i++) {
2630                 printf("Testing QueryDomainInfo level %u\n", levels[i]);
2631
2632                 r.in.domain_handle = handle;
2633                 r.in.level = levels[i];
2634
2635                 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2636                 if (!NT_STATUS_IS_OK(status)) {
2637                         printf("QueryDomainInfo level %u failed - %s\n", 
2638                                r.in.level, nt_errstr(status));
2639                         ret = False;
2640                         continue;
2641                 }
2642
2643                 printf("Testing SetDomainInfo level %u\n", levels[i]);
2644
2645                 s.in.domain_handle = handle;
2646                 s.in.level = levels[i];
2647                 s.in.info = r.out.info;
2648
2649                 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2650                 if (set_ok[i]) {
2651                         if (!NT_STATUS_IS_OK(status)) {
2652                                 printf("SetDomainInfo level %u failed - %s\n", 
2653                                        r.in.level, nt_errstr(status));
2654                                 ret = False;
2655                                 continue;
2656                         }
2657                 } else {
2658                         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
2659                                 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n", 
2660                                        r.in.level, nt_errstr(status));
2661                                 ret = False;
2662                                 continue;
2663                         }
2664                 }
2665
2666                 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2667                 if (!NT_STATUS_IS_OK(status)) {
2668                         printf("QueryDomainInfo level %u failed - %s\n", 
2669                                r.in.level, nt_errstr(status));
2670                         ret = False;
2671                         continue;
2672                 }
2673         }
2674
2675         return True;    
2676 }
2677
2678
2679 static BOOL test_QueryDomainInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2680                                   struct policy_handle *handle)
2681 {
2682         NTSTATUS status;
2683         struct samr_QueryDomainInfo2 r;
2684         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
2685         int i;
2686         BOOL ret = True;
2687
2688         for (i=0;i<ARRAY_SIZE(levels);i++) {
2689                 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
2690
2691                 r.in.domain_handle = handle;
2692                 r.in.level = levels[i];
2693
2694                 status = dcerpc_samr_QueryDomainInfo2(p, mem_ctx, &r);
2695                 if (!NT_STATUS_IS_OK(status)) {
2696                         printf("QueryDomainInfo2 level %u failed - %s\n", 
2697                                r.in.level, nt_errstr(status));
2698                         ret = False;
2699                         continue;
2700                 }
2701         }
2702
2703         return True;    
2704 }
2705
2706 /* Test whether querydispinfo level 5 and enumdomgroups return the same
2707    set of group names. */
2708 static BOOL test_GroupList(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2709                            struct policy_handle *handle)
2710 {
2711         struct samr_EnumDomainGroups q1;
2712         struct samr_QueryDisplayInfo q2;
2713         NTSTATUS status;
2714         uint32_t resume_handle=0;
2715         int i;
2716         BOOL ret = True;
2717
2718         int num_names = 0;
2719         const char **names = NULL;
2720
2721         printf("Testing coherency of querydispinfo vs enumdomgroups\n");
2722
2723         q1.in.domain_handle = handle;
2724         q1.in.resume_handle = &resume_handle;
2725         q1.in.max_size = 5;
2726         q1.out.resume_handle = &resume_handle;
2727
2728         status = STATUS_MORE_ENTRIES;
2729         while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
2730                 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &q1);
2731
2732                 if (!NT_STATUS_IS_OK(status) &&
2733                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
2734                         break;
2735
2736                 for (i=0; i<q1.out.num_entries; i++) {
2737                         add_string_to_array(mem_ctx,
2738                                             q1.out.sam->entries[i].name.string,
2739                                             &names, &num_names);
2740                 }
2741         }
2742
2743         if (!NT_STATUS_IS_OK(status)) {
2744                 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
2745                 return False;
2746         }
2747         
2748         if (!q1.out.sam) {
2749                 return False;
2750         }
2751
2752         q2.in.domain_handle = handle;
2753         q2.in.level = 5;
2754         q2.in.start_idx = 0;
2755         q2.in.max_entries = 5;
2756         q2.in.buf_size = (uint32_t)-1;
2757
2758         status = STATUS_MORE_ENTRIES;
2759         while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
2760                 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &q2);
2761
2762                 if (!NT_STATUS_IS_OK(status) &&
2763                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
2764                         break;
2765
2766                 for (i=0; i<q2.out.info.info5.count; i++) {
2767                         int j;
2768                         const char *name = q2.out.info.info5.entries[i].account_name.string;
2769                         BOOL found = False;
2770                         for (j=0; j<num_names; j++) {
2771                                 if (names[j] == NULL)
2772                                         continue;
2773                                 /* Hmm. No strequal in samba4 */
2774                                 if (strequal(names[j], name)) {
2775                                         names[j] = NULL;
2776                                         found = True;
2777                                         break;
2778                                 }
2779                         }
2780
2781                         if (!found) {
2782                                 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
2783                                        name);
2784                                 ret = False;
2785                         }
2786                 }
2787                 q2.in.start_idx += q2.out.info.info5.count;
2788         }
2789
2790         if (!NT_STATUS_IS_OK(status)) {
2791                 printf("QueryDisplayInfo level 5 failed - %s\n",
2792                        nt_errstr(status));
2793                 ret = False;
2794         }
2795
2796         for (i=0; i<num_names; i++) {
2797                 if (names[i] != NULL) {
2798                         printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
2799                                names[i]);
2800                         ret = False;
2801                 }
2802         }
2803
2804         return ret;
2805 }
2806
2807 static BOOL test_DeleteDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2808                                    struct policy_handle *group_handle)
2809 {
2810         struct samr_DeleteDomainGroup d;
2811         NTSTATUS status;
2812         BOOL ret = True;
2813
2814         printf("Testing DeleteDomainGroup\n");
2815
2816         d.in.group_handle = group_handle;
2817         d.out.group_handle = group_handle;
2818
2819         status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2820         if (!NT_STATUS_IS_OK(status)) {
2821                 printf("DeleteDomainGroup failed - %s\n", nt_errstr(status));
2822                 ret = False;
2823         }
2824
2825         return ret;
2826 }
2827
2828 static BOOL test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2829                                             struct policy_handle *domain_handle)
2830 {
2831         struct samr_TestPrivateFunctionsDomain r;
2832         NTSTATUS status;
2833         BOOL ret = True;
2834
2835         printf("Testing TestPrivateFunctionsDomain\n");
2836
2837         r.in.domain_handle = domain_handle;
2838
2839         status = dcerpc_samr_TestPrivateFunctionsDomain(p, mem_ctx, &r);
2840         if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
2841                 printf("TestPrivateFunctionsDomain failed - %s\n", nt_errstr(status));
2842                 ret = False;
2843         }
2844
2845         return ret;
2846 }
2847
2848 static BOOL test_RidToSid(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2849                           struct dom_sid *domain_sid,
2850                           struct policy_handle *domain_handle)
2851 {
2852         struct samr_RidToSid r;
2853         NTSTATUS status;
2854         BOOL ret = True;
2855         struct dom_sid *calc_sid;
2856         int rids[] = { 0, 42, 512, 10200 };
2857         int i;
2858
2859         for (i=0;i<ARRAY_SIZE(rids);i++) {
2860         
2861                 printf("Testing RidToSid\n");
2862                 
2863                 calc_sid = dom_sid_dup(mem_ctx, domain_sid);
2864                 r.in.domain_handle = domain_handle;
2865                 r.in.rid = rids[i];
2866                 
2867                 status = dcerpc_samr_RidToSid(p, mem_ctx, &r);
2868                 if (!NT_STATUS_IS_OK(status)) {
2869                         printf("RidToSid for %d failed - %s\n", rids[i], nt_errstr(status));
2870                         ret = False;
2871                 } else {
2872                         calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
2873
2874                         if (!dom_sid_equal(calc_sid, r.out.sid)) {
2875                                 printf("RidToSid for %d failed - got %s, expected %s\n", rids[i], 
2876                                        dom_sid_string(mem_ctx, r.out.sid), 
2877                                        dom_sid_string(mem_ctx, calc_sid));
2878                                 ret = False;
2879                         }
2880                 }
2881         }
2882
2883         return ret;
2884 }
2885
2886 static BOOL test_GetBootKeyInformation(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2887                                        struct policy_handle *domain_handle)
2888 {
2889         struct samr_GetBootKeyInformation r;
2890         NTSTATUS status;
2891         BOOL ret = True;
2892
2893         printf("Testing GetBootKeyInformation\n");
2894
2895         r.in.domain_handle = domain_handle;
2896
2897         status = dcerpc_samr_GetBootKeyInformation(p, mem_ctx, &r);
2898         if (!NT_STATUS_IS_OK(status)) {
2899                 /* w2k3 seems to fail this sometimes and pass it sometimes */
2900                 printf("GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
2901         }
2902
2903         return ret;
2904 }
2905
2906 static BOOL test_AddGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2907                                 struct policy_handle *domain_handle,
2908                                 struct policy_handle *group_handle)
2909 {
2910         NTSTATUS status;
2911         struct samr_AddGroupMember r;
2912         struct samr_DeleteGroupMember d;
2913         struct samr_QueryGroupMember q;
2914         struct samr_SetMemberAttributesOfGroup s;
2915         BOOL ret = True;
2916         uint32_t rid;
2917
2918         status = test_LookupName(p, mem_ctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
2919         if (!NT_STATUS_IS_OK(status)) {
2920                 return False;
2921         }
2922
2923         r.in.group_handle = group_handle;
2924         r.in.rid = rid;
2925         r.in.flags = 0; /* ??? */
2926
2927         printf("Testing AddGroupMember and DeleteGroupMember\n");
2928
2929         d.in.group_handle = group_handle;
2930         d.in.rid = rid;
2931
2932         status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
2933         if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_NOT_IN_GROUP, status)) {
2934                 printf("DeleteGroupMember gave %s - should be NT_STATUS_MEMBER_NOT_IN_GROUP\n", 
2935                        nt_errstr(status));
2936                 return False;
2937         }
2938
2939         status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
2940         if (!NT_STATUS_IS_OK(status)) {
2941                 printf("AddGroupMember failed - %s\n", nt_errstr(status));
2942                 return False;
2943         }
2944
2945         status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
2946         if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_IN_GROUP, status)) {
2947                 printf("AddGroupMember gave %s - should be NT_STATUS_MEMBER_IN_GROUP\n", 
2948                        nt_errstr(status));
2949                 return False;
2950         }
2951
2952         /* this one is quite strange. I am using random inputs in the
2953            hope of triggering an error that might give us a clue */
2954         s.in.group_handle = group_handle;
2955         s.in.unknown1 = random();
2956         s.in.unknown2 = random();
2957
2958         status = dcerpc_samr_SetMemberAttributesOfGroup(p, mem_ctx, &s);
2959         if (!NT_STATUS_IS_OK(status)) {
2960                 printf("SetMemberAttributesOfGroup failed - %s\n", nt_errstr(status));
2961                 return False;
2962         }
2963
2964         q.in.group_handle = group_handle;
2965
2966         status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &q);
2967         if (!NT_STATUS_IS_OK(status)) {
2968                 printf("QueryGroupMember failed - %s\n", nt_errstr(status));
2969                 return False;
2970         }
2971
2972         status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
2973         if (!NT_STATUS_IS_OK(status)) {
2974                 printf("DeleteGroupMember failed - %s\n", nt_errstr(status));
2975                 return False;
2976         }
2977
2978         status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
2979         if (!NT_STATUS_IS_OK(status)) {
2980                 printf("AddGroupMember failed - %s\n", nt_errstr(status));
2981                 return False;
2982         }
2983
2984         return ret;
2985 }
2986
2987
2988 static BOOL test_CreateDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2989                                    struct policy_handle *domain_handle, struct policy_handle *group_handle)
2990 {
2991         NTSTATUS status;
2992         struct samr_CreateDomainGroup r;
2993         uint32_t rid;
2994         struct lsa_String name;
2995         BOOL ret = True;
2996
2997         init_lsa_String(&name, TEST_GROUPNAME);
2998
2999         r.in.domain_handle = domain_handle;
3000         r.in.name = &name;
3001         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3002         r.out.group_handle = group_handle;
3003         r.out.rid = &rid;
3004
3005         printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
3006
3007         status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
3008
3009         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
3010                 printf("Server refused create of '%s'\n", r.in.name->string);
3011                 ZERO_STRUCTP(group_handle);
3012                 return True;
3013         }
3014
3015         if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS) ||
3016             NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
3017                 if (!test_DeleteGroup_byname(p, mem_ctx, domain_handle, r.in.name->string)) {
3018                         return False;
3019                 }
3020                 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
3021         }
3022         if (!NT_STATUS_IS_OK(status)) {
3023                 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
3024                 return False;
3025         }
3026
3027         if (!test_AddGroupMember(p, mem_ctx, domain_handle, group_handle)) {
3028                 ret = False;
3029         }
3030
3031         if (!test_SetGroupInfo(p, mem_ctx, group_handle)) {
3032                 ret = False;
3033         }
3034
3035         return ret;
3036 }
3037
3038
3039 /*
3040   its not totally clear what this does. It seems to accept any sid you like.
3041 */
3042 static BOOL test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p, 
3043                                                TALLOC_CTX *mem_ctx, 
3044                                                struct policy_handle *domain_handle)
3045 {
3046         NTSTATUS status;
3047         struct samr_RemoveMemberFromForeignDomain r;
3048
3049         r.in.domain_handle = domain_handle;
3050         r.in.sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-12-34-56-78");
3051
3052         status = dcerpc_samr_RemoveMemberFromForeignDomain(p, mem_ctx, &r);
3053         if (!NT_STATUS_IS_OK(status)) {
3054                 printf("RemoveMemberFromForeignDomain failed - %s\n", nt_errstr(status));
3055                 return False;
3056         }
3057
3058         return True;
3059 }
3060
3061
3062
3063 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3064                          struct policy_handle *handle);
3065
3066 static BOOL test_OpenDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3067                             struct policy_handle *handle, struct dom_sid *sid)
3068 {
3069         NTSTATUS status;
3070         struct samr_OpenDomain r;
3071         struct policy_handle domain_handle;
3072         struct policy_handle user_handle;
3073         struct policy_handle alias_handle;
3074         struct policy_handle group_handle;
3075         BOOL ret = True;
3076
3077         ZERO_STRUCT(user_handle);
3078         ZERO_STRUCT(alias_handle);
3079         ZERO_STRUCT(group_handle);
3080         ZERO_STRUCT(domain_handle);
3081
3082         printf("Testing OpenDomain\n");
3083
3084         r.in.connect_handle = handle;
3085         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3086         r.in.sid = sid;
3087         r.out.domain_handle = &domain_handle;
3088
3089         status = dcerpc_samr_OpenDomain(p, mem_ctx, &r);
3090         if (!NT_STATUS_IS_OK(status)) {
3091                 printf("OpenDomain failed - %s\n", nt_errstr(status));
3092                 return False;
3093         }
3094
3095         /* run the domain tests with the main handle closed - this tests
3096            the servers reference counting */
3097         ret &= test_samr_handle_Close(p, mem_ctx, handle);
3098
3099         ret &= test_QuerySecurity(p, mem_ctx, &domain_handle);
3100         ret &= test_RemoveMemberFromForeignDomain(p, mem_ctx, &domain_handle);
3101         ret &= test_CreateUser2(p, mem_ctx, &domain_handle);
3102         ret &= test_CreateUser(p, mem_ctx, &domain_handle, &user_handle);
3103         ret &= test_CreateAlias(p, mem_ctx, &domain_handle, &alias_handle, sid);
3104         ret &= test_CreateDomainGroup(p, mem_ctx, &domain_handle, &group_handle);
3105         ret &= test_QueryDomainInfo(p, mem_ctx, &domain_handle);
3106         ret &= test_QueryDomainInfo2(p, mem_ctx, &domain_handle);
3107         ret &= test_EnumDomainUsers(p, mem_ctx, &domain_handle);
3108         ret &= test_EnumDomainUsers_async(p, mem_ctx, &domain_handle);
3109         ret &= test_EnumDomainGroups(p, mem_ctx, &domain_handle);
3110         ret &= test_EnumDomainAliases(p, mem_ctx, &domain_handle);
3111         ret &= test_QueryDisplayInfo(p, mem_ctx, &domain_handle);
3112         ret &= test_QueryDisplayInfo2(p, mem_ctx, &domain_handle);
3113         ret &= test_QueryDisplayInfo3(p, mem_ctx, &domain_handle);
3114         ret &= test_QueryDisplayInfo_continue(p, mem_ctx, &domain_handle);
3115         ret &= test_GetDisplayEnumerationIndex(p, mem_ctx, &domain_handle);
3116         ret &= test_GetDisplayEnumerationIndex2(p, mem_ctx, &domain_handle);
3117         ret &= test_GroupList(p, mem_ctx, &domain_handle);
3118         ret &= test_TestPrivateFunctionsDomain(p, mem_ctx, &domain_handle);
3119         ret &= test_RidToSid(p, mem_ctx, sid, &domain_handle);
3120         ret &= test_GetBootKeyInformation(p, mem_ctx, &domain_handle);
3121
3122         if (!policy_handle_empty(&user_handle) &&
3123             !test_DeleteUser(p, mem_ctx, &user_handle)) {
3124                 ret = False;
3125         }
3126
3127         if (!policy_handle_empty(&alias_handle) &&
3128             !test_DeleteAlias(p, mem_ctx, &alias_handle)) {
3129                 ret = False;
3130         }
3131
3132         if (!policy_handle_empty(&group_handle) &&
3133             !test_DeleteDomainGroup(p, mem_ctx, &group_handle)) {
3134                 ret = False;
3135         }
3136
3137         ret &= test_samr_handle_Close(p, mem_ctx, &domain_handle);
3138
3139         /* reconnect the main handle */
3140         ret &= test_Connect(p, mem_ctx, handle);
3141
3142         return ret;
3143 }
3144
3145 static BOOL test_LookupDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3146                               struct policy_handle *handle, struct lsa_String *domain)
3147 {
3148         NTSTATUS status;
3149         struct samr_LookupDomain r;
3150         struct lsa_String n2;
3151         BOOL ret = True;
3152
3153         printf("Testing LookupDomain(%s)\n", domain->string);
3154
3155         /* check for correct error codes */
3156         r.in.connect_handle = handle;
3157         r.in.domain_name = &n2;
3158         n2.string = NULL;
3159
3160         status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3161         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_PARAMETER, status)) {
3162                 printf("failed: LookupDomain expected NT_STATUS_INVALID_PARAMETER - %s\n", nt_errstr(status));
3163                 ret = False;
3164         }
3165
3166         n2.string = "xxNODOMAINxx";
3167
3168         status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3169         if (!NT_STATUS_EQUAL(NT_STATUS_NO_SUCH_DOMAIN, status)) {
3170                 printf("failed: LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN - %s\n", nt_errstr(status));
3171                 ret = False;
3172         }
3173
3174         r.in.connect_handle = handle;
3175         r.in.domain_name = domain;
3176
3177         status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3178         if (!NT_STATUS_IS_OK(status)) {
3179                 printf("LookupDomain failed - %s\n", nt_errstr(status));
3180                 ret = False;
3181         }
3182
3183         if (!test_GetDomPwInfo(p, mem_ctx, domain)) {
3184                 ret = False;
3185         }
3186
3187         if (!test_OpenDomain(p, mem_ctx, handle, r.out.sid)) {
3188                 ret = False;
3189         }
3190
3191         return ret;
3192 }
3193
3194
3195 static BOOL test_EnumDomains(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3196                              struct policy_handle *handle)
3197 {
3198         NTSTATUS status;
3199         struct samr_EnumDomains r;
3200         uint32_t resume_handle = 0;
3201         int i;
3202         BOOL ret = True;
3203
3204         r.in.connect_handle = handle;
3205         r.in.resume_handle = &resume_handle;
3206         r.in.buf_size = (uint32_t)-1;
3207         r.out.resume_handle = &resume_handle;
3208
3209         status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
3210         if (!NT_STATUS_IS_OK(status)) {
3211                 printf("EnumDomains failed - %s\n", nt_errstr(status));
3212                 return False;
3213         }
3214
3215         if (!r.out.sam) {
3216                 return False;
3217         }
3218
3219         for (i=0;i<r.out.sam->count;i++) {
3220                 if (!test_LookupDomain(p, mem_ctx, handle, 
3221                                        &r.out.sam->entries[i].name)) {
3222                         ret = False;
3223                 }
3224         }
3225
3226         status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
3227         if (!NT_STATUS_IS_OK(status)) {
3228                 printf("EnumDomains failed - %s\n", nt_errstr(status));
3229                 return False;
3230         }
3231
3232         return ret;
3233 }
3234
3235
3236 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3237                          struct policy_handle *handle)
3238 {
3239         NTSTATUS status;
3240         struct samr_Connect r;
3241         struct samr_Connect2 r2;
3242         struct samr_Connect3 r3;
3243         struct samr_Connect4 r4;
3244         struct samr_Connect5 r5;
3245         union samr_ConnectInfo info;
3246         struct policy_handle h;
3247         BOOL ret = True, got_handle = False;
3248
3249         printf("testing samr_Connect\n");
3250
3251         r.in.system_name = 0;
3252         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3253         r.out.connect_handle = &h;
3254
3255         status = dcerpc_samr_Connect(p, mem_ctx, &r);
3256         if (!NT_STATUS_IS_OK(status)) {
3257                 printf("Connect failed - %s\n", nt_errstr(status));
3258                 ret = False;
3259         } else {
3260                 got_handle = True;
3261                 *handle = h;
3262         }
3263
3264         printf("testing samr_Connect2\n");
3265
3266         r2.in.system_name = NULL;
3267         r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3268         r2.out.connect_handle = &h;
3269
3270         status = dcerpc_samr_Connect2(p, mem_ctx, &r2);
3271         if (!NT_STATUS_IS_OK(status)) {
3272                 printf("Connect2 failed - %s\n", nt_errstr(status));
3273                 ret = False;
3274         } else {
3275                 if (got_handle) {
3276                         test_samr_handle_Close(p, mem_ctx, handle);
3277                 }
3278                 got_handle = True;
3279                 *handle = h;
3280         }
3281
3282         printf("testing samr_Connect3\n");
3283
3284         r3.in.system_name = NULL;
3285         r3.in.unknown = 0;
3286         r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3287         r3.out.connect_handle = &h;
3288
3289         status = dcerpc_samr_Connect3(p, mem_ctx, &r3);
3290         if (!NT_STATUS_IS_OK(status)) {
3291                 printf("Connect3 failed - %s\n", nt_errstr(status));
3292                 ret = False;
3293         } else {
3294                 if (got_handle) {
3295                         test_samr_handle_Close(p, mem_ctx, handle);
3296                 }
3297                 got_handle = True;
3298                 *handle = h;
3299         }
3300
3301         printf("testing samr_Connect4\n");
3302
3303         r4.in.system_name = "";
3304         r4.in.unknown = 0;
3305         r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3306         r4.out.connect_handle = &h;
3307
3308         status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
3309         if (!NT_STATUS_IS_OK(status)) {
3310                 printf("Connect4 failed - %s\n", nt_errstr(status));
3311                 ret = False;
3312         } else {
3313                 if (got_handle) {
3314                         test_samr_handle_Close(p, mem_ctx, handle);
3315                 }
3316                 got_handle = True;
3317                 *handle = h;
3318         }
3319
3320         printf("testing samr_Connect5\n");
3321
3322         info.info1.unknown1 = 0;
3323         info.info1.unknown2 = 0;
3324
3325         r5.in.system_name = "";
3326         r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3327         r5.in.level = 1;
3328         r5.in.info = &info;
3329         r5.out.info = &info;
3330         r5.out.connect_handle = &h;
3331
3332         status = dcerpc_samr_Connect5(p, mem_ctx, &r5);
3333         if (!NT_STATUS_IS_OK(status)) {
3334                 printf("Connect5 failed - %s\n", nt_errstr(status));
3335                 ret = False;
3336         } else {
3337                 if (got_handle) {
3338                         test_samr_handle_Close(p, mem_ctx, handle);
3339                 }
3340                 got_handle = True;
3341                 *handle = h;
3342         }
3343
3344         return ret;
3345 }
3346
3347
3348 BOOL torture_rpc_samr(void)
3349 {
3350         NTSTATUS status;
3351         struct dcerpc_pipe *p;
3352         TALLOC_CTX *mem_ctx;
3353         BOOL ret = True;
3354         struct policy_handle handle;
3355
3356         mem_ctx = talloc_init("torture_rpc_samr");
3357
3358         status = torture_rpc_connection(mem_ctx, &p, &dcerpc_table_samr);
3359         if (!NT_STATUS_IS_OK(status)) {
3360                 talloc_free(mem_ctx);
3361                 return False;
3362         }
3363
3364         if (!test_Connect(p, mem_ctx, &handle)) {
3365                 ret = False;
3366         }
3367
3368         if (!test_QuerySecurity(p, mem_ctx, &handle)) {
3369                 ret = False;
3370         }
3371
3372         if (!test_EnumDomains(p, mem_ctx, &handle)) {
3373                 ret = False;
3374         }
3375
3376         if (!test_SetDsrmPassword(p, mem_ctx, &handle)) {
3377                 ret = False;
3378         }
3379
3380         if (!test_Shutdown(p, mem_ctx, &handle)) {
3381                 ret = False;
3382         }
3383
3384         if (!test_samr_handle_Close(p, mem_ctx, &handle)) {
3385                 ret = False;
3386         }
3387
3388         talloc_free(mem_ctx);
3389
3390         return ret;
3391 }
3392