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