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