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