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