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