r1510: add a commented out routine I used to test password change on NT3.
[samba.git] / source4 / torture / rpc / samr.c
1 /* 
2    Unix SMB/CIFS implementation.
3    test suite for samr rpc operations
4
5    Copyright (C) Andrew Tridgell 2003
6    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "includes.h"
24
25 #define TEST_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 (s.in.level == 2) {
1712                         init_samr_Name(&s.in.info->name, "NewName");
1713                 }
1714
1715                 if (s.in.level == 4) {
1716                         init_samr_Name(&s.in.info->description, "test description");
1717                 }
1718
1719                 status = dcerpc_samr_SetGroupInfo(p, mem_ctx, &s);
1720                 if (set_ok[i]) {
1721                         if (!NT_STATUS_IS_OK(status)) {
1722                                 printf("SetGroupInfo level %u failed - %s\n", 
1723                                        r.in.level, nt_errstr(status));
1724                                 ret = False;
1725                                 continue;
1726                         }
1727                 } else {
1728                         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
1729                                 printf("SetGroupInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n", 
1730                                        r.in.level, nt_errstr(status));
1731                                 ret = False;
1732                                 continue;
1733                         }
1734                 }
1735         }
1736
1737         return ret;
1738 }
1739
1740 static BOOL test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1741                                struct policy_handle *handle)
1742 {
1743         NTSTATUS status;
1744         struct samr_QueryUserInfo r;
1745         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
1746                            11, 12, 13, 14, 16, 17, 20, 21};
1747         int i;
1748         BOOL ret = True;
1749
1750         for (i=0;i<ARRAY_SIZE(levels);i++) {
1751                 printf("Testing QueryUserInfo level %u\n", levels[i]);
1752
1753                 r.in.handle = handle;
1754                 r.in.level = levels[i];
1755
1756                 status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
1757                 if (!NT_STATUS_IS_OK(status)) {
1758                         printf("QueryUserInfo level %u failed - %s\n", 
1759                                levels[i], nt_errstr(status));
1760                         ret = False;
1761                 }
1762         }
1763
1764         return ret;
1765 }
1766
1767 static BOOL test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1768                                 struct policy_handle *handle)
1769 {
1770         NTSTATUS status;
1771         struct samr_QueryUserInfo2 r;
1772         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
1773                            11, 12, 13, 14, 16, 17, 20, 21};
1774         int i;
1775         BOOL ret = True;
1776
1777         for (i=0;i<ARRAY_SIZE(levels);i++) {
1778                 printf("Testing QueryUserInfo2 level %u\n", levels[i]);
1779
1780                 r.in.handle = handle;
1781                 r.in.level = levels[i];
1782
1783                 status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
1784                 if (!NT_STATUS_IS_OK(status)) {
1785                         printf("QueryUserInfo2 level %u failed - %s\n", 
1786                                levels[i], nt_errstr(status));
1787                         ret = False;
1788                 }
1789         }
1790
1791         return ret;
1792 }
1793
1794 static BOOL test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1795                           struct policy_handle *handle, uint32_t rid)
1796 {
1797         NTSTATUS status;
1798         struct samr_OpenUser r;
1799         struct policy_handle acct_handle;
1800         BOOL ret = True;
1801
1802         printf("Testing OpenUser(%u)\n", rid);
1803
1804         r.in.handle = handle;
1805         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
1806         r.in.rid = rid;
1807         r.out.acct_handle = &acct_handle;
1808
1809         status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
1810         if (!NT_STATUS_IS_OK(status)) {
1811                 printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
1812                 return False;
1813         }
1814
1815         if (!test_QuerySecurity(p, mem_ctx, &acct_handle)) {
1816                 ret = False;
1817         }
1818
1819         if (!test_QueryUserInfo(p, mem_ctx, &acct_handle)) {
1820                 ret = False;
1821         }
1822
1823         if (!test_QueryUserInfo2(p, mem_ctx, &acct_handle)) {
1824                 ret = False;
1825         }
1826
1827         if (!test_GetUserPwInfo(p, mem_ctx, &acct_handle)) {
1828                 ret = False;
1829         }
1830
1831         if (!test_GetGroupsForUser(p,mem_ctx, &acct_handle)) {
1832                 ret = False;
1833         }
1834
1835         if (!test_Close(p, mem_ctx, &acct_handle)) {
1836                 ret = False;
1837         }
1838
1839         return ret;
1840 }
1841
1842 static BOOL test_OpenGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1843                            struct policy_handle *handle, uint32_t rid)
1844 {
1845         NTSTATUS status;
1846         struct samr_OpenGroup r;
1847         struct policy_handle acct_handle;
1848         BOOL ret = True;
1849
1850         printf("Testing OpenGroup(%u)\n", rid);
1851
1852         r.in.handle = handle;
1853         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
1854         r.in.rid = rid;
1855         r.out.acct_handle = &acct_handle;
1856
1857         status = dcerpc_samr_OpenGroup(p, mem_ctx, &r);
1858         if (!NT_STATUS_IS_OK(status)) {
1859                 printf("OpenGroup(%u) failed - %s\n", rid, nt_errstr(status));
1860                 return False;
1861         }
1862
1863         if (!test_QuerySecurity(p, mem_ctx, &acct_handle)) {
1864                 ret = False;
1865         }
1866
1867         if (!test_QueryGroupInfo(p, mem_ctx, &acct_handle)) {
1868                 ret = False;
1869         }
1870
1871         if (!test_Close(p, mem_ctx, &acct_handle)) {
1872                 ret = False;
1873         }
1874
1875         return ret;
1876 }
1877
1878 static BOOL test_OpenAlias(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1879                            struct policy_handle *handle, uint32_t rid)
1880 {
1881         NTSTATUS status;
1882         struct samr_OpenAlias r;
1883         struct policy_handle acct_handle;
1884         BOOL ret = True;
1885
1886         printf("Testing OpenAlias(%u)\n", rid);
1887
1888         r.in.handle = handle;
1889         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
1890         r.in.rid = rid;
1891         r.out.acct_handle = &acct_handle;
1892
1893         status = dcerpc_samr_OpenAlias(p, mem_ctx, &r);
1894         if (!NT_STATUS_IS_OK(status)) {
1895                 printf("OpenAlias(%u) failed - %s\n", rid, nt_errstr(status));
1896                 return False;
1897         }
1898
1899         if (!test_QuerySecurity(p, mem_ctx, &acct_handle)) {
1900                 ret = False;
1901         }
1902
1903         if (!test_QueryAliasInfo(p, mem_ctx, &acct_handle)) {
1904                 ret = False;
1905         }
1906
1907         if (!test_GetMembersInAlias(p, mem_ctx, &acct_handle)) {
1908                 ret = False;
1909         }
1910
1911         if (!test_Close(p, mem_ctx, &acct_handle)) {
1912                 ret = False;
1913         }
1914
1915         return ret;
1916 }
1917
1918 static BOOL test_EnumDomainUsers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1919                                  struct policy_handle *handle)
1920 {
1921         NTSTATUS status;
1922         struct samr_EnumDomainUsers r;
1923         uint32_t resume_handle=0;
1924         int i;
1925         BOOL ret = True;
1926         struct samr_LookupNames n;
1927         struct samr_LookupRids  lr ;
1928
1929         printf("Testing EnumDomainUsers\n");
1930
1931         r.in.handle = handle;
1932         r.in.resume_handle = &resume_handle;
1933         r.in.acct_flags = 0;
1934         r.in.max_size = (uint32_t)-1;
1935         r.out.resume_handle = &resume_handle;
1936
1937         status = dcerpc_samr_EnumDomainUsers(p, mem_ctx, &r);
1938         if (!NT_STATUS_IS_OK(status)) {
1939                 printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
1940                 return False;
1941         }
1942         
1943         if (!r.out.sam) {
1944                 return False;
1945         }
1946
1947         if (r.out.sam->count == 0) {
1948                 return True;
1949         }
1950
1951         for (i=0;i<r.out.sam->count;i++) {
1952                 if (!test_OpenUser(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
1953                         ret = False;
1954                 }
1955         }
1956
1957         printf("Testing LookupNames\n");
1958         n.in.handle = handle;
1959         n.in.num_names = r.out.sam->count;
1960         n.in.names = talloc(mem_ctx, r.out.sam->count * sizeof(struct samr_Name));
1961         for (i=0;i<r.out.sam->count;i++) {
1962                 n.in.names[i] = r.out.sam->entries[i].name;
1963         }
1964         status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
1965         if (!NT_STATUS_IS_OK(status)) {
1966                 printf("LookupNames failed - %s\n", nt_errstr(status));
1967                 ret = False;
1968         }
1969
1970
1971         printf("Testing LookupRids\n");
1972         lr.in.handle = handle;
1973         lr.in.num_rids = r.out.sam->count;
1974         lr.in.rids = talloc(mem_ctx, r.out.sam->count * sizeof(uint32_t));
1975         for (i=0;i<r.out.sam->count;i++) {
1976                 lr.in.rids[i] = r.out.sam->entries[i].idx;
1977         }
1978         status = dcerpc_samr_LookupRids(p, mem_ctx, &lr);
1979         if (!NT_STATUS_IS_OK(status)) {
1980                 printf("LookupRids failed - %s\n", nt_errstr(status));
1981                 ret = False;
1982         }
1983
1984         return ret;     
1985 }
1986
1987 static BOOL test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1988                                   struct policy_handle *handle)
1989 {
1990         NTSTATUS status;
1991         struct samr_EnumDomainGroups r;
1992         uint32_t resume_handle=0;
1993         int i;
1994         BOOL ret = True;
1995
1996         printf("Testing EnumDomainGroups\n");
1997
1998         r.in.handle = handle;
1999         r.in.resume_handle = &resume_handle;
2000         r.in.max_size = (uint32_t)-1;
2001         r.out.resume_handle = &resume_handle;
2002
2003         status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
2004         if (!NT_STATUS_IS_OK(status)) {
2005                 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
2006                 return False;
2007         }
2008         
2009         if (!r.out.sam) {
2010                 return False;
2011         }
2012
2013         for (i=0;i<r.out.sam->count;i++) {
2014                 if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2015                         ret = False;
2016                 }
2017         }
2018
2019         return ret;
2020 }
2021
2022 static BOOL test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2023                                    struct policy_handle *handle)
2024 {
2025         NTSTATUS status;
2026         struct samr_EnumDomainAliases r;
2027         uint32_t resume_handle=0;
2028         int i;
2029         BOOL ret = True;
2030
2031         printf("Testing EnumDomainAliases\n");
2032
2033         r.in.handle = handle;
2034         r.in.resume_handle = &resume_handle;
2035         r.in.account_flags = (uint32_t)-1;
2036         r.out.resume_handle = &resume_handle;
2037
2038         status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
2039         if (!NT_STATUS_IS_OK(status)) {
2040                 printf("EnumDomainAliases failed - %s\n", nt_errstr(status));
2041                 return False;
2042         }
2043         
2044         if (!r.out.sam) {
2045                 return False;
2046         }
2047
2048         for (i=0;i<r.out.sam->count;i++) {
2049                 if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
2050                         ret = False;
2051                 }
2052         }
2053
2054         return ret;     
2055 }
2056
2057 static BOOL test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2058                                             struct policy_handle *handle)
2059 {
2060         NTSTATUS status;
2061         struct samr_GetDisplayEnumerationIndex r;
2062         BOOL ret = True;
2063         uint16_t levels[] = {1, 2, 3, 4, 5};
2064         uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
2065         int i;
2066
2067         for (i=0;i<ARRAY_SIZE(levels);i++) {
2068                 printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
2069
2070                 r.in.handle = handle;
2071                 r.in.level = levels[i];
2072                 init_samr_Name(&r.in.name, TEST_ACCOUNT_NAME);
2073
2074                 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
2075
2076                 if (ok_lvl[i] && 
2077                     !NT_STATUS_IS_OK(status) &&
2078                     !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2079                         printf("GetDisplayEnumerationIndex level %u failed - %s\n", 
2080                                levels[i], nt_errstr(status));
2081                         ret = False;
2082                 }
2083
2084                 init_samr_Name(&r.in.name, "zzzzzzzz");
2085
2086                 status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
2087                 
2088                 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2089                         printf("GetDisplayEnumerationIndex level %u failed - %s\n", 
2090                                levels[i], nt_errstr(status));
2091                         ret = False;
2092                 }
2093         }
2094         
2095         return ret;     
2096 }
2097
2098 static BOOL test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2099                                              struct policy_handle *handle)
2100 {
2101         NTSTATUS status;
2102         struct samr_GetDisplayEnumerationIndex2 r;
2103         BOOL ret = True;
2104         uint16_t levels[] = {1, 2, 3, 4, 5};
2105         uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
2106         int i;
2107
2108         for (i=0;i<ARRAY_SIZE(levels);i++) {
2109                 printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
2110
2111                 r.in.handle = handle;
2112                 r.in.level = levels[i];
2113                 init_samr_Name(&r.in.name, TEST_ACCOUNT_NAME);
2114
2115                 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
2116                 if (ok_lvl[i] && 
2117                     !NT_STATUS_IS_OK(status) && 
2118                     !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2119                         printf("GetDisplayEnumerationIndex2 level %u failed - %s\n", 
2120                                levels[i], nt_errstr(status));
2121                         ret = False;
2122                 }
2123
2124                 init_samr_Name(&r.in.name, "zzzzzzzz");
2125
2126                 status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
2127                 if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
2128                         printf("GetDisplayEnumerationIndex2 level %u failed - %s\n", 
2129                                levels[i], nt_errstr(status));
2130                         ret = False;
2131                 }
2132         }
2133         
2134         return ret;     
2135 }
2136
2137 static BOOL test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2138                                   struct policy_handle *handle)
2139 {
2140         NTSTATUS status;
2141         struct samr_QueryDisplayInfo r;
2142         BOOL ret = True;
2143         uint16_t levels[] = {1, 2, 3, 4, 5};
2144         int i;
2145
2146         for (i=0;i<ARRAY_SIZE(levels);i++) {
2147                 printf("Testing QueryDisplayInfo level %u\n", levels[i]);
2148
2149                 r.in.handle = handle;
2150                 r.in.level = levels[i];
2151                 r.in.start_idx = 0;
2152                 r.in.max_entries = 1000;
2153                 r.in.buf_size = (uint32_t)-1;
2154
2155                 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
2156                 if (!NT_STATUS_IS_OK(status)) {
2157                         printf("QueryDisplayInfo level %u failed - %s\n", 
2158                                levels[i], nt_errstr(status));
2159                         ret = False;
2160                 }
2161         }
2162         
2163         return ret;     
2164 }
2165
2166 static BOOL test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2167                                   struct policy_handle *handle)
2168 {
2169         NTSTATUS status;
2170         struct samr_QueryDisplayInfo2 r;
2171         BOOL ret = True;
2172         uint16_t levels[] = {1, 2, 3, 4, 5};
2173         int i;
2174
2175         for (i=0;i<ARRAY_SIZE(levels);i++) {
2176                 printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
2177
2178                 r.in.handle = handle;
2179                 r.in.level = levels[i];
2180                 r.in.start_idx = 0;
2181                 r.in.max_entries = 1000;
2182                 r.in.buf_size = (uint32_t)-1;
2183
2184                 status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
2185                 if (!NT_STATUS_IS_OK(status)) {
2186                         printf("QueryDisplayInfo2 level %u failed - %s\n", 
2187                                levels[i], nt_errstr(status));
2188                         ret = False;
2189                 }
2190         }
2191         
2192         return ret;     
2193 }
2194
2195 static BOOL test_QueryDisplayInfo3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2196                                   struct policy_handle *handle)
2197 {
2198         NTSTATUS status;
2199         struct samr_QueryDisplayInfo3 r;
2200         BOOL ret = True;
2201         uint16_t levels[] = {1, 2, 3, 4, 5};
2202         int i;
2203
2204         for (i=0;i<ARRAY_SIZE(levels);i++) {
2205                 printf("Testing QueryDisplayInfo3 level %u\n", levels[i]);
2206
2207                 r.in.handle = handle;
2208                 r.in.level = levels[i];
2209                 r.in.start_idx = 0;
2210                 r.in.max_entries = 1000;
2211                 r.in.buf_size = (uint32_t)-1;
2212
2213                 status = dcerpc_samr_QueryDisplayInfo3(p, mem_ctx, &r);
2214                 if (!NT_STATUS_IS_OK(status)) {
2215                         printf("QueryDisplayInfo3 level %u failed - %s\n", 
2216                                levels[i], nt_errstr(status));
2217                         ret = False;
2218                 }
2219         }
2220         
2221         return ret;     
2222 }
2223
2224 static BOOL test_QueryDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2225                                  struct policy_handle *handle)
2226 {
2227         NTSTATUS status;
2228         struct samr_QueryDomainInfo r;
2229         struct samr_SetDomainInfo s;
2230         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
2231         uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1,  0,  1,  0};
2232         int i;
2233         BOOL ret = True;
2234
2235         for (i=0;i<ARRAY_SIZE(levels);i++) {
2236                 printf("Testing QueryDomainInfo level %u\n", levels[i]);
2237
2238                 r.in.handle = handle;
2239                 r.in.level = levels[i];
2240
2241                 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2242                 if (!NT_STATUS_IS_OK(status)) {
2243                         printf("QueryDomainInfo level %u failed - %s\n", 
2244                                r.in.level, nt_errstr(status));
2245                         ret = False;
2246                         continue;
2247                 }
2248
2249                 printf("Testing SetDomainInfo level %u\n", levels[i]);
2250
2251                 s.in.handle = handle;
2252                 s.in.level = levels[i];
2253                 s.in.info = r.out.info;
2254
2255                 status = dcerpc_samr_SetDomainInfo(p, mem_ctx, &s);
2256                 if (set_ok[i]) {
2257                         if (!NT_STATUS_IS_OK(status)) {
2258                                 printf("SetDomainInfo level %u failed - %s\n", 
2259                                        r.in.level, nt_errstr(status));
2260                                 ret = False;
2261                                 continue;
2262                         }
2263                 } else {
2264                         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status)) {
2265                                 printf("SetDomainInfo level %u gave %s - should have been NT_STATUS_INVALID_INFO_CLASS\n", 
2266                                        r.in.level, nt_errstr(status));
2267                                 ret = False;
2268                                 continue;
2269                         }
2270                 }
2271
2272                 status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
2273                 if (!NT_STATUS_IS_OK(status)) {
2274                         printf("QueryDomainInfo level %u failed - %s\n", 
2275                                r.in.level, nt_errstr(status));
2276                         ret = False;
2277                         continue;
2278                 }
2279         }
2280
2281         return True;    
2282 }
2283
2284
2285 static BOOL test_QueryDomainInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2286                                   struct policy_handle *handle)
2287 {
2288         NTSTATUS status;
2289         struct samr_QueryDomainInfo2 r;
2290         uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
2291         int i;
2292         BOOL ret = True;
2293
2294         for (i=0;i<ARRAY_SIZE(levels);i++) {
2295                 printf("Testing QueryDomainInfo2 level %u\n", levels[i]);
2296
2297                 r.in.handle = handle;
2298                 r.in.level = levels[i];
2299
2300                 status = dcerpc_samr_QueryDomainInfo2(p, mem_ctx, &r);
2301                 if (!NT_STATUS_IS_OK(status)) {
2302                         printf("QueryDomainInfo2 level %u failed - %s\n", 
2303                                r.in.level, nt_errstr(status));
2304                         ret = False;
2305                         continue;
2306                 }
2307         }
2308
2309         return True;    
2310 }
2311
2312 void add_string_to_array(TALLOC_CTX *mem_ctx,
2313                          const char *str, const char ***strings, int *num)
2314 {
2315         *strings = talloc_realloc(mem_ctx, *strings,
2316                                   ((*num)+1) * sizeof(**strings));
2317
2318         if (*strings == NULL)
2319                 return;
2320
2321         (*strings)[*num] = str;
2322         *num += 1;
2323
2324         return;
2325 }
2326
2327 /* Test whether querydispinfo level 5 and enumdomgroups return the same
2328    set of group names. */
2329 static BOOL test_GroupList(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2330                            struct policy_handle *handle)
2331 {
2332         struct samr_EnumDomainGroups q1;
2333         struct samr_QueryDisplayInfo q2;
2334         NTSTATUS status;
2335         uint32_t resume_handle=0;
2336         int i;
2337         BOOL ret = True;
2338
2339         int num_names = 0;
2340         const char **names = NULL;
2341
2342         printf("Testing coherency of querydispinfo vs enumdomgroups\n");
2343
2344         q1.in.handle = handle;
2345         q1.in.resume_handle = &resume_handle;
2346         q1.in.max_size = 5;
2347         q1.out.resume_handle = &resume_handle;
2348
2349         status = STATUS_MORE_ENTRIES;
2350         while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
2351                 status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &q1);
2352
2353                 if (!NT_STATUS_IS_OK(status) &&
2354                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
2355                         break;
2356
2357                 for (i=0; i<q1.out.sam->count; i++) {
2358                         add_string_to_array(mem_ctx,
2359                                             q1.out.sam->entries[i].name.name,
2360                                             &names, &num_names);
2361                 }
2362         }
2363
2364         if (!NT_STATUS_IS_OK(status)) {
2365                 printf("EnumDomainGroups failed - %s\n", nt_errstr(status));
2366                 return False;
2367         }
2368         
2369         if (!q1.out.sam) {
2370                 return False;
2371         }
2372
2373         q2.in.handle = handle;
2374         q2.in.level = 5;
2375         q2.in.start_idx = 0;
2376         q2.in.max_entries = 5;
2377         q2.in.buf_size = (uint32_t)-1;
2378
2379         status = STATUS_MORE_ENTRIES;
2380         while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
2381                 status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &q2);
2382
2383                 if (!NT_STATUS_IS_OK(status) &&
2384                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
2385                         break;
2386
2387                 for (i=0; i<q2.out.info.info5.count; i++) {
2388                         char *name;
2389                         size_t namelen;
2390                         int j;
2391                         BOOL found = False;
2392
2393                         /* Querydisplayinfo returns ascii -- convert */
2394
2395                         namelen = convert_string_allocate(CH_DISPLAY, CH_UNIX,
2396                                                           q2.out.info.info5.entries[i].account_name.name,
2397                                                           q2.out.info.info5.entries[i].account_name.name_len,
2398                                                           (void **)&name);
2399                         name = realloc(name, namelen+1);
2400                         name[namelen] = 0;
2401
2402                         for (j=0; j<num_names; j++) {
2403                                 if (names[j] == NULL)
2404                                         continue;
2405                                 /* Hmm. No strequal in samba4 */
2406                                 if (strequal(names[j], name)) {
2407                                         names[j] = NULL;
2408                                         found = True;
2409                                         break;
2410                                 }
2411                         }
2412
2413                         if (!found) {
2414                                 printf("QueryDisplayInfo gave name [%s] that EnumDomainGroups did not\n",
2415                                        name);
2416                                 ret = False;
2417                         }
2418                 }
2419                 q2.in.start_idx += q2.out.info.info5.count;
2420         }
2421
2422         if (!NT_STATUS_IS_OK(status)) {
2423                 printf("QueryDisplayInfo level 5 failed - %s\n",
2424                        nt_errstr(status));
2425                 ret = False;
2426         }
2427
2428         for (i=0; i<num_names; i++) {
2429                 if (names[i] != NULL) {
2430                         printf("EnumDomainGroups gave name [%s] that QueryDisplayInfo did not\n",
2431                                names[i]);
2432                         ret = False;
2433                 }
2434         }
2435
2436         return ret;
2437 }
2438
2439 static BOOL test_DeleteDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2440                                    struct policy_handle *group_handle)
2441 {
2442         struct samr_DeleteDomainGroup d;
2443         NTSTATUS status;
2444         BOOL ret = True;
2445
2446         printf("Testing DeleteDomainGroup\n");
2447
2448         d.in.handle = group_handle;
2449         d.out.handle = group_handle;
2450
2451         status = dcerpc_samr_DeleteDomainGroup(p, mem_ctx, &d);
2452         if (!NT_STATUS_IS_OK(status)) {
2453                 printf("DeleteDomainGroup failed - %s\n", nt_errstr(status));
2454                 ret = False;
2455         }
2456
2457         return ret;
2458 }
2459
2460 static BOOL test_TestPrivateFunctionsDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2461                                             struct policy_handle *domain_handle)
2462 {
2463         struct samr_TestPrivateFunctionsDomain r;
2464         NTSTATUS status;
2465         BOOL ret = True;
2466
2467         printf("Testing TestPrivateFunctionsDomain\n");
2468
2469         r.in.handle = domain_handle;
2470
2471         status = dcerpc_samr_TestPrivateFunctionsDomain(p, mem_ctx, &r);
2472         if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
2473                 printf("TestPrivateFunctionsDomain failed - %s\n", nt_errstr(status));
2474                 ret = False;
2475         }
2476
2477         return ret;
2478 }
2479
2480 static BOOL test_RidToSid(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2481                           struct policy_handle *domain_handle)
2482 {
2483         struct samr_RidToSid r;
2484         NTSTATUS status;
2485         BOOL ret = True;
2486
2487         printf("Testing RidToSid\n");
2488
2489         r.in.handle = domain_handle;
2490         r.in.rid = 512;
2491
2492         status = dcerpc_samr_RidToSid(p, mem_ctx, &r);
2493         if (!NT_STATUS_IS_OK(status)) {
2494                 printf("RidToSid failed - %s\n", nt_errstr(status));
2495                 ret = False;
2496         }
2497
2498         return ret;
2499 }
2500
2501 static BOOL test_GetBootKeyInformation(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
2502                                        struct policy_handle *domain_handle)
2503 {
2504         struct samr_GetBootKeyInformation r;
2505         NTSTATUS status;
2506         BOOL ret = True;
2507
2508         printf("Testing GetBootKeyInformation\n");
2509
2510         r.in.handle = domain_handle;
2511
2512         status = dcerpc_samr_GetBootKeyInformation(p, mem_ctx, &r);
2513         if (!NT_STATUS_IS_OK(status)) {
2514                 /* w2k3 seems to fail this sometimes and pass it sometimes */
2515                 printf("GetBootKeyInformation (ignored) - %s\n", nt_errstr(status));
2516         }
2517
2518         return ret;
2519 }
2520
2521 static BOOL test_AddGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2522                                 struct policy_handle *domain_handle,
2523                                 struct policy_handle *group_handle)
2524 {
2525         NTSTATUS status;
2526         struct samr_AddGroupMember r;
2527         struct samr_DeleteGroupMember d;
2528         struct samr_QueryGroupMember q;
2529         struct samr_SetMemberAttributesOfGroup s;
2530         BOOL ret = True;
2531         uint32_t rid;
2532
2533         status = test_LookupName(p, mem_ctx, domain_handle, TEST_ACCOUNT_NAME, &rid);
2534         if (!NT_STATUS_IS_OK(status)) {
2535                 return False;
2536         }
2537
2538         r.in.handle = group_handle;
2539         r.in.rid = rid;
2540         r.in.flags = 0; /* ??? */
2541
2542         printf("Testing AddGroupMember and DeleteGroupMember\n");
2543
2544         d.in.handle = group_handle;
2545         d.in.rid = rid;
2546
2547         status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
2548         if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_NOT_IN_GROUP, status)) {
2549                 printf("DeleteGroupMember gave %s - should be NT_STATUS_MEMBER_NOT_IN_GROUP\n", 
2550                        nt_errstr(status));
2551                 return False;
2552         }
2553
2554         status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
2555         if (!NT_STATUS_IS_OK(status)) {
2556                 printf("AddGroupMember failed - %s\n", nt_errstr(status));
2557                 return False;
2558         }
2559
2560         status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
2561         if (!NT_STATUS_EQUAL(NT_STATUS_MEMBER_IN_GROUP, status)) {
2562                 printf("AddGroupMember gave %s - should be NT_STATUS_MEMBER_IN_GROUP\n", 
2563                        nt_errstr(status));
2564                 return False;
2565         }
2566
2567         /* this one is quite strange. I am using random inputs in the
2568            hope of triggering an error that might give us a clue */
2569         s.in.handle = group_handle;
2570         s.in.unknown1 = random();
2571         s.in.unknown2 = random();
2572
2573         status = dcerpc_samr_SetMemberAttributesOfGroup(p, mem_ctx, &s);
2574         if (!NT_STATUS_IS_OK(status)) {
2575                 printf("SetMemberAttributesOfGroup failed - %s\n", nt_errstr(status));
2576                 return False;
2577         }
2578
2579         q.in.handle = group_handle;
2580
2581         status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &q);
2582         if (!NT_STATUS_IS_OK(status)) {
2583                 printf("QueryGroupMember failed - %s\n", nt_errstr(status));
2584                 return False;
2585         }
2586
2587         status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
2588         if (!NT_STATUS_IS_OK(status)) {
2589                 printf("DeleteGroupMember failed - %s\n", nt_errstr(status));
2590                 return False;
2591         }
2592
2593         status = dcerpc_samr_AddGroupMember(p, mem_ctx, &r);
2594         if (!NT_STATUS_IS_OK(status)) {
2595                 printf("AddGroupMember failed - %s\n", nt_errstr(status));
2596                 return False;
2597         }
2598
2599         return ret;
2600 }
2601
2602
2603 static BOOL test_CreateDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2604                                    struct policy_handle *domain_handle, struct policy_handle *group_handle)
2605 {
2606         NTSTATUS status;
2607         struct samr_CreateDomainGroup r;
2608         uint32_t rid;
2609         struct samr_Name name;
2610         BOOL ret = True;
2611
2612         init_samr_Name(&name, TEST_GROUPNAME);
2613
2614         r.in.handle = domain_handle;
2615         r.in.name = &name;
2616         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
2617         r.out.group_handle = group_handle;
2618         r.out.rid = &rid;
2619
2620         printf("Testing CreateDomainGroup(%s)\n", r.in.name->name);
2621
2622         status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
2623
2624         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2625                 printf("Server refused create of '%s'\n", r.in.name->name);
2626                 ZERO_STRUCTP(group_handle);
2627                 return True;
2628         }
2629
2630         if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS) ||
2631             NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
2632                 if (!test_DeleteGroup_byname(p, mem_ctx, domain_handle, r.in.name->name)) {
2633                         return False;
2634                 }
2635                 status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
2636         }
2637         if (!NT_STATUS_IS_OK(status)) {
2638                 printf("CreateDomainGroup failed - %s\n", nt_errstr(status));
2639                 return False;
2640         }
2641
2642         if (!test_AddGroupMember(p, mem_ctx, domain_handle, group_handle)) {
2643                 ret = False;
2644         }
2645
2646         if (!test_SetGroupInfo(p, mem_ctx, group_handle)) {
2647                 ret = False;
2648         }
2649
2650         return ret;
2651 }
2652
2653
2654 /*
2655   its not totally clear what this does. It seems to accept any sid you like.
2656 */
2657 static BOOL test_RemoveMemberFromForeignDomain(struct dcerpc_pipe *p, 
2658                                                TALLOC_CTX *mem_ctx, 
2659                                                struct policy_handle *domain_handle)
2660 {
2661         NTSTATUS status;
2662         struct samr_RemoveMemberFromForeignDomain r;
2663
2664         r.in.handle = domain_handle;
2665         r.in.sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-12-34-56-78-9");
2666
2667         status = dcerpc_samr_RemoveMemberFromForeignDomain(p, mem_ctx, &r);
2668         if (!NT_STATUS_IS_OK(status)) {
2669                 printf("RemoveMemberFromForeignDomain failed - %s\n", nt_errstr(status));
2670                 return False;
2671         }
2672
2673         return True;
2674 }
2675
2676
2677
2678
2679 static BOOL test_OpenDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2680                             struct policy_handle *handle, struct dom_sid *sid)
2681 {
2682         NTSTATUS status;
2683         struct samr_OpenDomain r;
2684         struct policy_handle domain_handle;
2685         struct policy_handle user_handle;
2686         struct policy_handle alias_handle;
2687         struct policy_handle group_handle;
2688         BOOL ret = True;
2689
2690         ZERO_STRUCT(user_handle);
2691         ZERO_STRUCT(alias_handle);
2692         ZERO_STRUCT(group_handle);
2693         ZERO_STRUCT(domain_handle);
2694
2695         printf("Testing OpenDomain\n");
2696
2697         r.in.handle = handle;
2698         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
2699         r.in.sid = sid;
2700         r.out.domain_handle = &domain_handle;
2701
2702         status = dcerpc_samr_OpenDomain(p, mem_ctx, &r);
2703         if (!NT_STATUS_IS_OK(status)) {
2704                 printf("OpenDomain failed - %s\n", nt_errstr(status));
2705                 return False;
2706         }
2707
2708         if (!test_QuerySecurity(p, mem_ctx, &domain_handle)) {
2709                 ret = False;
2710         }
2711
2712         if (!test_RemoveMemberFromForeignDomain(p, mem_ctx, &domain_handle)) {
2713                 ret = False;
2714         }
2715
2716         if (!test_CreateUser2(p, mem_ctx, &domain_handle)) {
2717                 ret = False;
2718         }
2719
2720         if (!test_CreateUser(p, mem_ctx, &domain_handle, &user_handle)) {
2721                 ret = False;
2722         }
2723
2724         if (!test_CreateAlias(p, mem_ctx, &domain_handle, &alias_handle, sid)) {
2725                 ret = False;
2726         }
2727
2728         if (!test_CreateDomainGroup(p, mem_ctx, &domain_handle, &group_handle)) {
2729                 ret = False;
2730         }
2731
2732         if (!test_QueryDomainInfo(p, mem_ctx, &domain_handle)) {
2733                 ret = False;
2734         }
2735
2736         if (!test_QueryDomainInfo2(p, mem_ctx, &domain_handle)) {
2737                 ret = False;
2738         }
2739
2740         if (!test_EnumDomainUsers(p, mem_ctx, &domain_handle)) {
2741                 ret = False;
2742         }
2743
2744         if (!test_EnumDomainGroups(p, mem_ctx, &domain_handle)) {
2745                 ret = False;
2746         }
2747
2748         if (!test_EnumDomainAliases(p, mem_ctx, &domain_handle)) {
2749                 ret = False;
2750         }
2751
2752         if (!test_QueryDisplayInfo(p, mem_ctx, &domain_handle)) {
2753                 ret = False;
2754         }
2755
2756         if (!test_QueryDisplayInfo2(p, mem_ctx, &domain_handle)) {
2757                 ret = False;
2758         }
2759
2760         if (!test_QueryDisplayInfo3(p, mem_ctx, &domain_handle)) {
2761                 ret = False;
2762         }
2763
2764         if (!test_GetDisplayEnumerationIndex(p, mem_ctx, &domain_handle)) {
2765                 ret = False;
2766         }
2767
2768         if (!test_GetDisplayEnumerationIndex2(p, mem_ctx, &domain_handle)) {
2769                 ret = False;
2770         }
2771
2772         if (!test_GroupList(p, mem_ctx, &domain_handle)) {
2773                 ret = False;
2774         }
2775
2776         if (!test_TestPrivateFunctionsDomain(p, mem_ctx, &domain_handle)) {
2777                 ret = False;
2778         }
2779
2780         if (!test_RidToSid(p, mem_ctx, &domain_handle)) {
2781                 ret = False;
2782         }
2783
2784         if (!test_GetBootKeyInformation(p, mem_ctx, &domain_handle)) {
2785                 ret = False;
2786         }
2787
2788         if (!policy_handle_empty(&user_handle) &&
2789             !test_DeleteUser(p, mem_ctx, &user_handle)) {
2790                 ret = False;
2791         }
2792
2793         if (!policy_handle_empty(&alias_handle) &&
2794             !test_DeleteAlias(p, mem_ctx, &alias_handle)) {
2795                 ret = False;
2796         }
2797
2798         if (!policy_handle_empty(&group_handle) &&
2799             !test_DeleteDomainGroup(p, mem_ctx, &group_handle)) {
2800                 ret = False;
2801         }
2802
2803         if (!test_Close(p, mem_ctx, &domain_handle)) {
2804                 ret = False;
2805         }
2806
2807         return ret;
2808 }
2809
2810 static BOOL test_LookupDomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2811                               struct policy_handle *handle, struct samr_Name *domain)
2812 {
2813         NTSTATUS status;
2814         struct samr_LookupDomain r;
2815         struct samr_Name n2;
2816         BOOL ret = True;
2817
2818         printf("Testing LookupDomain(%s)\n", domain->name);
2819
2820         /* check for correct error codes */
2821         r.in.handle = handle;
2822         r.in.domain = &n2;
2823         n2.name = NULL;
2824
2825         status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
2826         if (!NT_STATUS_EQUAL(NT_STATUS_INVALID_PARAMETER, status)) {
2827                 printf("failed: LookupDomain expected NT_STATUS_INVALID_PARAMETER - %s\n", nt_errstr(status));
2828                 ret = False;
2829         }
2830
2831         n2.name = "xxNODOMAINxx";
2832
2833         status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
2834         if (!NT_STATUS_EQUAL(NT_STATUS_NO_SUCH_DOMAIN, status)) {
2835                 printf("failed: LookupDomain expected NT_STATUS_NO_SUCH_DOMAIN - %s\n", nt_errstr(status));
2836                 ret = False;
2837         }
2838
2839         r.in.handle = handle;
2840         r.in.domain = domain;
2841
2842         status = dcerpc_samr_LookupDomain(p, mem_ctx, &r);
2843         if (!NT_STATUS_IS_OK(status)) {
2844                 printf("LookupDomain failed - %s\n", nt_errstr(status));
2845                 ret = False;
2846         }
2847
2848         if (!test_GetDomPwInfo(p, mem_ctx, domain)) {
2849                 ret = False;
2850         }
2851
2852         if (!test_OpenDomain(p, mem_ctx, handle, r.out.sid)) {
2853                 ret = False;
2854         }
2855
2856         return ret;
2857 }
2858
2859
2860 static BOOL test_EnumDomains(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2861                              struct policy_handle *handle)
2862 {
2863         NTSTATUS status;
2864         struct samr_EnumDomains r;
2865         uint32_t resume_handle = 0;
2866         int i;
2867         BOOL ret = True;
2868
2869         r.in.handle = handle;
2870         r.in.resume_handle = &resume_handle;
2871         r.in.buf_size = (uint32_t)-1;
2872         r.out.resume_handle = &resume_handle;
2873
2874         status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
2875         if (!NT_STATUS_IS_OK(status)) {
2876                 printf("EnumDomains failed - %s\n", nt_errstr(status));
2877                 return False;
2878         }
2879
2880         if (!r.out.sam) {
2881                 return False;
2882         }
2883
2884         for (i=0;i<r.out.sam->count;i++) {
2885                 if (!test_LookupDomain(p, mem_ctx, handle, 
2886                                        &r.out.sam->entries[i].name)) {
2887                         ret = False;
2888                 }
2889         }
2890
2891         status = dcerpc_samr_EnumDomains(p, mem_ctx, &r);
2892         if (!NT_STATUS_IS_OK(status)) {
2893                 printf("EnumDomains failed - %s\n", nt_errstr(status));
2894                 return False;
2895         }
2896
2897         return ret;
2898 }
2899
2900
2901 static BOOL test_Connect(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
2902                          struct policy_handle *handle)
2903 {
2904         NTSTATUS status;
2905         struct samr_Connect r;
2906         struct samr_Connect2 r2;
2907         struct samr_Connect3 r3;
2908         struct samr_Connect4 r4;
2909         struct samr_Connect5 r5;
2910         union samr_ConnectInfo info;
2911         BOOL ret = True;
2912
2913         printf("testing samr_Connect\n");
2914
2915         r.in.system_name = 0;
2916         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
2917         r.out.handle = handle;
2918
2919         status = dcerpc_samr_Connect(p, mem_ctx, &r);
2920         if (!NT_STATUS_IS_OK(status)) {
2921                 printf("Connect failed - %s\n", nt_errstr(status));
2922                 ret = False;
2923         }
2924
2925         printf("testing samr_Connect2\n");
2926
2927         r2.in.system_name = NULL;
2928         r2.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
2929         r2.out.handle = handle;
2930
2931         status = dcerpc_samr_Connect2(p, mem_ctx, &r2);
2932         if (!NT_STATUS_IS_OK(status)) {
2933                 printf("Connect2 failed - %s\n", nt_errstr(status));
2934                 ret = False;
2935         }
2936
2937         printf("testing samr_Connect3\n");
2938
2939         r3.in.system_name = NULL;
2940         r3.in.unknown = 0;
2941         r3.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
2942         r3.out.handle = handle;
2943
2944         status = dcerpc_samr_Connect3(p, mem_ctx, &r3);
2945         if (!NT_STATUS_IS_OK(status)) {
2946                 printf("Connect3 failed - %s\n", nt_errstr(status));
2947                 ret = False;
2948         }
2949
2950         printf("testing samr_Connect4\n");
2951
2952         r4.in.system_name = "";
2953         r4.in.unknown = 0;
2954         r4.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
2955         r4.out.handle = handle;
2956
2957         status = dcerpc_samr_Connect4(p, mem_ctx, &r4);
2958         if (!NT_STATUS_IS_OK(status)) {
2959                 printf("Connect4 failed - %s\n", nt_errstr(status));
2960                 ret = False;
2961         }
2962
2963         printf("testing samr_Connect5\n");
2964
2965         info.info1.unknown1 = 0;
2966         info.info1.unknown2 = 0;
2967
2968         r5.in.system_name = "";
2969         r5.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
2970         r5.in.level = 1;
2971         r5.in.info = &info;
2972         r5.out.info = &info;
2973         r5.out.handle = handle;
2974
2975         status = dcerpc_samr_Connect5(p, mem_ctx, &r5);
2976         if (!NT_STATUS_IS_OK(status)) {
2977                 printf("Connect5 failed - %s\n", nt_errstr(status));
2978                 ret = False;
2979         }
2980
2981         return ret;
2982 }
2983
2984
2985 BOOL torture_rpc_samr(int dummy)
2986 {
2987         NTSTATUS status;
2988         struct dcerpc_pipe *p;
2989         TALLOC_CTX *mem_ctx;
2990         BOOL ret = True;
2991         struct policy_handle handle;
2992
2993         mem_ctx = talloc_init("torture_rpc_samr");
2994
2995         status = torture_rpc_connection(&p, 
2996                                         DCERPC_SAMR_NAME,
2997                                         DCERPC_SAMR_UUID,
2998                                         DCERPC_SAMR_VERSION);
2999         if (!NT_STATUS_IS_OK(status)) {
3000                 return False;
3001         }
3002
3003         if (!test_Connect(p, mem_ctx, &handle)) {
3004                 ret = False;
3005         }
3006
3007         if (!test_QuerySecurity(p, mem_ctx, &handle)) {
3008                 ret = False;
3009         }
3010
3011         if (!test_EnumDomains(p, mem_ctx, &handle)) {
3012                 ret = False;
3013         }
3014
3015         if (!test_SetDsrmPassword(p, mem_ctx, &handle)) {
3016                 ret = False;
3017         }
3018
3019         if (!test_Shutdown(p, mem_ctx, &handle)) {
3020                 ret = False;
3021         }
3022
3023         if (!test_Close(p, mem_ctx, &handle)) {
3024                 ret = False;
3025         }
3026
3027         talloc_destroy(mem_ctx);
3028
3029         torture_rpc_close(p);
3030
3031         return ret;
3032 }
3033