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