9fe6541dabc4e7a2a878ac75aeea3e27ccd431f0
[samba.git] / source4 / torture / rpc / lsa.c
1 /* 
2    Unix SMB/CIFS implementation.
3    test suite for lsa rpc operations
4
5    Copyright (C) Andrew Tridgell 2003
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "includes.h"
23 #include "librpc/gen_ndr/ndr_lsa.h"
24
25 static void init_lsa_String(struct lsa_String *name, const char *s)
26 {
27         name->string = s;
28 }
29
30 static BOOL test_OpenPolicy(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
31 {
32         struct lsa_ObjectAttribute attr;
33         struct policy_handle handle;
34         struct lsa_QosInfo qos;
35         struct lsa_OpenPolicy r;
36         NTSTATUS status;
37         uint16_t system_name = '\\';
38
39         printf("\ntesting OpenPolicy\n");
40
41         qos.len = 0;
42         qos.impersonation_level = 2;
43         qos.context_mode = 1;
44         qos.effective_only = 0;
45
46         attr.len = 0;
47         attr.root_dir = NULL;
48         attr.object_name = NULL;
49         attr.attributes = 0;
50         attr.sec_desc = NULL;
51         attr.sec_qos = &qos;
52
53         r.in.system_name = &system_name;
54         r.in.attr = &attr;
55         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
56         r.out.handle = &handle;
57
58         status = dcerpc_lsa_OpenPolicy(p, mem_ctx, &r);
59         if (!NT_STATUS_IS_OK(status)) {
60                 printf("OpenPolicy failed - %s\n", nt_errstr(status));
61                 return False;
62         }
63
64         return True;
65 }
66
67
68 static BOOL test_OpenPolicy2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
69                              struct policy_handle *handle)
70 {
71         struct lsa_ObjectAttribute attr;
72         struct lsa_QosInfo qos;
73         struct lsa_OpenPolicy2 r;
74         NTSTATUS status;
75
76         printf("\ntesting OpenPolicy2\n");
77
78         qos.len = 0;
79         qos.impersonation_level = 2;
80         qos.context_mode = 1;
81         qos.effective_only = 0;
82
83         attr.len = 0;
84         attr.root_dir = NULL;
85         attr.object_name = NULL;
86         attr.attributes = 0;
87         attr.sec_desc = NULL;
88         attr.sec_qos = &qos;
89
90         r.in.system_name = "\\";
91         r.in.attr = &attr;
92         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
93         r.out.handle = handle;
94
95         status = dcerpc_lsa_OpenPolicy2(p, mem_ctx, &r);
96         if (!NT_STATUS_IS_OK(status)) {
97                 printf("OpenPolicy2 failed - %s\n", nt_errstr(status));
98                 return False;
99         }
100
101         return True;
102 }
103
104 static BOOL test_LookupNames(struct dcerpc_pipe *p, 
105                             TALLOC_CTX *mem_ctx, 
106                             struct policy_handle *handle,
107                             struct lsa_TransNameArray *tnames)
108 {
109         struct lsa_LookupNames r;
110         struct lsa_TransSidArray sids;
111         struct lsa_String *names;
112         uint32_t count = 0;
113         NTSTATUS status;
114         int i;
115
116         printf("\nTesting LookupNames with %d names\n", tnames->count);
117
118         sids.count = 0;
119         sids.sids = NULL;
120
121         names = talloc_array_p(mem_ctx, struct lsa_String, tnames->count);
122         for (i=0;i<tnames->count;i++) {
123                 init_lsa_String(&names[i], tnames->names[i].name.string);
124         }
125
126         r.in.handle = handle;
127         r.in.num_names = tnames->count;
128         r.in.names = names;
129         r.in.sids = &sids;
130         r.in.level = 1;
131         r.in.count = &count;
132         r.out.count = &count;
133         r.out.sids = &sids;
134
135         status = dcerpc_lsa_LookupNames(p, mem_ctx, &r);
136         if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
137                 printf("LookupNames failed - %s\n", nt_errstr(status));
138                 return False;
139         }
140
141         printf("\n");
142
143         return True;
144 }
145
146 static BOOL test_LookupNames2(struct dcerpc_pipe *p, 
147                               TALLOC_CTX *mem_ctx, 
148                               struct policy_handle *handle,
149                               struct lsa_TransNameArray2 *tnames)
150 {
151         struct lsa_LookupNames2 r;
152         struct lsa_TransSidArray2 sids;
153         struct lsa_String *names;
154         uint32_t count = 0;
155         NTSTATUS status;
156         int i;
157
158         printf("\nTesting LookupNames2 with %d names\n", tnames->count);
159
160         sids.count = 0;
161         sids.sids = NULL;
162
163         names = talloc_array_p(mem_ctx, struct lsa_String, tnames->count);
164         for (i=0;i<tnames->count;i++) {
165                 init_lsa_String(&names[i], tnames->names[i].name.string);
166         }
167
168         r.in.handle = handle;
169         r.in.num_names = tnames->count;
170         r.in.names = names;
171         r.in.sids = &sids;
172         r.in.level = 1;
173         r.in.count = &count;
174         r.in.unknown1 = 0;
175         r.in.unknown2 = 0;
176         r.out.count = &count;
177         r.out.sids = &sids;
178
179         status = dcerpc_lsa_LookupNames2(p, mem_ctx, &r);
180         if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
181                 printf("LookupNames2 failed - %s\n", nt_errstr(status));
182                 return False;
183         }
184
185         printf("\n");
186
187         return True;
188 }
189
190
191 static BOOL test_LookupSids(struct dcerpc_pipe *p, 
192                             TALLOC_CTX *mem_ctx, 
193                             struct policy_handle *handle,
194                             struct lsa_SidArray *sids)
195 {
196         struct lsa_LookupSids r;
197         struct lsa_TransNameArray names;
198         uint32_t count = sids->num_sids;
199         NTSTATUS status;
200
201         printf("\nTesting LookupSids\n");
202
203         names.count = 0;
204         names.names = NULL;
205
206         r.in.handle = handle;
207         r.in.sids = sids;
208         r.in.names = &names;
209         r.in.level = 1;
210         r.in.count = &count;
211         r.out.count = &count;
212         r.out.names = &names;
213
214         status = dcerpc_lsa_LookupSids(p, mem_ctx, &r);
215         if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
216                 printf("LookupSids failed - %s\n", nt_errstr(status));
217                 return False;
218         }
219
220         printf("\n");
221
222         if (!test_LookupNames(p, mem_ctx, handle, &names)) {
223                 return False;
224         }
225
226         return True;
227 }
228
229
230 static BOOL test_LookupSids2(struct dcerpc_pipe *p, 
231                             TALLOC_CTX *mem_ctx, 
232                             struct policy_handle *handle,
233                             struct lsa_SidArray *sids)
234 {
235         struct lsa_LookupSids2 r;
236         struct lsa_TransNameArray2 names;
237         uint32_t count = sids->num_sids;
238         NTSTATUS status;
239
240         printf("\nTesting LookupSids2\n");
241
242         names.count = 0;
243         names.names = NULL;
244
245         r.in.handle = handle;
246         r.in.sids = sids;
247         r.in.names = &names;
248         r.in.level = 1;
249         r.in.count = &count;
250         r.in.unknown1 = 0;
251         r.in.unknown2 = 0;
252         r.out.count = &count;
253         r.out.names = &names;
254
255         status = dcerpc_lsa_LookupSids2(p, mem_ctx, &r);
256         if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
257                 printf("LookupSids2 failed - %s\n", nt_errstr(status));
258                 return False;
259         }
260
261         printf("\n");
262
263         if (!test_LookupNames2(p, mem_ctx, handle, &names)) {
264                 return False;
265         }
266
267         return True;
268 }
269
270 static BOOL test_many_LookupSids(struct dcerpc_pipe *p, 
271                                  TALLOC_CTX *mem_ctx, 
272                                  struct policy_handle *handle)
273 {
274         struct lsa_LookupSids r;
275         struct lsa_TransNameArray names;
276         uint32_t count;
277         NTSTATUS status;
278         struct lsa_SidArray sids;
279         int i;
280
281         printf("\nTesting LookupSids with lots of SIDs\n");
282
283         names.count = 0;
284         names.names = NULL;
285
286         sids.num_sids = 100;
287
288         sids.sids = talloc_array_p(mem_ctx, struct lsa_SidPtr, sids.num_sids);
289
290         for (i=0; i<sids.num_sids; i++) {
291                 const char *sidstr = "S-1-5-32-545";
292                 sids.sids[i].sid = dom_sid_parse_talloc(mem_ctx, sidstr);
293         }
294
295         count = sids.num_sids;
296
297         r.in.handle = handle;
298         r.in.sids = &sids;
299         r.in.names = &names;
300         r.in.level = 1;
301         r.in.count = &names.count;
302         r.out.count = &count;
303         r.out.names = &names;
304
305         status = dcerpc_lsa_LookupSids(p, mem_ctx, &r);
306         if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
307                 printf("LookupSids failed - %s\n", nt_errstr(status));
308                 return False;
309         }
310
311         printf("\n");
312
313         if (!test_LookupNames(p, mem_ctx, handle, &names)) {
314                 return False;
315         }
316
317         return True;
318 }
319
320 static BOOL test_LookupPrivValue(struct dcerpc_pipe *p, 
321                                  TALLOC_CTX *mem_ctx, 
322                                  struct policy_handle *handle,
323                                  struct lsa_String *name)
324 {
325         NTSTATUS status;
326         struct lsa_LookupPrivValue r;
327
328         r.in.handle = handle;
329         r.in.name = name;
330
331         status = dcerpc_lsa_LookupPrivValue(p, mem_ctx, &r);
332         if (!NT_STATUS_IS_OK(status)) {
333                 printf("\nLookupPrivValue failed - %s\n", nt_errstr(status));
334                 return False;
335         }
336
337         return True;
338 }
339
340 static BOOL test_LookupPrivName(struct dcerpc_pipe *p, 
341                                 TALLOC_CTX *mem_ctx, 
342                                 struct policy_handle *handle,
343                                 struct lsa_LUID *luid)
344 {
345         NTSTATUS status;
346         struct lsa_LookupPrivName r;
347
348         r.in.handle = handle;
349         r.in.luid = luid;
350
351         status = dcerpc_lsa_LookupPrivName(p, mem_ctx, &r);
352         if (!NT_STATUS_IS_OK(status)) {
353                 printf("\nLookupPrivName failed - %s\n", nt_errstr(status));
354                 return False;
355         }
356
357         return True;
358 }
359
360 static BOOL test_RemovePrivilegesFromAccount(struct dcerpc_pipe *p, 
361                                              TALLOC_CTX *mem_ctx,                                 
362                                              struct policy_handle *acct_handle,
363                                              struct lsa_LUID *luid)
364 {
365         NTSTATUS status;
366         struct lsa_RemovePrivilegesFromAccount r;
367         struct lsa_PrivilegeSet privs;
368         BOOL ret = True;
369
370         printf("Testing RemovePrivilegesFromAccount\n");
371
372         r.in.handle = acct_handle;
373         r.in.remove_all = 0;
374         r.in.privs = &privs;
375
376         privs.count = 1;
377         privs.unknown = 0;
378         privs.set = talloc_array_p(mem_ctx, struct lsa_LUIDAttribute, 1);
379         privs.set[0].luid = *luid;
380         privs.set[0].attribute = 0;
381
382         status = dcerpc_lsa_RemovePrivilegesFromAccount(p, mem_ctx, &r);
383         if (!NT_STATUS_IS_OK(status)) {
384                 printf("RemovePrivilegesFromAccount failed - %s\n", nt_errstr(status));
385                 return False;
386         }
387
388         return ret;
389 }
390
391 static BOOL test_AddPrivilegesToAccount(struct dcerpc_pipe *p, 
392                                         TALLOC_CTX *mem_ctx,                              
393                                         struct policy_handle *acct_handle,
394                                         struct lsa_LUID *luid)
395 {
396         NTSTATUS status;
397         struct lsa_AddPrivilegesToAccount r;
398         struct lsa_PrivilegeSet privs;
399         BOOL ret = True;
400
401         printf("Testing AddPrivilegesToAccount\n");
402
403         r.in.handle = acct_handle;
404         r.in.privs = &privs;
405
406         privs.count = 1;
407         privs.unknown = 0;
408         privs.set = talloc_array_p(mem_ctx, struct lsa_LUIDAttribute, 1);
409         privs.set[0].luid = *luid;
410         privs.set[0].attribute = 0;
411
412         status = dcerpc_lsa_AddPrivilegesToAccount(p, mem_ctx, &r);
413         if (!NT_STATUS_IS_OK(status)) {
414                 printf("AddPrivilegesToAccount failed - %s\n", nt_errstr(status));
415                 return False;
416         }
417
418         return ret;
419 }
420
421 static BOOL test_EnumPrivsAccount(struct dcerpc_pipe *p, 
422                                   TALLOC_CTX *mem_ctx,                            
423                                   struct policy_handle *handle,
424                                   struct policy_handle *acct_handle)
425 {
426         NTSTATUS status;
427         struct lsa_EnumPrivsAccount r;
428         BOOL ret = True;
429
430         printf("Testing EnumPrivsAccount\n");
431
432         r.in.handle = acct_handle;
433
434         status = dcerpc_lsa_EnumPrivsAccount(p, mem_ctx, &r);
435         if (!NT_STATUS_IS_OK(status)) {
436                 printf("EnumPrivsAccount failed - %s\n", nt_errstr(status));
437                 return False;
438         }
439
440         if (r.out.privs && r.out.privs->count > 0) {
441                 int i;
442                 for (i=0;i<r.out.privs->count;i++) {
443                         test_LookupPrivName(p, mem_ctx, handle, 
444                                             &r.out.privs->set[i].luid);
445                 }
446
447                 ret &= test_RemovePrivilegesFromAccount(p, mem_ctx, acct_handle, 
448                                                         &r.out.privs->set[0].luid);
449                 ret &= test_AddPrivilegesToAccount(p, mem_ctx, acct_handle, 
450                                                    &r.out.privs->set[0].luid);
451         }
452
453         return ret;
454 }
455
456 static BOOL test_Delete(struct dcerpc_pipe *p, 
457                        TALLOC_CTX *mem_ctx, 
458                        struct policy_handle *handle)
459 {
460         NTSTATUS status;
461         struct lsa_Delete r;
462
463         printf("\ntesting Delete\n");
464
465         r.in.handle = handle;
466         status = dcerpc_lsa_Delete(p, mem_ctx, &r);
467         if (!NT_STATUS_IS_OK(status)) {
468                 printf("Delete failed - %s\n", nt_errstr(status));
469                 return False;
470         }
471
472         printf("\n");
473
474         return True;
475 }
476
477
478 static BOOL test_CreateAccount(struct dcerpc_pipe *p, 
479                                TALLOC_CTX *mem_ctx, 
480                                struct policy_handle *handle)
481 {
482         NTSTATUS status;
483         struct lsa_CreateAccount r;
484         struct dom_sid2 *newsid;
485         struct policy_handle acct_handle;
486
487         newsid = dom_sid_parse_talloc(mem_ctx, "S-1-5-12349876-4321-2854");
488
489         printf("Testing CreateAccount\n");
490
491         r.in.handle = handle;
492         r.in.sid = newsid;
493         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
494         r.out.acct_handle = &acct_handle;
495
496         status = dcerpc_lsa_CreateAccount(p, mem_ctx, &r);
497         if (!NT_STATUS_IS_OK(status)) {
498                 printf("CreateAccount failed - %s\n", nt_errstr(status));
499                 return False;
500         }
501
502         if (!test_Delete(p, mem_ctx, &acct_handle)) {
503                 return False;
504         }
505
506         return True;
507 }
508
509
510 static BOOL test_CreateTrustedDomain(struct dcerpc_pipe *p, 
511                                      TALLOC_CTX *mem_ctx, 
512                                      struct policy_handle *handle)
513 {
514         NTSTATUS status;
515         struct lsa_CreateTrustedDomain r;
516         struct lsa_TrustInformation trustinfo;
517         struct dom_sid *domsid;
518         struct policy_handle dom_handle;
519
520         printf("Testing CreateTrustedDomain\n");
521
522         domsid = dom_sid_parse_talloc(mem_ctx, "S-1-5-21-97398-379795-12345");
523
524         trustinfo.sid = domsid;
525         init_lsa_String(&trustinfo.name, "torturedomain");
526
527         r.in.handle = handle;
528         r.in.info = &trustinfo;
529         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
530         r.out.dom_handle = &dom_handle;
531
532         status = dcerpc_lsa_CreateTrustedDomain(p, mem_ctx, &r);
533         if (!NT_STATUS_IS_OK(status)) {
534                 printf("CreateTrustedDomain failed - %s\n", nt_errstr(status));
535                 return False;
536         }
537
538         if (!test_Delete(p, mem_ctx, &dom_handle)) {
539                 return False;
540         }
541
542         return True;
543 }
544
545 static BOOL test_CreateSecret(struct dcerpc_pipe *p, 
546                               TALLOC_CTX *mem_ctx, 
547                               struct policy_handle *handle)
548 {
549         NTSTATUS status;
550         struct lsa_CreateSecret r;
551         struct lsa_OpenSecret r2;
552         struct lsa_SetSecret r3;
553         struct lsa_QuerySecret r4;
554         struct policy_handle sec_handle, sec_handle2;
555         struct lsa_Delete d;
556         struct lsa_DATA_BUF buf1;
557         struct lsa_DATA_BUF_PTR bufp1;
558         DATA_BLOB enc_key;
559         BOOL ret = True;
560         DATA_BLOB session_key;
561         NTTIME old_mtime, new_mtime;
562         DATA_BLOB blob1, blob2;
563         const char *secret1 = "abcdef12345699qwerty";
564         char *secret2;
565         char *secname;
566
567         printf("Testing CreateSecret\n");
568
569         asprintf(&secname, "torturesecret-%u", (uint_t)random());
570
571         init_lsa_String(&r.in.name, secname);
572
573         r.in.handle = handle;
574         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
575         r.out.sec_handle = &sec_handle;
576
577         status = dcerpc_lsa_CreateSecret(p, mem_ctx, &r);
578         if (!NT_STATUS_IS_OK(status)) {
579                 printf("CreateSecret failed - %s\n", nt_errstr(status));
580                 return False;
581         }
582
583         r2.in.handle = handle;
584         r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
585         r2.in.name = r.in.name;
586         r2.out.sec_handle = &sec_handle2;
587
588         printf("Testing OpenSecret\n");
589
590         status = dcerpc_lsa_OpenSecret(p, mem_ctx, &r2);
591         if (!NT_STATUS_IS_OK(status)) {
592                 printf("OpenSecret failed - %s\n", nt_errstr(status));
593                 ret = False;
594         }
595
596         status = dcerpc_fetch_session_key(p, &session_key);
597         if (!NT_STATUS_IS_OK(status)) {
598                 printf("dcerpc_fetch_session_key failed - %s\n", nt_errstr(status));
599                 ret = False;
600         }
601
602         enc_key = sess_encrypt_string(secret1, &session_key);
603
604         r3.in.handle = &sec_handle;
605         r3.in.new_val = &buf1;
606         r3.in.old_val = NULL;
607         r3.in.new_val->data = enc_key.data;
608         r3.in.new_val->length = enc_key.length;
609         r3.in.new_val->size = enc_key.length;
610
611         printf("Testing SetSecret\n");
612
613         status = dcerpc_lsa_SetSecret(p, mem_ctx, &r3);
614         if (!NT_STATUS_IS_OK(status)) {
615                 printf("SetSecret failed - %s\n", nt_errstr(status));
616                 ret = False;
617         }
618
619         data_blob_free(&enc_key);
620
621         ZERO_STRUCT(new_mtime);
622         ZERO_STRUCT(old_mtime);
623
624         /* fetch the secret back again */
625         r4.in.handle = &sec_handle;
626         r4.in.new_val = &bufp1;
627         r4.in.new_mtime = &new_mtime;
628         r4.in.old_val = NULL;
629         r4.in.old_mtime = NULL;
630
631         bufp1.buf = NULL;
632
633         status = dcerpc_lsa_QuerySecret(p, mem_ctx, &r4);
634         if (!NT_STATUS_IS_OK(status)) {
635                 printf("QuerySecret failed - %s\n", nt_errstr(status));
636                 ret = False;
637         }
638
639         if (r4.out.new_val->buf == NULL) {
640                 printf("No secret buffer returned\n");
641                 ret = False;
642         } else {
643                 blob1.data = r4.out.new_val->buf->data;
644                 blob1.length = r4.out.new_val->buf->length;
645
646                 blob2 = data_blob(NULL, blob1.length);
647
648                 secret2 = sess_decrypt_string(&blob1, &session_key);
649
650                 printf("returned secret '%s'\n", secret2);
651
652                 if (strcmp(secret1, secret2) != 0) {
653                         printf("Returned secret doesn't match\n");
654                         ret = False;
655                 }
656         }
657
658         if (!test_Delete(p, mem_ctx, &sec_handle)) {
659                 ret = False;
660         }
661
662         d.in.handle = &sec_handle2;
663         status = dcerpc_lsa_Delete(p, mem_ctx, &d);
664         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
665                 printf("Second delete expected INVALID_HANDLE - %s\n", nt_errstr(status));
666                 ret = False;
667         }
668
669         return ret;
670 }
671
672
673 static BOOL test_EnumAccountRights(struct dcerpc_pipe *p, 
674                                    TALLOC_CTX *mem_ctx, 
675                                    struct policy_handle *acct_handle,
676                                    struct dom_sid *sid)
677 {
678         NTSTATUS status;
679         struct lsa_EnumAccountRights r;
680         struct lsa_RightSet rights;
681
682         printf("Testing EnumAccountRights\n");
683
684         r.in.handle = acct_handle;
685         r.in.sid = sid;
686         r.out.rights = &rights;
687
688         status = dcerpc_lsa_EnumAccountRights(p, mem_ctx, &r);
689         if (!NT_STATUS_IS_OK(status)) {
690                 printf("EnumAccountRights failed - %s\n", nt_errstr(status));
691                 return False;
692         }
693
694         return True;
695 }
696
697
698 static BOOL test_QuerySecurity(struct dcerpc_pipe *p, 
699                              TALLOC_CTX *mem_ctx, 
700                              struct policy_handle *handle,
701                              struct policy_handle *acct_handle)
702 {
703         NTSTATUS status;
704         struct lsa_QuerySecurity r;
705
706         printf("Testing QuerySecurity\n");
707
708         r.in.handle = acct_handle;
709         r.in.sec_info = 7;
710
711         status = dcerpc_lsa_QuerySecurity(p, mem_ctx, &r);
712         if (!NT_STATUS_IS_OK(status)) {
713                 printf("QuerySecurity failed - %s\n", nt_errstr(status));
714                 return False;
715         }
716
717         return True;
718 }
719
720 static BOOL test_OpenAccount(struct dcerpc_pipe *p, 
721                              TALLOC_CTX *mem_ctx, 
722                              struct policy_handle *handle,
723                              struct dom_sid *sid)
724 {
725         NTSTATUS status;
726         struct lsa_OpenAccount r;
727         struct policy_handle acct_handle;
728
729         printf("Testing OpenAccount\n");
730
731         r.in.handle = handle;
732         r.in.sid = sid;
733         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
734         r.out.acct_handle = &acct_handle;
735
736         status = dcerpc_lsa_OpenAccount(p, mem_ctx, &r);
737         if (!NT_STATUS_IS_OK(status)) {
738                 printf("OpenAccount failed - %s\n", nt_errstr(status));
739                 return False;
740         }
741
742         if (!test_EnumPrivsAccount(p, mem_ctx, handle, &acct_handle)) {
743                 return False;
744         }
745
746         if (!test_QuerySecurity(p, mem_ctx, handle, &acct_handle)) {
747                 return False;
748         }
749
750         return True;
751 }
752
753 static BOOL test_EnumAccounts(struct dcerpc_pipe *p, 
754                           TALLOC_CTX *mem_ctx, 
755                           struct policy_handle *handle)
756 {
757         NTSTATUS status;
758         struct lsa_EnumAccounts r;
759         struct lsa_SidArray sids1, sids2;
760         uint32_t resume_handle = 0;
761         int i;
762
763         printf("\ntesting EnumAccounts\n");
764
765         r.in.handle = handle;
766         r.in.resume_handle = &resume_handle;
767         r.in.num_entries = 100;
768         r.out.resume_handle = &resume_handle;
769         r.out.sids = &sids1;
770
771         resume_handle = 0;
772         while (True) {
773                 status = dcerpc_lsa_EnumAccounts(p, mem_ctx, &r);
774                 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES)) {
775                         break;
776                 }
777                 if (!NT_STATUS_IS_OK(status)) {
778                         printf("EnumAccounts failed - %s\n", nt_errstr(status));
779                         return False;
780                 }
781
782                 if (!test_LookupSids(p, mem_ctx, handle, &sids1)) {
783                         return False;
784                 }
785
786                 if (!test_LookupSids2(p, mem_ctx, handle, &sids1)) {
787                         return False;
788                 }
789
790                 printf("testing all accounts\n");
791                 for (i=0;i<sids1.num_sids;i++) {
792                         test_OpenAccount(p, mem_ctx, handle, sids1.sids[i].sid);
793                         test_EnumAccountRights(p, mem_ctx, handle, sids1.sids[i].sid);
794                 }
795                 printf("\n");
796         }
797
798         if (sids1.num_sids < 3) {
799                 return True;
800         }
801         
802         printf("trying EnumAccounts partial listing (asking for 1 at 2)\n");
803         resume_handle = 2;
804         r.in.num_entries = 1;
805         r.out.sids = &sids2;
806
807         status = dcerpc_lsa_EnumAccounts(p, mem_ctx, &r);
808         if (!NT_STATUS_IS_OK(status)) {
809                 printf("EnumAccounts failed - %s\n", nt_errstr(status));
810                 return False;
811         }
812
813         if (sids2.num_sids != 1) {
814                 printf("Returned wrong number of entries (%d)\n", sids2.num_sids);
815                 return False;
816         }
817
818         return True;
819 }
820
821 static BOOL test_LookupPrivDisplayName(struct dcerpc_pipe *p,
822                                 TALLOC_CTX *mem_ctx,
823                                 struct policy_handle *handle,
824                                 struct lsa_String *priv_name)
825 {
826         struct lsa_LookupPrivDisplayName r;
827         NTSTATUS status;
828         /* produce a reasonable range of language output without screwing up
829            terminals */
830         uint16 language_id = (random() % 4) + 0x409;
831
832         printf("testing LookupPrivDisplayName(%s)\n", priv_name->string);
833         
834         r.in.handle = handle;
835         r.in.name = priv_name;
836         r.in.language_id = &language_id;
837         r.out.language_id = &language_id;
838         r.in.unknown = 0;
839
840         status = dcerpc_lsa_LookupPrivDisplayName(p, mem_ctx, &r);
841         if (!NT_STATUS_IS_OK(status)) {
842                 printf("LookupPrivDisplayName failed - %s\n", nt_errstr(status));
843                 return False;
844         }
845         printf("%s -> \"%s\"  (language 0x%x/0x%x)\n", 
846                priv_name->string, r.out.disp_name->string, 
847                *r.in.language_id, *r.out.language_id);
848
849         return True;
850 }
851
852 static BOOL test_EnumAccountsWithUserRight(struct dcerpc_pipe *p, 
853                                 TALLOC_CTX *mem_ctx,
854                                 struct policy_handle *handle,
855                                 struct lsa_String *priv_name)
856 {
857         struct lsa_EnumAccountsWithUserRight r;
858         struct lsa_SidArray sids;
859         NTSTATUS status;
860
861         ZERO_STRUCT(sids);
862         
863         printf("testing EnumAccountsWithUserRight(%s)\n", priv_name->string);
864         
865         r.in.handle = handle;
866         r.in.name = priv_name;
867         r.out.sids = &sids;
868
869         status = dcerpc_lsa_EnumAccountsWithUserRight(p, mem_ctx, &r);
870
871         /* NT_STATUS_NO_MORE_ENTRIES means noone has this privilege */
872         if (NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES)) {
873                 return True;
874         }
875
876         if (!NT_STATUS_IS_OK(status)) {
877                 printf("EnumAccountsWithUserRight failed - %s\n", nt_errstr(status));
878                 return False;
879         }
880         
881         return True;
882 }
883
884
885 static BOOL test_EnumPrivs(struct dcerpc_pipe *p, 
886                            TALLOC_CTX *mem_ctx, 
887                            struct policy_handle *handle)
888 {
889         NTSTATUS status;
890         struct lsa_EnumPrivs r;
891         struct lsa_PrivArray privs1;
892         uint32_t resume_handle = 0;
893         int i;
894         BOOL ret = True;
895
896         printf("\ntesting EnumPrivs\n");
897
898         r.in.handle = handle;
899         r.in.resume_handle = &resume_handle;
900         r.in.max_count = 100;
901         r.out.resume_handle = &resume_handle;
902         r.out.privs = &privs1;
903
904         resume_handle = 0;
905         status = dcerpc_lsa_EnumPrivs(p, mem_ctx, &r);
906         if (!NT_STATUS_IS_OK(status)) {
907                 printf("EnumPrivs failed - %s\n", nt_errstr(status));
908                 return False;
909         }
910
911         for (i = 0; i< privs1.count; i++) {
912                 test_LookupPrivDisplayName(p, mem_ctx, handle, &privs1.privs[i].name);
913                 test_LookupPrivValue(p, mem_ctx, handle, &privs1.privs[i].name);
914                 if (!test_EnumAccountsWithUserRight(p, mem_ctx, handle, &privs1.privs[i].name)) {
915                         ret = False;
916                 }
917         }
918
919         return ret;
920 }
921
922
923 static BOOL test_EnumTrustDom(struct dcerpc_pipe *p, 
924                               TALLOC_CTX *mem_ctx, 
925                               struct policy_handle *handle)
926 {
927         struct lsa_EnumTrustDom r;
928         NTSTATUS status;
929         uint32_t resume_handle = 0;
930         struct lsa_DomainList domains;
931         int i,j;
932         BOOL ret = True;
933
934         printf("\nTesting EnumTrustDom\n");
935
936         r.in.handle = handle;
937         r.in.resume_handle = &resume_handle;
938         r.in.num_entries = 100;
939         r.out.domains = &domains;
940         r.out.resume_handle = &resume_handle;
941
942         status = dcerpc_lsa_EnumTrustDom(p, mem_ctx, &r);
943
944         /* NO_MORE_ENTRIES is allowed */
945         if (NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES)) {
946                 return True;
947         }
948
949         if (!NT_STATUS_IS_OK(status)) {
950                 printf("EnumTrustDom failed - %s\n", nt_errstr(status));
951                 return False;
952         }
953
954         printf("\nTesting OpenTrustedDomain, OpenTrustedDomainByName and QueryInfoTrustedDomain\n");
955
956         for (i=0; i< domains.count; i++) {
957                 struct lsa_OpenTrustedDomain trust;
958                 struct lsa_OpenTrustedDomainByName trust_by_name;
959                 struct policy_handle trustdom_handle;
960                 struct policy_handle handle2;
961                 struct lsa_Close c;
962                 int levels [] = {1, 3, 6, 8, 12};
963                 
964                 trust.in.handle = handle;
965                 trust.in.sid = domains.domains[i].sid;
966                 trust.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
967                 trust.out.trustdom_handle = &trustdom_handle;
968
969                 status = dcerpc_lsa_OpenTrustedDomain(p, mem_ctx, &trust);
970
971                 if (!NT_STATUS_IS_OK(status)) {
972                         printf("OpenTrustedDomain failed - %s\n", nt_errstr(status));
973                         return False;
974                 }
975
976                 c.in.handle = &trustdom_handle;
977                 c.out.handle = &handle2;
978                 
979                 for (j=0; j < ARRAY_SIZE(levels); j++) {
980                         struct lsa_QueryTrustedDomainInfo q;
981                         union lsa_TrustedDomainInfo info;
982                         q.in.trustdom_handle = &trustdom_handle;
983                         q.in.level = levels[j];
984                         q.out.info = &info;
985                         status = dcerpc_lsa_QueryTrustedDomainInfo(p, mem_ctx, &q);
986                         if (!NT_STATUS_IS_OK(status)) {
987                                 printf("QueryTrustedDomainInfo level %d failed - %s\n", 
988                                        levels[j], nt_errstr(status));
989                                 ret = False;
990                         }
991                 }
992                 
993                 status = dcerpc_lsa_Close(p, mem_ctx, &c);
994                 if (!NT_STATUS_IS_OK(status)) {
995                         printf("Close of trusted domain failed - %s\n", nt_errstr(status));
996                         return False;
997                 }
998
999                 trust_by_name.in.handle = handle;
1000                 trust_by_name.in.name = domains.domains[i].name;
1001                 trust_by_name.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1002                 trust_by_name.out.trustdom_handle = &trustdom_handle;
1003                 
1004                 status = dcerpc_lsa_OpenTrustedDomainByName(p, mem_ctx, &trust_by_name);
1005
1006                 if (!NT_STATUS_IS_OK(status)) {
1007                         printf("OpenTrustedDomainByName failed - %s\n", nt_errstr(status));
1008                         return False;
1009                 }
1010
1011                 for (j=0; j < ARRAY_SIZE(levels); j++) {
1012                         struct lsa_QueryTrustedDomainInfo q;
1013                         union lsa_TrustedDomainInfo info;
1014                         q.in.trustdom_handle = &trustdom_handle;
1015                         q.in.level = levels[j];
1016                         q.out.info = &info;
1017                         status = dcerpc_lsa_QueryTrustedDomainInfo(p, mem_ctx, &q);
1018                         if (!NT_STATUS_IS_OK(status)) {
1019                                 printf("QueryTrustedDomainInfo level %d failed - %s\n", 
1020                                        levels[j], nt_errstr(status));
1021                                 ret = False;
1022                         }
1023                 }
1024                 
1025                 c.in.handle = &trustdom_handle;
1026                 c.out.handle = &handle2;
1027
1028                 status = dcerpc_lsa_Close(p, mem_ctx, &c);
1029                 if (!NT_STATUS_IS_OK(status)) {
1030                         printf("Close of trusted domain failed - %s\n", nt_errstr(status));
1031                         return False;
1032                 }
1033
1034                 for (j=0; j < ARRAY_SIZE(levels); j++) {
1035                         struct lsa_QueryTrustedDomainInfoBySid q;
1036                         union lsa_TrustedDomainInfo info;
1037                         q.in.handle  = handle;
1038                         q.in.dom_sid = domains.domains[i].sid;
1039                         q.in.level   = levels[j];
1040                         q.out.info   = &info;
1041                         status = dcerpc_lsa_QueryTrustedDomainInfoBySid(p, mem_ctx, &q);
1042                         if (!NT_STATUS_IS_OK(status)) {
1043                                 printf("QueryTrustedDomainInfoBySid level %d failed - %s\n", 
1044                                        levels[j], nt_errstr(status));
1045                                 ret = False;
1046                         }
1047                 }
1048                 
1049                 for (j=0; j < ARRAY_SIZE(levels); j++) {
1050                         struct lsa_QueryTrustedDomainInfoByName q;
1051                         union lsa_TrustedDomainInfo info;
1052                         q.in.handle         = handle;
1053                         q.in.trusted_domain = domains.domains[i].name;
1054                         q.in.level          = levels[j];
1055                         q.out.info          = &info;
1056                         status = dcerpc_lsa_QueryTrustedDomainInfoByName(p, mem_ctx, &q);
1057                         if (!NT_STATUS_IS_OK(status)) {
1058                                 printf("QueryTrustedDomainInfoByName level %d failed - %s\n", 
1059                                        levels[j], nt_errstr(status));
1060                                 ret = False;
1061                         }
1062                 }
1063                 
1064                 
1065
1066         }
1067
1068         return ret;
1069 }
1070
1071 static BOOL test_QueryInfoPolicy(struct dcerpc_pipe *p, 
1072                                  TALLOC_CTX *mem_ctx, 
1073                                  struct policy_handle *handle)
1074 {
1075         struct lsa_QueryInfoPolicy r;
1076         NTSTATUS status;
1077         int i;
1078         BOOL ret = True;
1079         printf("\nTesting QueryInfoPolicy\n");
1080
1081         for (i=1;i<13;i++) {
1082                 r.in.handle = handle;
1083                 r.in.level = i;
1084
1085                 printf("\ntrying QueryInfoPolicy level %d\n", i);
1086
1087                 status = dcerpc_lsa_QueryInfoPolicy(p, mem_ctx, &r);
1088
1089                 if ((i == 9 || i == 10 || i == 11) &&
1090                     NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1091                         printf("server failed level %u (OK)\n", i);
1092                         continue;
1093                 }
1094
1095                 if (!NT_STATUS_IS_OK(status)) {
1096                         printf("QueryInfoPolicy failed - %s\n", nt_errstr(status));
1097                         ret = False;
1098                         continue;
1099                 }
1100         }
1101
1102         return ret;
1103 }
1104
1105 static BOOL test_QueryInfoPolicy2(struct dcerpc_pipe *p, 
1106                                   TALLOC_CTX *mem_ctx, 
1107                                   struct policy_handle *handle)
1108 {
1109         struct lsa_QueryInfoPolicy2 r;
1110         NTSTATUS status;
1111         int i;
1112         BOOL ret = True;
1113         printf("\nTesting QueryInfoPolicy2\n");
1114
1115         for (i=1;i<13;i++) {
1116                 r.in.handle = handle;
1117                 r.in.level = i;
1118
1119                 printf("\ntrying QueryInfoPolicy2 level %d\n", i);
1120
1121                 status = dcerpc_lsa_QueryInfoPolicy2(p, mem_ctx, &r);
1122
1123                 if ((i == 9 || i == 10 || i == 11) &&
1124                     NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1125                         printf("server failed level %u (OK)\n", i);
1126                         continue;
1127                 }
1128
1129                 if (!NT_STATUS_IS_OK(status)) {
1130                         printf("QueryInfoPolicy2 failed - %s\n", nt_errstr(status));
1131                         ret = False;
1132                         continue;
1133                 }
1134         }
1135
1136         return ret;
1137 }
1138
1139 static BOOL test_Close(struct dcerpc_pipe *p, 
1140                        TALLOC_CTX *mem_ctx, 
1141                        struct policy_handle *handle)
1142 {
1143         NTSTATUS status;
1144         struct lsa_Close r;
1145         struct policy_handle handle2;
1146
1147         printf("\ntesting Close\n");
1148
1149         r.in.handle = handle;
1150         r.out.handle = &handle2;
1151
1152         status = dcerpc_lsa_Close(p, mem_ctx, &r);
1153         if (!NT_STATUS_IS_OK(status)) {
1154                 printf("Close failed - %s\n", nt_errstr(status));
1155                 return False;
1156         }
1157
1158         status = dcerpc_lsa_Close(p, mem_ctx, &r);
1159         /* its really a fault - we need a status code for rpc fault */
1160         if (!NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
1161                 printf("Close failed - %s\n", nt_errstr(status));
1162                 return False;
1163         }
1164
1165         printf("\n");
1166
1167         return True;
1168 }
1169
1170 BOOL torture_rpc_lsa(void)
1171 {
1172         NTSTATUS status;
1173         struct dcerpc_pipe *p;
1174         TALLOC_CTX *mem_ctx;
1175         BOOL ret = True;
1176         struct policy_handle handle;
1177
1178         mem_ctx = talloc_init("torture_rpc_lsa");
1179
1180         status = torture_rpc_connection(&p, 
1181                                         DCERPC_LSARPC_NAME, 
1182                                         DCERPC_LSARPC_UUID, 
1183                                         DCERPC_LSARPC_VERSION);
1184         if (!NT_STATUS_IS_OK(status)) {
1185                 return False;
1186         }
1187
1188         if (!test_OpenPolicy(p, mem_ctx)) {
1189                 ret = False;
1190         }
1191
1192         if (!test_OpenPolicy2(p, mem_ctx, &handle)) {
1193                 ret = False;
1194         }
1195
1196         if (!test_many_LookupSids(p, mem_ctx, &handle)) {
1197                 ret = False;
1198         }
1199
1200         if (!test_CreateAccount(p, mem_ctx, &handle)) {
1201                 ret = False;
1202         }
1203
1204         if (!test_CreateSecret(p, mem_ctx, &handle)) {
1205                 ret = False;
1206         }
1207
1208         if (!test_CreateTrustedDomain(p, mem_ctx, &handle)) {
1209                 ret = False;
1210         }
1211
1212         if (!test_EnumAccounts(p, mem_ctx, &handle)) {
1213                 ret = False;
1214         }
1215
1216         if (!test_EnumPrivs(p, mem_ctx, &handle)) {
1217                 ret = False;
1218         }
1219
1220         if (!test_EnumTrustDom(p, mem_ctx, &handle)) {
1221                 ret = False;
1222         }
1223
1224         if (!test_QueryInfoPolicy(p, mem_ctx, &handle)) {
1225                 ret = False;
1226         }
1227
1228         if (!test_QueryInfoPolicy2(p, mem_ctx, &handle)) {
1229                 ret = False;
1230         }
1231         
1232 #if 0
1233         if (!test_Delete(p, mem_ctx, &handle)) {
1234                 ret = False;
1235         }
1236 #endif
1237         
1238         if (!test_Close(p, mem_ctx, &handle)) {
1239                 ret = False;
1240         }
1241
1242         talloc_destroy(mem_ctx);
1243
1244         torture_rpc_close(p);
1245
1246         return ret;
1247 }