r5879: Rename SAMR_FIELD_WORKSTATION to SAMR_FIELD_WORKSTATIONS - it is a list.
[ira/wip.git] / source4 / torture / rpc / samr.c
1 /* 
2    Unix SMB/CIFS implementation.
3    test suite for samr rpc operations
4
5    Copyright (C) Andrew Tridgell 2003
6    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 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_samr_String(struct samr_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 samr_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_samr_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_samr_String(&u.info ## lvl1.field1, value); \
230                 TESTCALL(SetUserInfo, s) \
231                 TESTCALL(SetUserInfo2, s2) \
232                 init_samr_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 2 : init_samr_String(&r.in.info->name,TEST_ALIASNAME); break;
654                     case 3 : init_samr_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 samr_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 samr_String sname[2];
774
775         init_samr_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_samr_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_samr_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 samr_AsciiName 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 samr_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 samr_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 samr_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_samr_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 static BOOL test_ChangePasswordUser3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1086                                      struct policy_handle *handle, 
1087                                      int policy_min_pw_len,
1088                                      char **password)
1089 {
1090         NTSTATUS status;
1091         struct samr_ChangePasswordUser3 r;
1092         BOOL ret = True;
1093         struct samr_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_samr_String(&account, TEST_ACCOUNT_NAME);
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, handle, policy_min_pw_len, password);
1137                 } else {
1138                         printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1139                         ret = False;
1140                 }
1141         } else if (!NT_STATUS_IS_OK(status)) {
1142                 printf("ChangePasswordUser3 failed - %s\n", nt_errstr(status));
1143                 ret = False;
1144         } else {
1145                 *password = newpass;
1146         }
1147
1148         return ret;
1149 }
1150
1151
1152 static BOOL test_GetMembersInAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1153                                   struct policy_handle *alias_handle)
1154 {
1155         struct samr_GetMembersInAlias r;
1156         struct lsa_SidArray sids;
1157         NTSTATUS status;
1158         BOOL     ret = True;
1159
1160         printf("Testing GetMembersInAlias\n");
1161
1162         r.in.alias_handle = alias_handle;
1163         r.out.sids = &sids;
1164
1165         status = dcerpc_samr_GetMembersInAlias(p, mem_ctx, &r);
1166         if (!NT_STATUS_IS_OK(status)) {
1167                 printf("GetMembersInAlias failed - %s\n",
1168                        nt_errstr(status));
1169                 ret = False;
1170         }
1171
1172         return ret;
1173 }
1174
1175 static BOOL test_AddMemberToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1176                                   struct policy_handle *alias_handle,
1177                                   const struct dom_sid *domain_sid)
1178 {
1179         struct samr_AddAliasMember r;
1180         struct samr_DeleteAliasMember d;
1181         NTSTATUS status;
1182         BOOL ret = True;
1183         struct dom_sid *sid;
1184
1185         sid = dom_sid_add_rid(mem_ctx, domain_sid, 512);
1186
1187         printf("testing AddAliasMember\n");
1188         r.in.alias_handle = alias_handle;
1189         r.in.sid = sid;
1190
1191         status = dcerpc_samr_AddAliasMember(p, mem_ctx, &r);
1192         if (!NT_STATUS_IS_OK(status)) {
1193                 printf("AddAliasMember failed - %s\n", nt_errstr(status));
1194                 ret = False;
1195         }
1196
1197         d.in.alias_handle = alias_handle;
1198         d.in.sid = sid;
1199
1200         status = dcerpc_samr_DeleteAliasMember(p, mem_ctx, &d);
1201         if (!NT_STATUS_IS_OK(status)) {
1202                 printf("DelAliasMember failed - %s\n", nt_errstr(status));
1203                 ret = False;
1204         }
1205
1206         return ret;
1207 }
1208
1209 static BOOL test_AddMultipleMembersToAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1210                                            struct policy_handle *alias_handle)
1211 {
1212         struct samr_AddMultipleMembersToAlias a;
1213         struct samr_RemoveMultipleMembersFromAlias r;
1214         NTSTATUS status;
1215         BOOL ret = True;
1216         struct lsa_SidArray sids;
1217
1218         printf("testing AddMultipleMembersToAlias\n");
1219         a.in.alias_handle = alias_handle;
1220         a.in.sids = &sids;
1221
1222         sids.num_sids = 3;
1223         sids.sids = talloc_array(mem_ctx, struct lsa_SidPtr, 3);
1224
1225         sids.sids[0].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-1");
1226         sids.sids[1].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-2");
1227         sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-3");
1228
1229         status = dcerpc_samr_AddMultipleMembersToAlias(p, mem_ctx, &a);
1230         if (!NT_STATUS_IS_OK(status)) {
1231                 printf("AddMultipleMembersToAlias failed - %s\n", nt_errstr(status));
1232                 ret = False;
1233         }
1234
1235
1236         printf("testing RemoveMultipleMembersFromAlias\n");
1237         r.in.alias_handle = alias_handle;
1238         r.in.sids = &sids;
1239
1240         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1241         if (!NT_STATUS_IS_OK(status)) {
1242                 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1243                 ret = False;
1244         }
1245
1246         /* strange! removing twice doesn't give any error */
1247         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1248         if (!NT_STATUS_IS_OK(status)) {
1249                 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1250                 ret = False;
1251         }
1252
1253         /* but removing an alias that isn't there does */
1254         sids.sids[2].sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1-2-3-4");
1255
1256         status = dcerpc_samr_RemoveMultipleMembersFromAlias(p, mem_ctx, &r);
1257         if (!NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) {
1258                 printf("RemoveMultipleMembersFromAlias failed - %s\n", nt_errstr(status));
1259                 ret = False;
1260         }
1261
1262         return ret;
1263 }
1264
1265 static BOOL test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1266                                             struct policy_handle *user_handle)
1267 {
1268         struct samr_TestPrivateFunctionsUser r;
1269         NTSTATUS status;
1270         BOOL ret = True;
1271
1272         printf("Testing TestPrivateFunctionsUser\n");
1273
1274         r.in.user_handle = user_handle;
1275
1276         status = dcerpc_samr_TestPrivateFunctionsUser(p, mem_ctx, &r);
1277         if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
1278                 printf("TestPrivateFunctionsUser failed - %s\n", nt_errstr(status));
1279                 ret = False;
1280         }
1281
1282         return ret;
1283 }
1284
1285
1286 static BOOL test_user_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1287                           struct policy_handle *handle, uint32_t base_acct_flags, 
1288                           const char *base_acct_name)
1289 {
1290         BOOL ret = True;
1291
1292         if (!test_QuerySecurity(p, mem_ctx, handle)) {
1293                 ret = False;
1294         }
1295
1296         if (!test_QueryUserInfo(p, mem_ctx, handle)) {
1297                 ret = False;
1298         }
1299
1300         if (!test_QueryUserInfo2(p, mem_ctx, handle)) {
1301                 ret = False;
1302         }
1303
1304         if (!test_SetUserInfo(p, mem_ctx, handle, base_acct_flags,
1305                               base_acct_name)) {
1306                 ret = False;
1307         }       
1308
1309         if (!test_GetUserPwInfo(p, mem_ctx, handle)) {
1310                 ret = False;
1311         }
1312
1313         if (!test_TestPrivateFunctionsUser(p, mem_ctx, handle)) {
1314                 ret = False;
1315         }
1316
1317         return ret;
1318 }
1319
1320 static BOOL test_alias_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1321                            struct policy_handle *alias_handle,
1322                            const struct dom_sid *domain_sid)
1323 {
1324         BOOL ret = True;
1325
1326         if (!test_QuerySecurity(p, mem_ctx, alias_handle)) {
1327                 ret = False;
1328         }
1329
1330         if (!test_QueryAliasInfo(p, mem_ctx, alias_handle)) {
1331                 ret = False;
1332         }
1333
1334         if (!test_SetAliasInfo(p, mem_ctx, alias_handle)) {
1335                 ret = False;
1336         }
1337
1338         if (!test_AddMemberToAlias(p, mem_ctx, alias_handle, domain_sid)) {
1339                 ret = False;
1340         }
1341
1342         if (!test_AddMultipleMembersToAlias(p, mem_ctx, alias_handle)) {
1343                 ret = False;
1344         }
1345
1346         return ret;
1347 }
1348
1349
1350 BOOL test_DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1351                             struct policy_handle *handle, const char *name)
1352 {
1353         NTSTATUS status;
1354         struct samr_DeleteUser d;
1355         struct policy_handle user_handle;
1356         uint32_t rid;
1357
1358         status = test_LookupName(p, mem_ctx, handle, name, &rid);
1359         if (!NT_STATUS_IS_OK(status)) {
1360                 goto failed;
1361         }
1362
1363         status = test_OpenUser_byname(p, mem_ctx, handle, name, &user_handle);
1364         if (!NT_STATUS_IS_OK(status)) {
1365                 goto failed;
1366         }
1367
1368         d.in.user_handle = &user_handle;
1369         d.out.user_handle = &user_handle;
1370         status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
1371         if (!NT_STATUS_IS_OK(status)) {
1372                 goto failed;
1373         }
1374
1375         return True;
1376
1377 failed:
1378         printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
1379         return False;
1380 }
1381
1382
1383 static BOOL test_DeleteGroup_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1384                                     struct policy_handle *handle, const char *name)
1385 {
1386         NTSTATUS status;
1387         struct samr_OpenGroup r;
1388         struct samr_DeleteDomainGroup d;
1389         struct policy_handle group_handle;
1390         uint32_t rid;
1391
1392         status = test_LookupName(p, mem_ctx, handle, name, &rid);
1393         if (!NT_STATUS_IS_OK(status)) {
1394                 goto failed;
1395         }
1396
1397         r.in.domain_handle = handle;
1398         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1399         r.in.rid = rid;
1400         r.out.group_handle = &group_handle;
1401         status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
1402         if (!NT_STATUS_IS_OK(status)) {
1403                 goto failed;
1404         }
1405
1406         d.in.group_handle = &group_handle;
1407         d.out.group_handle = &group_handle;
1408         status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
1409         if (!NT_STATUS_IS_OK(status)) {
1410                 goto failed;
1411         }
1412
1413         return True;
1414
1415 failed:
1416         printf("DeleteGroup_byname(%s) failed - %s\n", name, nt_errstr(status));
1417         return False;
1418 }
1419
1420
1421 static BOOL test_DeleteAlias_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1422                                    struct policy_handle *domain_handle, const char *name)
1423 {
1424         NTSTATUS status;
1425         struct samr_OpenAlias r;
1426         struct samr_DeleteDomAlias d;
1427         struct policy_handle alias_handle;
1428         uint32_t rid;
1429
1430         printf("testing DeleteAlias_byname\n");
1431
1432         status = test_LookupName(p, mem_ctx, domain_handle, name, &rid);
1433         if (!NT_STATUS_IS_OK(status)) {
1434                 goto failed;
1435         }
1436
1437         r.in.domain_handle = domain_handle;
1438         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1439         r.in.rid = rid;
1440         r.out.alias_handle = &alias_handle;
1441         status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
1442         if (!NT_STATUS_IS_OK(status)) {
1443                 goto failed;
1444         }
1445
1446         d.in.alias_handle = &alias_handle;
1447         d.out.alias_handle = &alias_handle;
1448         status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
1449         if (!NT_STATUS_IS_OK(status)) {
1450                 goto failed;
1451         }
1452
1453         return True;
1454
1455 failed:
1456         printf("DeleteUser_byname(%s) failed - %s\n", name, nt_errstr(status));
1457         return False;
1458 }
1459
1460 static BOOL test_DeleteAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1461                                      struct policy_handle *alias_handle)
1462 {
1463         struct samr_DeleteDomAlias d;
1464         NTSTATUS status;
1465         BOOL ret = True;
1466         printf("Testing DeleteAlias\n");
1467
1468         d.in.alias_handle = alias_handle;
1469         d.out.alias_handle = alias_handle;
1470
1471         status = dcerpc_samr_DeleteDomAlias(p, mem_ctx, &d);
1472         if (!NT_STATUS_IS_OK(status)) {
1473                 printf("DeleteAlias failed - %s\n", nt_errstr(status));
1474                 ret = False;
1475         }
1476
1477         return ret;
1478 }
1479
1480 static BOOL test_CreateAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1481                             struct policy_handle *domain_handle, 
1482                              struct policy_handle *alias_handle, 
1483                              const struct dom_sid *domain_sid)
1484 {
1485         NTSTATUS status;
1486         struct samr_CreateDomAlias r;
1487         struct samr_String name;
1488         uint32_t rid;
1489         BOOL ret = True;
1490
1491         init_samr_String(&name, TEST_ALIASNAME);
1492         r.in.domain_handle = domain_handle;
1493         r.in.aliasname = &name;
1494         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1495         r.out.alias_handle = alias_handle;
1496         r.out.rid = &rid;
1497
1498         printf("Testing CreateAlias (%s)\n", r.in.aliasname->string);
1499
1500         status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
1501
1502         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1503                 printf("Server refused create of '%s'\n", r.in.aliasname->string);
1504                 return True;
1505         }
1506
1507         if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
1508                 if (!test_DeleteAlias_byname(p, mem_ctx, domain_handle, r.in.aliasname->string)) {
1509                         return False;
1510                 }
1511                 status = dcerpc_samr_CreateDomAlias(p, mem_ctx, &r);
1512         }
1513
1514         if (!NT_STATUS_IS_OK(status)) {
1515                 printf("CreateAlias failed - %s\n", nt_errstr(status));
1516                 return False;
1517         }
1518
1519         if (!test_alias_ops(p, mem_ctx, alias_handle, domain_sid)) {
1520                 ret = False;
1521         }
1522
1523         return ret;
1524 }
1525
1526 static BOOL test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1527                                 struct policy_handle *domain_handle, char **password)
1528 {
1529         BOOL ret = True;
1530
1531         if (!*password) {
1532                 return False;
1533         }
1534
1535         if (!test_ChangePasswordUser(p, mem_ctx, domain_handle, password)) {
1536                 ret = False;
1537         }
1538
1539         if (!test_ChangePasswordUser2(p, mem_ctx, domain_handle, password)) {
1540                 ret = False;
1541         }
1542
1543         if (!test_OemChangePasswordUser2(p, mem_ctx, domain_handle, password)) {
1544                 ret = False;
1545         }
1546
1547         /* we change passwords twice - this has the effect of verifying
1548            they were changed correctly for the final call */
1549         if (!test_ChangePasswordUser3(p, mem_ctx, domain_handle, 0, password)) {
1550                 ret = False;
1551         }
1552
1553         if (!test_ChangePasswordUser3(p, mem_ctx, domain_handle, 0, password)) {
1554                 ret = False;
1555         }
1556
1557         return ret;
1558 }
1559
1560 static BOOL test_CreateUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1561                             struct policy_handle *domain_handle, struct policy_handle *user_handle)
1562 {
1563         NTSTATUS status;
1564         struct samr_CreateUser r;
1565         struct samr_QueryUserInfo q;
1566         uint32_t rid;
1567         char *password = NULL;
1568
1569         int i;
1570         const uint32_t password_fields[] = {
1571                 SAMR_FIELD_PASSWORD,
1572                 SAMR_FIELD_PASSWORD2,
1573                 SAMR_FIELD_PASSWORD | SAMR_FIELD_PASSWORD2,
1574                 0
1575         };
1576
1577         /* This call creates a 'normal' account - check that it really does */
1578         const uint32_t acct_flags = ACB_NORMAL;
1579         struct samr_String name;
1580         BOOL ret = True;
1581
1582         init_samr_String(&name, TEST_ACCOUNT_NAME);
1583
1584         r.in.domain_handle = domain_handle;
1585         r.in.account_name = &name;
1586         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1587         r.out.user_handle = user_handle;
1588         r.out.rid = &rid;
1589
1590         printf("Testing CreateUser(%s)\n", r.in.account_name->string);
1591
1592         status = dcerpc_samr_CreateUser(p, mem_ctx, &r);
1593
1594         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1595                 printf("Server refused create of '%s'\n", r.in.account_name->string);
1596                 ZERO_STRUCTP(user_handle);
1597                 return True;
1598         }
1599
1600         if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
1601                 if (!test_DeleteUser_byname(p, mem_ctx, domain_handle, r.in.account_name->string)) {
1602                         return False;
1603                 }
1604                 status = dcerpc_samr_CreateUser(p, mem_ctx, &r);
1605         }
1606         if (!NT_STATUS_IS_OK(status)) {
1607                 printf("CreateUser failed - %s\n", nt_errstr(status));
1608                 return False;
1609         }
1610
1611         q.in.user_handle = user_handle;
1612         q.in.level = 16;
1613
1614         status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
1615         if (!NT_STATUS_IS_OK(status)) {
1616                 printf("QueryUserInfo level %u failed - %s\n", 
1617                        q.in.level, nt_errstr(status));
1618                 ret = False;
1619         } else {
1620                 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
1621                         printf("QuerUserInfo level 16 failed, it returned 0x%08x (%u) when we expected flags of 0x%08x (%u)\n",
1622                                q.out.info->info16.acct_flags, q.out.info->info16.acct_flags, 
1623                                acct_flags, acct_flags);
1624                         ret = False;
1625                 }
1626         }
1627
1628         if (!test_user_ops(p, mem_ctx, user_handle, acct_flags, name.string)) {
1629                 ret = False;
1630         }
1631
1632         if (!test_SetUserPass(p, mem_ctx, user_handle, &password)) {
1633                 ret = False;
1634         }       
1635
1636         for (i = 0; password_fields[i]; i++) {
1637                 if (!test_SetUserPass_23(p, mem_ctx, user_handle, password_fields[i], &password)) {
1638                         ret = False;
1639                 }       
1640                 
1641                 /* check it was set right */
1642                 if (!test_ChangePasswordUser3(p, mem_ctx, domain_handle, 0, &password)) {
1643                         ret = False;
1644                 }
1645         }               
1646
1647         for (i = 0; password_fields[i]; i++) {
1648                 if (!test_SetUserPass_25(p, mem_ctx, user_handle, password_fields[i], &password)) {
1649                         ret = False;
1650                 }       
1651                 
1652                 /* check it was set right */
1653                 if (!test_ChangePasswordUser3(p, mem_ctx, domain_handle, 0, &password)) {
1654                         ret = False;
1655                 }
1656         }               
1657
1658         if (!test_SetUserPassEx(p, mem_ctx, user_handle, &password)) {
1659                 ret = False;
1660         }       
1661
1662         if (!test_ChangePassword(p, mem_ctx, domain_handle, &password)) {
1663                 ret = False;
1664         }       
1665
1666         return ret;
1667 }
1668
1669
1670 static BOOL test_DeleteUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1671                             struct policy_handle *user_handle)
1672 {
1673         struct samr_DeleteUser d;
1674         NTSTATUS status;
1675         BOOL ret = True;
1676
1677         printf("Testing DeleteUser\n");
1678
1679         d.in.user_handle = user_handle;
1680         d.out.user_handle = user_handle;
1681
1682         status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
1683         if (!NT_STATUS_IS_OK(status)) {
1684                 printf("DeleteUser failed - %s\n", nt_errstr(status));
1685                 ret = False;
1686         }
1687
1688         return ret;
1689 }
1690
1691 static BOOL test_CreateUser2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1692                              struct policy_handle *handle)
1693 {
1694         NTSTATUS status;
1695         struct samr_CreateUser2 r;
1696         struct samr_QueryUserInfo q;
1697         struct samr_DeleteUser d;
1698         struct policy_handle user_handle;
1699         uint32_t rid;
1700         struct samr_String name;
1701         BOOL ret = True;
1702         int i;
1703
1704         struct {
1705                 uint32_t acct_flags;
1706                 const char *account_name;
1707                 NTSTATUS nt_status;
1708         } account_types[] = {
1709                 { ACB_NORMAL, TEST_ACCOUNT_NAME, NT_STATUS_OK },
1710                 { ACB_NORMAL | ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1711                 { ACB_NORMAL | ACB_PWNOEXP, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1712                 { ACB_WSTRUST, TEST_MACHINENAME, NT_STATUS_OK },
1713                 { ACB_WSTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1714                 { ACB_WSTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1715                 { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
1716                 { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1717                 { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
1718                 { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
1719                 { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
1720                 { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
1721                 { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1722                 { ACB_DISABLED, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
1723                 { 0, NULL, NT_STATUS_INVALID_PARAMETER }
1724         };
1725
1726         for (i = 0; account_types[i].account_name; i++) {
1727                 uint32_t acct_flags = account_types[i].acct_flags;
1728                 uint32_t access_granted;
1729
1730                 init_samr_String(&name, account_types[i].account_name);
1731
1732                 r.in.domain_handle = handle;
1733                 r.in.account_name = &name;
1734                 r.in.acct_flags = acct_flags;
1735                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1736                 r.out.user_handle = &user_handle;
1737                 r.out.access_granted = &access_granted;
1738                 r.out.rid = &rid;
1739                 
1740                 printf("Testing CreateUser2(%s, 0x%x)\n", r.in.account_name->string, acct_flags);
1741                 
1742                 status = dcerpc_samr_CreateUser2(p, mem_ctx, &r);
1743                 
1744                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1745                         printf("Server refused create of '%s'\n", r.in.account_name->string);
1746                         continue;
1747
1748                 } else if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
1749                         if (!test_DeleteUser_byname(p, mem_ctx, handle, r.in.account_name->string)) {
1750                                 return False;
1751                         }
1752                         status = dcerpc_samr_CreateUser2(p, mem_ctx, &r);
1753
1754                 }
1755                 if (!NT_STATUS_EQUAL(status, account_types[i].nt_status)) {
1756                         printf("CreateUser2 failed gave incorrect error return - %s (should be %s)\n", 
1757                                nt_errstr(status), nt_errstr(account_types[i].nt_status));
1758                         ret = False;
1759                 }
1760                 
1761                 if (NT_STATUS_IS_OK(status)) {
1762                         q.in.user_handle = &user_handle;
1763                         q.in.level = 16;
1764                         
1765                         status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
1766                         if (!NT_STATUS_IS_OK(status)) {
1767                                 printf("QueryUserInfo level %u failed - %s\n", 
1768                                        q.in.level, nt_errstr(status));
1769                                 ret = False;
1770                         } else {
1771                                 if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
1772                                         printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
1773                                                q.out.info->info16.acct_flags, 
1774                                                acct_flags);
1775                                         ret = False;
1776                                 }
1777                         }
1778                 
1779                         if (!test_user_ops(p, mem_ctx, &user_handle, acct_flags, name.string)) {
1780                                 ret = False;
1781                         }
1782
1783                         printf("Testing DeleteUser (createuser2 test)\n");
1784                 
1785                         d.in.user_handle = &user_handle;
1786                         d.out.user_handle = &user_handle;
1787                         
1788                         status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
1789                         if (!NT_STATUS_IS_OK(status)) {
1790                                 printf("DeleteUser failed - %s\n", nt_errstr(status));
1791                                 ret = False;
1792                         }
1793                 }
1794         }
1795
1796         return ret;
1797 }
1798
1799 static BOOL test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1800                                 struct policy_handle *handle)
1801 {
1802         NTSTATUS status;
1803         struct samr_QueryAliasInfo r;
1804         uint16_t levels[] = {1, 2, 3};
1805         int i;
1806         BOOL ret = True;
1807
1808         for (i=0;i<ARRAY_SIZE(levels);i++) {
1809                 printf("Testing QueryAliasInfo level %u\n", levels[i]);
1810
1811                 r.in.alias_handle = handle;
1812                 r.in.level = levels[i];
1813
1814                 status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
1815                 if (!NT_STATUS_IS_OK(status)) {
1816                         printf("QueryAliasInfo level %u failed - %s\n", 
1817                                levels[i], nt_errstr(status));
1818                         ret = False;
1819                 }
1820         }
1821
1822         return ret;
1823 }
1824
1825 static BOOL test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1826                                 struct policy_handle *handle)
1827 {
1828         NTSTATUS status;
1829         struct samr_QueryGroupInfo r;
1830         uint16_t levels[] = {1, 2, 3, 4, 5};
1831         int i;
1832         BOOL ret = True;
1833
1834         for (i=0;i<ARRAY_SIZE(levels);i++) {
1835                 printf("Testing QueryGroupInfo level %u\n", levels[i]);
1836
1837                 r.in.group_handle = handle;
1838                 r.in.level = levels[i];
1839
1840                 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
1841                 if (!NT_STATUS_IS_OK(status)) {
1842                         printf("QueryGroupInfo level %u failed - %s\n", 
1843                                levels[i], nt_errstr(status));
1844                         ret = False;
1845                 }
1846         }
1847
1848         return ret;
1849 }
1850
1851 static BOOL test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1852                                   struct policy_handle *handle)
1853 {
1854         NTSTATUS status;
1855         struct samr_QueryGroupMember r;
1856         BOOL ret = True;
1857
1858         printf("Testing QueryGroupMember\n");
1859
1860         r.in.group_handle = handle;
1861
1862         status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
1863         if (!NT_STATUS_IS_OK(status)) {
1864                 printf("QueryGroupInfo failed - %s\n", nt_errstr(status));
1865                 ret = False;
1866         }
1867
1868         return ret;
1869 }
1870
1871
1872 static BOOL test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1873                               struct policy_handle *handle)
1874 {
1875         NTSTATUS status;
1876         struct samr_QueryGroupInfo r;
1877         struct samr_SetGroupInfo s;
1878         uint16_t levels[] = {1, 2, 3, 4};
1879         uint16_t set_ok[] = {0, 1, 1, 1};
1880         int i;
1881         BOOL ret = True;
1882
1883         for (i=0;i<ARRAY_SIZE(levels);i++) {
1884                 printf("Testing QueryGroupInfo level %u\n", levels[i]);
1885
1886                 r.in.group_handle = handle;
1887                 r.in.level = levels[i];
1888
1889                 status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
1890                 if (!NT_STATUS_IS_OK(status)) {
1891                         printf("QueryGroupInfo level %u failed - %s\n", 
1892                                levels[i], nt_errstr(status));
1893                         ret = False;
1894                 }
1895
1896                 printf("Testing SetGroupInfo level %u\n", levels[i]);
1897
1898                 s.in.group_handle = handle;
1899                 s.in.level = levels[i];
1900                 s.in.info = r.out.info;
1901
1902 #if 0
1903                 /* disabled this, as it changes the name only from the point of view of samr, 
1904                    but leaves the name from the point of view of w2k3 internals (and ldap). This means
1905                    the name is still reserved, so creating the old name fails, but deleting by the old name
1906                    also fails */
1907                 if (s.in.level == 2) {
1908                         init_samr_String(&s.in.info->string, "NewName");
1909                 }
1910 #endif
1911
1912                 if (s.in.level == 4) {
1913                         init_samr_String(&s.in.info->description, "test description");
1914                 }
1915
1916                 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
1917                 if (set_ok[i]) {
1918                         if (!NT_STATUS_IS_OK(status)) {
1919                                 printf("SetGroupInfo level %u failed - %s\n", 
1920                                        r.in.level, nt_errstr(status));
1921                                 ret = False;
1922                                 continue;
1923                         }
1924                 } else {
1925                         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
1926                                 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n", 
1927                                        r.in.level, nt_errstr(status));
1928                                 ret = False;
1929                                 continue;
1930                         }
1931                 }
1932         }
1933
1934         return ret;
1935 }
1936
1937 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1938                                struct policy_handle *handle)
1939 {
1940         NTSTATUS status;
1941         struct samr_QueryUserInfo r;
1942         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
1943                            11, 12, 13, 14, 16, 17, 20, 21};
1944         int i;
1945         BOOL ret = True;
1946
1947         for (i=0;i<ARRAY_SIZE(levels);i++) {
1948                 printf("Testing QueryUserInfo level %u\n", levels[i]);
1949
1950                 r.in.user_handle = handle;
1951                 r.in.level = levels[i];
1952
1953                 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
1954                 if (!NT_STATUS_IS_OK(status)) {
1955                         printf("QueryUserInfo level %u failed - %s\n", 
1956                                levels[i], nt_errstr(status));
1957                         ret = False;
1958                 }
1959         }
1960
1961         return ret;
1962 }
1963
1964 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1965                                 struct policy_handle *handle)
1966 {
1967         NTSTATUS status;
1968         struct samr_QueryUserInfo2 r;
1969         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
1970                            11, 12, 13, 14, 16, 17, 20, 21};
1971         int i;
1972         BOOL ret = True;
1973
1974         for (i=0;i<ARRAY_SIZE(levels);i++) {
1975                 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
1976
1977                 r.in.user_handle = handle;
1978                 r.in.level = levels[i];
1979
1980                 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
1981                 if (!NT_STATUS_IS_OK(status)) {
1982                         printf("QueryUserInfo2 level %u failed - %s\n", 
1983                                levels[i], nt_errstr(status));
1984                         ret = False;
1985                 }
1986         }
1987
1988         return ret;
1989 }
1990
1991 static BOOL test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1992                           struct policy_handle *handle, uint32_t rid)
1993 {
1994         NTSTATUS status;
1995         struct samr_OpenUser r;
1996         struct policy_handle user_handle;
1997         BOOL ret = True;
1998
1999         printf("Testing OpenUser(%u)\n", rid);
2000
2001         r.in.domain_handle = handle;
2002         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2003         r.in.rid = rid;
2004         r.out.user_handle = &user_handle;
2005
2006         status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
2007         if (!NT_STATUS_IS_OK(status)) {
2008                 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
2009                 return False;
2010         }
2011
2012         if (!test_QuerySecurity(p, mem_ctx, &user_handle)) {
2013                 ret = False;
2014         }
2015
2016         if (!test_QueryUserInfo(p, mem_ctx, &user_handle)) {
2017                 ret = False;
2018         }
2019
2020         if (!test_QueryUserInfo2(p, mem_ctx, &user_handle)) {
2021                 ret = False;
2022         }
2023
2024         if (!test_GetUserPwInfo(p, mem_ctx, &user_handle)) {
2025                 ret = False;
2026         }
2027
2028         if (!test_GetGroupsForUser(p,mem_ctx, &user_handle)) {
2029                 ret = False;
2030         }
2031
2032         if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
2033                 ret = False;
2034         }
2035
2036         return ret;
2037 }
2038
2039 static BOOL test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2040                            struct policy_handle *handle, uint32_t rid)
2041 {
2042         NTSTATUS status;
2043         struct samr_OpenGroup r;
2044         struct policy_handle group_handle;
2045         BOOL ret = True;
2046
2047         printf("Testing OpenGroup(%u)\n", rid);
2048
2049         r.in.domain_handle = handle;
2050         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2051         r.in.rid = rid;
2052         r.out.group_handle = &group_handle;
2053
2054         status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
2055         if (!NT_STATUS_IS_OK(status)) {
2056                 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
2057                 return False;
2058         }
2059
2060         if (!test_QuerySecurity(p, mem_ctx, &group_handle)) {
2061                 ret = False;
2062         }
2063
2064         if (!test_QueryGroupInfo(p, mem_ctx, &group_handle)) {
2065                 ret = False;
2066         }
2067
2068         if (!test_QueryGroupMember(p, mem_ctx, &group_handle)) {
2069                 ret = False;
2070         }
2071
2072         if (!test_samr_handle_Close(p, mem_ctx, &group_handle)) {
2073                 ret = False;
2074         }
2075
2076         return ret;
2077 }
2078
2079 static BOOL test_OpenAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2080                            struct policy_handle *handle, uint32_t rid)
2081 {
2082         NTSTATUS status;
2083         struct samr_OpenAlias r;
2084         struct policy_handle alias_handle;
2085         BOOL ret = True;
2086
2087         printf("Testing OpenAlias(%u)\n", rid);
2088
2089         r.in.domain_handle = handle;
2090         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2091         r.in.rid = rid;
2092         r.out.alias_handle = &alias_handle;
2093
2094         status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
2095         if (!NT_STATUS_IS_OK(status)) {
2096                 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
2097                 return False;
2098         }
2099
2100         if (!test_QuerySecurity(p, mem_ctx, &alias_handle)) {
2101                 ret = False;
2102         }
2103
2104         if (!test_QueryAliasInfo(p, mem_ctx, &alias_handle)) {
2105                 ret = False;
2106         }
2107
2108         if (!test_GetMembersInAlias(p, mem_ctx, &alias_handle)) {
2109                 ret = False;
2110         }
2111
2112         if (!test_samr_handle_Close(p, mem_ctx, &alias_handle)) {
2113                 ret = False;
2114         }
2115
2116         return ret;
2117 }
2118
2119 static BOOL test_EnumDomainUsers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2120                                  struct policy_handle *handle)
2121 {
2122         NTSTATUS status;
2123         struct samr_EnumDomainUsers r;
2124         uint32_t resume_handle=0;
2125         int i;
2126         BOOL ret = True;
2127         struct samr_LookupNames n;
2128         struct samr_LookupRids  lr ;
2129
2130         printf("Testing EnumDomainUsers\n");
2131
2132         r.in.domain_handle = handle;
2133         r.in.resume_handle = &resume_handle;
2134         r.in.acct_flags = 0;
2135         r.in.max_size = (uint32_t)-1;
2136         r.out.resume_handle = &resume_handle;
2137
2138         status = dcerpc_samr_EnumDomainUsers(p, mem_ctx, &r);
2139         if (!NT_STATUS_IS_OK(status)) {
2140                 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
2141                 return False;
2142         }
2143         
2144         if (!r.out.sam) {
2145                 return False;
2146         }
2147
2148         if (r.out.sam->count == 0) {
2149                 return True;
2150         }
2151
2152         for (i=0;i<r.out.sam->count;i++) {
2153                 if (!test_OpenUser(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2154                         ret = False;
2155                 }
2156         }
2157
2158         printf("Testing LookupNames\n");
2159         n.in.domain_handle = handle;
2160         n.in.num_names = r.out.sam->count;
2161         n.in.names = talloc_array(mem_ctx, struct samr_String, r.out.sam->count);
2162         for (i=0;i<r.out.sam->count;i++) {
2163                 n.in.names[i] = r.out.sam->entries[i].name;
2164         }
2165         status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
2166         if (!NT_STATUS_IS_OK(status)) {
2167                 printf("LookupNames failed - %s\n", nt_errstr(status));
2168                 ret = False;
2169         }
2170
2171
2172         printf("Testing LookupRids\n");
2173         lr.in.domain_handle = handle;
2174         lr.in.num_rids = r.out.sam->count;
2175         lr.in.rids = talloc_array(mem_ctx, uint32_t, r.out.sam->count);
2176         for (i=0;i<r.out.sam->count;i++) {
2177                 lr.in.rids[i] = r.out.sam->entries[i].idx;
2178         }
2179         status = dcerpc_samr_LookupRids(p, mem_ctx, &lr);
2180         if (!NT_STATUS_IS_OK(status)) {
2181                 printf("LookupRids failed - %s\n", nt_errstr(status));
2182                 ret = False;
2183         }
2184
2185         return ret;     
2186 }
2187
2188 /*
2189   try blasting the server with a bunch of sync requests
2190 */
2191 static BOOL test_EnumDomainUsers_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2192                                        struct policy_handle *handle)
2193 {
2194         NTSTATUS status;
2195         struct samr_EnumDomainUsers r;
2196         uint32_t resume_handle=0;
2197         int i;
2198 #define ASYNC_COUNT 100
2199         struct rpc_request *req[ASYNC_COUNT];
2200
2201         if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
2202                 printf("samr async test disabled - enable dangerous tests to use\n");
2203                 return True;
2204         }
2205
2206         printf("Testing EnumDomainUsers_async\n");
2207
2208         r.in.domain_handle = handle;
2209         r.in.resume_handle = &resume_handle;
2210         r.in.acct_flags = 0;
2211         r.in.max_size = (uint32_t)-1;
2212         r.out.resume_handle = &resume_handle;
2213
2214         for (i=0;i<ASYNC_COUNT;i++) {
2215                 req[i] = dcerpc_samr_EnumDomainUsers_send(p, mem_ctx, &r);
2216         }
2217
2218         for (i=0;i<ASYNC_COUNT;i++) {
2219                 status = dcerpc_ndr_request_recv(req[i]);
2220                 if (!NT_STATUS_IS_OK(status)) {
2221                         printf("EnumDomainUsers[%d] failed - %s\n", 
2222                                i, nt_errstr(status));
2223                         return False;
2224                 }
2225         }
2226         
2227         printf("%d async requests OK\n", i);
2228
2229         return True;
2230 }
2231
2232 static BOOL test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2233                                   struct policy_handle *handle)
2234 {
2235         NTSTATUS status;
2236         struct samr_EnumDomainGroups r;
2237         uint32_t resume_handle=0;
2238         int i;
2239         BOOL ret = True;
2240
2241         printf("Testing EnumDomainGroups\n");
2242
2243         r.in.domain_handle = handle;
2244         r.in.resume_handle = &resume_handle;
2245         r.in.max_size = (uint32_t)-1;
2246         r.out.resume_handle = &resume_handle;
2247
2248         status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
2249         if (!NT_STATUS_IS_OK(status)) {
2250                 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
2251                 return False;
2252         }
2253         
2254         if (!r.out.sam) {
2255                 return False;
2256         }
2257
2258         for (i=0;i<r.out.sam->count;i++) {
2259                 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2260                         ret = False;
2261                 }
2262         }
2263
2264         return ret;
2265 }
2266
2267 static BOOL test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2268                                    struct policy_handle *handle)
2269 {
2270         NTSTATUS status;
2271         struct samr_EnumDomainAliases r;
2272         uint32_t resume_handle=0;
2273         int i;
2274         BOOL ret = True;
2275
2276         printf("Testing EnumDomainAliases\n");
2277
2278         r.in.domain_handle = handle;
2279         r.in.resume_handle = &resume_handle;
2280         r.in.acct_flags = (uint32_t)-1;
2281         r.out.resume_handle = &resume_handle;
2282
2283         status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
2284         if (!NT_STATUS_IS_OK(status)) {
2285                 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
2286                 return False;
2287         }
2288         
2289         if (!r.out.sam) {
2290                 return False;
2291         }
2292
2293         for (i=0;i<r.out.sam->count;i++) {
2294                 if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2295                         ret = False;
2296                 }
2297         }
2298
2299         return ret;     
2300 }
2301
2302 static BOOL test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2303                                             struct policy_handle *handle)
2304 {
2305         NTSTATUS status;
2306         struct samr_GetDisplayEnumerationIndex r;
2307         BOOL ret = True;
2308         uint16_t levels[] = {1, 2, 3, 4, 5};
2309         uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
2310         int i;
2311
2312         for (i=0;i<ARRAY_SIZE(levels);i++) {
2313                 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
2314
2315                 r.in.domain_handle = handle;
2316                 r.in.level = levels[i];
2317                 init_samr_String(&r.in.name, TEST_ACCOUNT_NAME);
2318
2319                 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
2320
2321                 if (ok_lvl[i] && 
2322                     !NT_STATUS_IS_OK(status) &&
2323                     !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2324                         printf("GetDisplayEnumerationIndex level %u failed - %s\n", 
2325                                levels[i], nt_errstr(status));
2326                         ret = False;
2327                 }
2328
2329                 init_samr_String(&r.in.name, "zzzzzzzz");
2330
2331                 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
2332                 
2333                 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2334                         printf("GetDisplayEnumerationIndex level %u failed - %s\n", 
2335                                levels[i], nt_errstr(status));
2336                         ret = False;
2337                 }
2338         }
2339         
2340         return ret;     
2341 }
2342
2343 static BOOL test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2344                                              struct policy_handle *handle)
2345 {
2346         NTSTATUS status;
2347         struct samr_GetDisplayEnumerationIndex2 r;
2348         BOOL ret = True;
2349         uint16_t levels[] = {1, 2, 3, 4, 5};
2350         uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
2351         int i;
2352
2353         for (i=0;i<ARRAY_SIZE(levels);i++) {
2354                 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
2355
2356                 r.in.domain_handle = handle;
2357                 r.in.level = levels[i];
2358                 init_samr_String(&r.in.name, TEST_ACCOUNT_NAME);
2359
2360                 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
2361                 if (ok_lvl[i] && 
2362                     !NT_STATUS_IS_OK(status) && 
2363                     !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2364                         printf("GetDisplayEnumerationIndex2 level %u failed - %s\n", 
2365                                levels[i], nt_errstr(status));
2366                         ret = False;
2367                 }
2368
2369                 init_samr_String(&r.in.name, "zzzzzzzz");
2370
2371                 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
2372                 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2373                         printf("GetDisplayEnumerationIndex2 level %u failed - %s\n", 
2374                                levels[i], nt_errstr(status));
2375                         ret = False;
2376                 }
2377         }
2378         
2379         return ret;     
2380 }
2381
2382 static BOOL test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2383                                   struct policy_handle *handle)
2384 {
2385         NTSTATUS status;
2386         struct samr_QueryDisplayInfo r;
2387         BOOL ret = True;
2388         uint16_t levels[] = {1, 2, 3, 4, 5};
2389         int i;
2390
2391         for (i=0;i<ARRAY_SIZE(levels);i++) {
2392                 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
2393
2394                 r.in.domain_handle = handle;
2395                 r.in.level = levels[i];
2396                 r.in.start_idx = 0;
2397                 r.in.max_entries = 1000;
2398                 r.in.buf_size = (uint32_t)-1;
2399
2400                 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
2401                 if (!NT_STATUS_IS_OK(status)) {
2402                         printf("QueryDisplayInfo level %u failed - %s\n", 
2403                                levels[i], nt_errstr(status));
2404                         ret = False;
2405                 }
2406         }
2407         
2408         return ret;     
2409 }
2410
2411 static BOOL test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2412                                   struct policy_handle *handle)
2413 {
2414         NTSTATUS status;
2415         struct samr_QueryDisplayInfo2 r;
2416         BOOL ret = True;
2417         uint16_t levels[] = {1, 2, 3, 4, 5};
2418         int i;
2419
2420         for (i=0;i<ARRAY_SIZE(levels);i++) {
2421                 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
2422
2423                 r.in.domain_handle = handle;
2424                 r.in.level = levels[i];
2425                 r.in.start_idx = 0;
2426                 r.in.max_entries = 1000;
2427                 r.in.buf_size = (uint32_t)-1;
2428
2429                 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
2430                 if (!NT_STATUS_IS_OK(status)) {
2431                         printf("QueryDisplayInfo2 level %u failed - %s\n", 
2432                                levels[i], nt_errstr(status));
2433                         ret = False;
2434                 }
2435         }
2436         
2437         return ret;     
2438 }
2439
2440 static BOOL test_QueryDisplayInfo3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2441                                   struct policy_handle *handle)
2442 {
2443         NTSTATUS status;
2444         struct samr_QueryDisplayInfo3 r;
2445         BOOL ret = True;
2446         uint16_t levels[] = {1, 2, 3, 4, 5};
2447         int i;
2448
2449         for (i=0;i<ARRAY_SIZE(levels);i++) {
2450                 printf("Testing QueryDisplayInfo3 level %u\n", levels[i]);
2451
2452                 r.in.domain_handle = handle;
2453                 r.in.level = levels[i];
2454                 r.in.start_idx = 0;
2455                 r.in.max_entries = 1000;
2456                 r.in.buf_size = (uint32_t)-1;
2457
2458                 status = dcerpc_samr_QueryDisplayInfo3(p, mem_ctx, &r);
2459                 if (!NT_STATUS_IS_OK(status)) {
2460                         printf("QueryDisplayInfo3 level %u failed - %s\n", 
2461                                levels[i], nt_errstr(status));
2462                         ret = False;
2463                 }
2464         }
2465         
2466         return ret;     
2467 }
2468
2469 static BOOL test_QueryDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2470                                  struct policy_handle *handle)
2471 {
2472         NTSTATUS status;
2473         struct samr_QueryDomainInfo r;
2474         struct samr_SetDomainInfo s;
2475         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
2476         uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1,  0,  1,  0};
2477         int i;
2478         BOOL ret = True;
2479
2480         for (i=0;i<ARRAY_SIZE(levels);i++) {
2481                 printf("Testing QueryDomainInfo level %u\n", levels[i]);
2482
2483                 r.in.domain_handle = handle;
2484                 r.in.level = levels[i];
2485
2486                 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2487                 if (!NT_STATUS_IS_OK(status)) {
2488                         printf("QueryDomainInfo level %u failed - %s\n", 
2489                                r.in.level, nt_errstr(status));
2490                         ret = False;
2491                         continue;
2492                 }
2493
2494                 printf("Testing SetDomainInfo level %u\n", levels[i]);
2495
2496                 s.in.domain_handle = handle;
2497                 s.in.level = levels[i];
2498                 s.in.info = r.out.info;
2499
2500                 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2501                 if (set_ok[i]) {
2502                         if (!NT_STATUS_IS_OK(status)) {
2503                                 printf("SetDomainInfo level %u failed - %s\n", 
2504                                        r.in.level, nt_errstr(status));
2505                                 ret = False;
2506                                 continue;
2507                         }
2508                 } else {
2509                         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
2510                                 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n", 
2511                                        r.in.level, nt_errstr(status));
2512                                 ret = False;
2513                                 continue;
2514                         }
2515                 }
2516
2517                 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2518                 if (!NT_STATUS_IS_OK(status)) {
2519                         printf("QueryDomainInfo level %u failed - %s\n", 
2520                                r.in.level, nt_errstr(status));
2521                         ret = False;
2522                         continue;
2523                 }
2524         }
2525
2526         return True;    
2527 }
2528
2529
2530 static BOOL test_QueryDomainInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2531                                   struct policy_handle *handle)
2532 {
2533         NTSTATUS status;
2534         struct samr_QueryDomainInfo2 r;
2535         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
2536         int i;
2537         BOOL ret = True;
2538
2539         for (i=0;i<ARRAY_SIZE(levels);i++) {
2540                 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
2541
2542                 r.in.domain_handle = handle;
2543                 r.in.level = levels[i];
2544
2545                 status = dcerpc_samr_QueryDomainInfo2(p, mem_ctx, &r);
2546                 if (!NT_STATUS_IS_OK(status)) {
2547                         printf("QueryDomainInfo2 level %u failed - %s\n", 
2548                                r.in.level, nt_errstr(status));
2549                         ret = False;
2550                         continue;
2551                 }
2552         }
2553
2554         return True;    
2555 }
2556
2557 /* Test whether querydispinfo level 5 and enumdomgroups return the same
2558    set of group names. */
2559 static BOOL test_GroupList(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2560                            struct policy_handle *handle)
2561 {
2562         struct samr_EnumDomainGroups q1;
2563         struct samr_QueryDisplayInfo q2;
2564         NTSTATUS status;
2565         uint32_t resume_handle=0;
2566         int i;
2567         BOOL ret = True;
2568
2569         int num_names = 0;
2570         const char **names = NULL;
2571
2572         printf("Testing coherency of querydispinfo vs enumdomgroups\n");
2573
2574         q1.in.domain_handle = handle;
2575         q1.in.resume_handle = &resume_handle;
2576         q1.in.max_size = 5;
2577         q1.out.resume_handle = &resume_handle;
2578
2579         status = STATUS_MORE_ENTRIES;
2580         while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
2581                 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &q1);
2582
2583                 if (!NT_STATUS_IS_OK(status) &&
2584                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
2585                         break;
2586
2587                 for (i=0; i<q1.out.num_entries; i++) {
2588                         add_string_to_array(mem_ctx,
2589                                             q1.out.sam->entries[i].name.string,
2590                                             &names, &num_names);
2591                 }
2592         }
2593
2594         if (!NT_STATUS_IS_OK(status)) {
2595                 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
2596                 return False;
2597         }
2598         
2599         if (!q1.out.sam) {
2600                 return False;
2601         }
2602
2603         q2.in.domain_handle = handle;
2604         q2.in.level = 5;
2605         q2.in.start_idx = 0;
2606         q2.in.max_entries = 5;
2607         q2.in.buf_size = (uint32_t)-1;
2608
2609         status = STATUS_MORE_ENTRIES;
2610         while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
2611                 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &q2);
2612
2613                 if (!NT_STATUS_IS_OK(status) &&
2614                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
2615                         break;
2616
2617                 for (i=0; i<q2.out.info.info5.count; i++) {
2618                         int j;
2619                         const char *name = q2.out.info.info5.entries[i].account_name.string;
2620                         BOOL found = False;
2621                         for (j=0; j<num_names; j++) {
2622                                 if (names[j] == NULL)
2623                                         continue;
2624                                 /* Hmm. No strequal in samba4 */
2625                                 if (strequal(names[j], name)) {
2626                                         names[j] = NULL;
2627                                         found = True;
2628                                         break;
2629                                 }
2630                         }
2631
2632                         if (!found) {
2633                                 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
2634                                        name);
2635                                 ret = False;
2636                         }
2637                 }
2638                 q2.in.start_idx += q2.out.info.info5.count;
2639         }
2640
2641         if (!NT_STATUS_IS_OK(status)) {
2642                 printf("QueryDisplayInfo level 5 failed - %s\n",
2643                        nt_errstr(status));
2644                 ret = False;
2645         }
2646
2647         for (i=0; i<num_names; i++) {
2648                 if (names[i] != NULL) {
2649                         printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
2650                                names[i]);
2651                         ret = False;
2652                 }
2653         }
2654
2655         return ret;
2656 }
2657
2658 static BOOL test_DeleteDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2659                                    struct policy_handle *group_handle)
2660 {
2661         struct samr_DeleteDomainGroup d;
2662         NTSTATUS status;
2663         BOOL ret = True;
2664
2665         printf("Testing DeleteDomainGroup\n");
2666
2667         d.in.group_handle = group_handle;
2668         d.out.group_handle = group_handle;
2669
2670         status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2671         if (!NT_STATUS_IS_OK(status)) {
2672                 printf("DeleteDomainGroup failed - %s\n", nt_errstr(status));
2673                 ret = False;
2674         }
2675
2676         return ret;
2677 }
2678
2679 static BOOL test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2680                                             struct policy_handle *domain_handle)
2681 {
2682         struct samr_TestPrivateFunctionsDomain r;
2683         NTSTATUS status;
2684         BOOL ret = True;
2685
2686         printf("Testing TestPrivateFunctionsDomain\n");
2687
2688         r.in.domain_handle = domain_handle;
2689
2690         status = dcerpc_samr_TestPrivateFunctionsDomain(p, mem_ctx, &r);
2691         if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
2692                 printf("TestPrivateFunctionsDomain failed - %s\n", nt_errstr(status));
2693                 ret = False;
2694         }
2695
2696         return ret;
2697 }
2698
2699 static BOOL test_RidToSid(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2700                           struct policy_handle *domain_handle)
2701 {
2702         struct samr_RidToSid r;
2703         NTSTATUS status;
2704         BOOL ret = True;
2705
2706         printf("Testing RidToSid\n");
2707
2708         r.in.domain_handle = domain_handle;
2709         r.in.rid = 512;
2710
2711         status = dcerpc_samr_RidToSid(p, mem_ctx, &r);
2712         if (!NT_STATUS_IS_OK(status)) {
2713                 printf("RidToSid failed - %s\n", nt_errstr(status));
2714                 ret = False;
2715         }
2716
2717         return ret;
2718 }
2719
2720 static BOOL test_GetBootKeyInformation(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2721                                        struct policy_handle *domain_handle)
2722 {
2723         struct samr_GetBootKeyInformation r;
2724         NTSTATUS status;
2725         BOOL ret = True;
2726
2727         printf("Testing GetBootKeyInformation\n");
2728
2729         r.in.domain_handle = domain_handle;
2730
2731         status = dcerpc_samr_GetBootKeyInformation(p, mem_ctx, &r);
2732         if (!NT_STATUS_IS_OK(status)) {
2733                 /* w2k3 seems to fail this sometimes and pass it sometimes */
2734                 printf("GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
2735         }
2736
2737         return ret;
2738 }
2739
2740 static BOOL test_AddGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2741                                 struct policy_handle *domain_handle,
2742                                 struct policy_handle *group_handle)
2743 {
2744         NTSTATUS status;
2745         struct samr_AddGroupMember r;
2746         struct samr_DeleteGroupMember d;
2747         struct samr_QueryGroupMember q;
2748         struct samr_SetMemberAttributesOfGroup s;
2749         BOOL ret = True;
2750         uint32_t rid;
2751
2752         status = test_LookupName(p, mem_ctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
2753         if (!NT_STATUS_IS_OK(status)) {
2754                 return False;
2755         }
2756
2757         r.in.group_handle = group_handle;
2758         r.in.rid = rid;
2759         r.in.flags = 0; /* ??? */
2760
2761         printf("Testing AddGroupMember and DeleteGroupMember\n");
2762
2763         d.in.group_handle = group_handle;
2764         d.in.rid = rid;
2765
2766         status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
2767         if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_NOT_IN_GROUP, status)) {
2768                 printf("DeleteGroupMember gave %s - should be NT_STATUS_MEMBER_NOT_IN_GROUP\n", 
2769                        nt_errstr(status));
2770                 return False;
2771         }
2772
2773         status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
2774         if (!NT_STATUS_IS_OK(status)) {
2775                 printf("AddGroupMember failed - %s\n", nt_errstr(status));
2776                 return False;
2777         }
2778
2779         status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
2780         if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_IN_GROUP, status)) {
2781                 printf("AddGroupMember gave %s - should be NT_STATUS_MEMBER_IN_GROUP\n", 
2782                        nt_errstr(status));
2783                 return False;
2784         }
2785
2786         /* this one is quite strange. I am using random inputs in the
2787            hope of triggering an error that might give us a clue */
2788         s.in.group_handle = group_handle;
2789         s.in.unknown1 = random();
2790         s.in.unknown2 = random();
2791
2792         status = dcerpc_samr_SetMemberAttributesOfGroup(p, mem_ctx, &s);
2793         if (!NT_STATUS_IS_OK(status)) {
2794                 printf("SetMemberAttributesOfGroup failed - %s\n", nt_errstr(status));
2795                 return False;
2796         }
2797
2798         q.in.group_handle = group_handle;
2799
2800         status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &q);
2801         if (!NT_STATUS_IS_OK(status)) {
2802                 printf("QueryGroupMember failed - %s\n", nt_errstr(status));
2803                 return False;
2804         }
2805
2806         status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
2807         if (!NT_STATUS_IS_OK(status)) {
2808                 printf("DeleteGroupMember failed - %s\n", nt_errstr(status));
2809                 return False;
2810         }
2811
2812         status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
2813         if (!NT_STATUS_IS_OK(status)) {
2814                 printf("AddGroupMember failed - %s\n", nt_errstr(status));
2815                 return False;
2816         }
2817
2818         return ret;
2819 }
2820
2821
2822 static BOOL test_CreateDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2823                                    struct policy_handle *domain_handle, struct policy_handle *group_handle)
2824 {
2825         NTSTATUS status;
2826         struct samr_CreateDomainGroup r;
2827         uint32_t rid;
2828         struct samr_String name;
2829         BOOL ret = True;
2830
2831         init_samr_String(&name, TEST_GROUPNAME);
2832
2833         r.in.domain_handle = domain_handle;
2834         r.in.name = &name;
2835         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2836         r.out.group_handle = group_handle;
2837         r.out.rid = &rid;
2838
2839         printf("Testing CreateDomainGroup(%s)\n", r.in.name->string);
2840
2841         status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
2842
2843         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2844                 printf("Server refused create of '%s'\n", r.in.name->string);
2845                 ZERO_STRUCTP(group_handle);
2846                 return True;
2847         }
2848
2849         if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS) ||
2850             NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2851                 if (!test_DeleteGroup_byname(p, mem_ctx, domain_handle, r.in.name->string)) {
2852                         return False;
2853                 }
2854                 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
2855         }
2856         if (!NT_STATUS_IS_OK(status)) {
2857                 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
2858                 return False;
2859         }
2860
2861         if (!test_AddGroupMember(p, mem_ctx, domain_handle, group_handle)) {
2862                 ret = False;
2863         }
2864
2865         if (!test_SetGroupInfo(p, mem_ctx, group_handle)) {
2866                 ret = False;
2867         }
2868
2869         return ret;
2870 }
2871
2872
2873 /*
2874   its not totally clear what this does. It seems to accept any sid you like.
2875 */
2876 static BOOL test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p, 
2877                                                TALLOC_CTX *mem_ctx, 
2878                                                struct policy_handle *domain_handle)
2879 {
2880         NTSTATUS status;
2881         struct samr_RemoveMemberFromForeignDomain r;
2882
2883         r.in.domain_handle = domain_handle;
2884         r.in.sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-12-34-56-78-9");
2885
2886         status = dcerpc_samr_RemoveMemberFromForeignDomain(p, mem_ctx, &r);
2887         if (!NT_STATUS_IS_OK(status)) {
2888                 printf("RemoveMemberFromForeignDomain failed - %s\n", nt_errstr(status));
2889                 return False;
2890         }
2891
2892         return True;
2893 }
2894
2895
2896
2897 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2898                          struct policy_handle *handle);
2899
2900 static BOOL test_OpenDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2901                             struct policy_handle *handle, struct dom_sid *sid)
2902 {
2903         NTSTATUS status;
2904         struct samr_OpenDomain r;
2905         struct policy_handle domain_handle;
2906         struct policy_handle user_handle;
2907         struct policy_handle alias_handle;
2908         struct policy_handle group_handle;
2909         BOOL ret = True;
2910
2911         ZERO_STRUCT(user_handle);
2912         ZERO_STRUCT(alias_handle);
2913         ZERO_STRUCT(group_handle);
2914         ZERO_STRUCT(domain_handle);
2915
2916         printf("Testing OpenDomain\n");
2917
2918         r.in.connect_handle = handle;
2919         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2920         r.in.sid = sid;
2921         r.out.domain_handle = &domain_handle;
2922
2923         status = dcerpc_samr_OpenDomain(p, mem_ctx, &r);
2924         if (!NT_STATUS_IS_OK(status)) {
2925                 printf("OpenDomain failed - %s\n", nt_errstr(status));
2926                 return False;
2927         }
2928
2929         /* run the domain tests with the main handle closed - this tests
2930            the servers reference counting */
2931         ret &= test_samr_handle_Close(p, mem_ctx, handle);
2932
2933         ret &= test_QuerySecurity(p, mem_ctx, &domain_handle);
2934         ret &= test_RemoveMemberFromForeignDomain(p, mem_ctx, &domain_handle);
2935         ret &= test_CreateUser2(p, mem_ctx, &domain_handle);
2936         ret &= test_CreateUser(p, mem_ctx, &domain_handle, &user_handle);
2937         ret &= test_CreateAlias(p, mem_ctx, &domain_handle, &alias_handle, sid);
2938         ret &= test_CreateDomainGroup(p, mem_ctx, &domain_handle, &group_handle);
2939         ret &= test_QueryDomainInfo(p, mem_ctx, &domain_handle);
2940         ret &= test_QueryDomainInfo2(p, mem_ctx, &domain_handle);
2941         ret &= test_EnumDomainUsers(p, mem_ctx, &domain_handle);
2942         ret &= test_EnumDomainUsers_async(p, mem_ctx, &domain_handle);
2943         ret &= test_EnumDomainGroups(p, mem_ctx, &domain_handle);
2944         ret &= test_EnumDomainAliases(p, mem_ctx, &domain_handle);
2945         ret &= test_QueryDisplayInfo(p, mem_ctx, &domain_handle);
2946         ret &= test_QueryDisplayInfo2(p, mem_ctx, &domain_handle);
2947         ret &= test_QueryDisplayInfo3(p, mem_ctx, &domain_handle);
2948         ret &= test_GetDisplayEnumerationIndex(p, mem_ctx, &domain_handle);
2949         ret &= test_GetDisplayEnumerationIndex2(p, mem_ctx, &domain_handle);
2950         ret &= test_GroupList(p, mem_ctx, &domain_handle);
2951         ret &= test_TestPrivateFunctionsDomain(p, mem_ctx, &domain_handle);
2952         ret &= test_RidToSid(p, mem_ctx, &domain_handle);
2953         ret &= test_GetBootKeyInformation(p, mem_ctx, &domain_handle);
2954
2955         if (!policy_handle_empty(&user_handle) &&
2956             !test_DeleteUser(p, mem_ctx, &user_handle)) {
2957                 ret = False;
2958         }
2959
2960         if (!policy_handle_empty(&alias_handle) &&
2961             !test_DeleteAlias(p, mem_ctx, &alias_handle)) {
2962                 ret = False;
2963         }
2964
2965         if (!policy_handle_empty(&group_handle) &&
2966             !test_DeleteDomainGroup(p, mem_ctx, &group_handle)) {
2967                 ret = False;
2968         }
2969
2970         ret &= test_samr_handle_Close(p, mem_ctx, &domain_handle);
2971
2972         /* reconnect the main handle */
2973         ret &= test_Connect(p, mem_ctx, handle);
2974
2975         return ret;
2976 }
2977
2978 static BOOL test_LookupDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2979                               struct policy_handle *handle, struct samr_String *domain)
2980 {
2981         NTSTATUS status;
2982         struct samr_LookupDomain r;
2983         struct samr_String n2;
2984         BOOL ret = True;
2985
2986         printf("Testing LookupDomain(%s)\n", domain->string);
2987
2988         /* check for correct error codes */
2989         r.in.connect_handle = handle;
2990         r.in.domain_name = &n2;
2991         n2.string = NULL;
2992
2993         status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
2994         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_PARAMETER, status)) {
2995                 printf("failed: LookupDomain expected NT_STATUS_INVALID_PARAMETER - %s\n", nt_errstr(status));
2996                 ret = False;
2997         }
2998
2999         n2.string = "xxNODOMAINxx";
3000
3001         status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3002         if (!NT_STATUS_EQUAL(NT_STATUS_NO_SUCH_DOMAIN, status)) {
3003                 printf("failed: LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN - %s\n", nt_errstr(status));
3004                 ret = False;
3005         }
3006
3007         r.in.connect_handle = handle;
3008         r.in.domain_name = domain;
3009
3010         status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
3011         if (!NT_STATUS_IS_OK(status)) {
3012                 printf("LookupDomain failed - %s\n", nt_errstr(status));
3013                 ret = False;
3014         }
3015
3016         if (!test_GetDomPwInfo(p, mem_ctx, domain)) {
3017                 ret = False;
3018         }
3019
3020         if (!test_OpenDomain(p, mem_ctx, handle, r.out.sid)) {
3021                 ret = False;
3022         }
3023
3024         return ret;
3025 }
3026
3027
3028 static BOOL test_EnumDomains(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3029                              struct policy_handle *handle)
3030 {
3031         NTSTATUS status;
3032         struct samr_EnumDomains r;
3033         uint32_t resume_handle = 0;
3034         int i;
3035         BOOL ret = True;
3036
3037         r.in.connect_handle = handle;
3038         r.in.resume_handle = &resume_handle;
3039         r.in.buf_size = (uint32_t)-1;
3040         r.out.resume_handle = &resume_handle;
3041
3042         status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
3043         if (!NT_STATUS_IS_OK(status)) {
3044                 printf("EnumDomains failed - %s\n", nt_errstr(status));
3045                 return False;
3046         }
3047
3048         if (!r.out.sam) {
3049                 return False;
3050         }
3051
3052         for (i=0;i<r.out.sam->count;i++) {
3053                 if (!test_LookupDomain(p, mem_ctx, handle, 
3054                                        &r.out.sam->entries[i].name)) {
3055                         ret = False;
3056                 }
3057         }
3058
3059         status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
3060         if (!NT_STATUS_IS_OK(status)) {
3061                 printf("EnumDomains failed - %s\n", nt_errstr(status));
3062                 return False;
3063         }
3064
3065         return ret;
3066 }
3067
3068
3069 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
3070                          struct policy_handle *handle)
3071 {
3072         NTSTATUS status;
3073         struct samr_Connect r;
3074         struct samr_Connect2 r2;
3075         struct samr_Connect3 r3;
3076         struct samr_Connect4 r4;
3077         struct samr_Connect5 r5;
3078         union samr_ConnectInfo info;
3079         struct policy_handle h;
3080         BOOL ret = True, got_handle = False;
3081
3082         printf("testing samr_Connect\n");
3083
3084         r.in.system_name = 0;
3085         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3086         r.out.connect_handle = &h;
3087
3088         status = dcerpc_samr_Connect(p, mem_ctx, &r);
3089         if (!NT_STATUS_IS_OK(status)) {
3090                 printf("Connect failed - %s\n", nt_errstr(status));
3091                 ret = False;
3092         } else {
3093                 got_handle = True;
3094                 *handle = h;
3095         }
3096
3097         printf("testing samr_Connect2\n");
3098
3099         r2.in.system_name = NULL;
3100         r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3101         r2.out.connect_handle = &h;
3102
3103         status = dcerpc_samr_Connect2(p, mem_ctx, &r2);
3104         if (!NT_STATUS_IS_OK(status)) {
3105                 printf("Connect2 failed - %s\n", nt_errstr(status));
3106                 ret = False;
3107         } else {
3108                 if (got_handle) {
3109                         test_samr_handle_Close(p, mem_ctx, handle);
3110                 }
3111                 got_handle = True;
3112                 *handle = h;
3113         }
3114
3115         printf("testing samr_Connect3\n");
3116
3117         r3.in.system_name = NULL;
3118         r3.in.unknown = 0;
3119         r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3120         r3.out.connect_handle = &h;
3121
3122         status = dcerpc_samr_Connect3(p, mem_ctx, &r3);
3123         if (!NT_STATUS_IS_OK(status)) {
3124                 printf("Connect3 failed - %s\n", nt_errstr(status));
3125                 ret = False;
3126         } else {
3127                 if (got_handle) {
3128                         test_samr_handle_Close(p, mem_ctx, handle);
3129                 }
3130                 got_handle = True;
3131                 *handle = h;
3132         }
3133
3134         printf("testing samr_Connect4\n");
3135
3136         r4.in.system_name = "";
3137         r4.in.unknown = 0;
3138         r4.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3139         r4.out.connect_handle = &h;
3140
3141         status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
3142         if (!NT_STATUS_IS_OK(status)) {
3143                 printf("Connect4 failed - %s\n", nt_errstr(status));
3144                 ret = False;
3145         } else {
3146                 if (got_handle) {
3147                         test_samr_handle_Close(p, mem_ctx, handle);
3148                 }
3149                 got_handle = True;
3150                 *handle = h;
3151         }
3152
3153         printf("testing samr_Connect5\n");
3154
3155         info.info1.unknown1 = 0;
3156         info.info1.unknown2 = 0;
3157
3158         r5.in.system_name = "";
3159         r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3160         r5.in.level = 1;
3161         r5.in.info = &info;
3162         r5.out.info = &info;
3163         r5.out.connect_handle = &h;
3164
3165         status = dcerpc_samr_Connect5(p, mem_ctx, &r5);
3166         if (!NT_STATUS_IS_OK(status)) {
3167                 printf("Connect5 failed - %s\n", nt_errstr(status));
3168                 ret = False;
3169         } else {
3170                 if (got_handle) {
3171                         test_samr_handle_Close(p, mem_ctx, handle);
3172                 }
3173                 got_handle = True;
3174                 *handle = h;
3175         }
3176
3177         return ret;
3178 }
3179
3180
3181 BOOL torture_rpc_samr(void)
3182 {
3183         NTSTATUS status;
3184         struct dcerpc_pipe *p;
3185         TALLOC_CTX *mem_ctx;
3186         BOOL ret = True;
3187         struct policy_handle handle;
3188
3189         mem_ctx = talloc_init("torture_rpc_samr");
3190
3191         status = torture_rpc_connection(&p, 
3192                                         DCERPC_SAMR_NAME,
3193                                         DCERPC_SAMR_UUID,
3194                                         DCERPC_SAMR_VERSION);
3195         if (!NT_STATUS_IS_OK(status)) {
3196                 return False;
3197         }
3198
3199         if (!test_Connect(p, mem_ctx, &handle)) {
3200                 ret = False;
3201         }
3202
3203         if (!test_QuerySecurity(p, mem_ctx, &handle)) {
3204                 ret = False;
3205         }
3206
3207         if (!test_EnumDomains(p, mem_ctx, &handle)) {
3208                 ret = False;
3209         }
3210
3211         if (!test_SetDsrmPassword(p, mem_ctx, &handle)) {
3212                 ret = False;
3213         }
3214
3215         if (!test_Shutdown(p, mem_ctx, &handle)) {
3216                 ret = False;
3217         }
3218
3219         if (!test_samr_handle_Close(p, mem_ctx, &handle)) {
3220                 ret = False;
3221         }
3222
3223         talloc_free(mem_ctx);
3224
3225         torture_rpc_close(p);
3226
3227         return ret;
3228 }
3229