r3978: added IDL and test code for lsa_LookupSids2() and lsa_LookupNames2()
[ira/wip.git] / source / 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_RIGHTS_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_RIGHTS_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(mem_ctx, tnames->count * sizeof(names[0]));
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(mem_ctx, tnames->count * sizeof(names[0]));
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 = 1000;
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_LookupPrivName(struct dcerpc_pipe *p, 
321                                 TALLOC_CTX *mem_ctx, 
322                                 struct policy_handle *handle,
323                                 struct lsa_LUID *luid)
324 {
325         NTSTATUS status;
326         struct lsa_LookupPrivName r;
327
328         r.in.handle = handle;
329         r.in.luid = luid;
330
331         status = dcerpc_lsa_LookupPrivName(p, mem_ctx, &r);
332         if (!NT_STATUS_IS_OK(status)) {
333                 printf("\nLookupPrivName failed - %s\n", nt_errstr(status));
334                 return False;
335         }
336
337         return True;
338 }
339
340 static BOOL test_EnumPrivsAccount(struct dcerpc_pipe *p, 
341                                   TALLOC_CTX *mem_ctx,                            
342                                   struct policy_handle *handle,
343                                   struct policy_handle *acct_handle)
344 {
345         NTSTATUS status;
346         struct lsa_EnumPrivsAccount r;
347
348         printf("Testing EnumPrivsAccount\n");
349
350         r.in.handle = acct_handle;
351
352         status = dcerpc_lsa_EnumPrivsAccount(p, mem_ctx, &r);
353         if (!NT_STATUS_IS_OK(status)) {
354                 printf("EnumPrivsAccount failed - %s\n", nt_errstr(status));
355                 return False;
356         }
357
358         if (r.out.privs) {
359                 int i;
360                 for (i=0;i<r.out.privs->count;i++) {
361                         test_LookupPrivName(p, mem_ctx, handle, 
362                                             &r.out.privs->set[i].luid);
363                 }
364         }
365
366         return True;
367 }
368
369 static BOOL test_Delete(struct dcerpc_pipe *p, 
370                        TALLOC_CTX *mem_ctx, 
371                        struct policy_handle *handle)
372 {
373         NTSTATUS status;
374         struct lsa_Delete r;
375
376         printf("\ntesting Delete\n");
377
378         r.in.handle = handle;
379         status = dcerpc_lsa_Delete(p, mem_ctx, &r);
380         if (!NT_STATUS_IS_OK(status)) {
381                 printf("Delete failed - %s\n", nt_errstr(status));
382                 return False;
383         }
384
385         printf("\n");
386
387         return True;
388 }
389
390
391 static BOOL test_CreateAccount(struct dcerpc_pipe *p, 
392                                TALLOC_CTX *mem_ctx, 
393                                struct policy_handle *handle)
394 {
395         NTSTATUS status;
396         struct lsa_CreateAccount r;
397         struct dom_sid2 *newsid;
398         struct policy_handle acct_handle;
399
400         newsid = dom_sid_parse_talloc(mem_ctx, "S-1-5-12349876-4321-2854");
401
402         printf("Testing CreateAccount\n");
403
404         r.in.handle = handle;
405         r.in.sid = newsid;
406         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
407         r.out.acct_handle = &acct_handle;
408
409         status = dcerpc_lsa_CreateAccount(p, mem_ctx, &r);
410         if (!NT_STATUS_IS_OK(status)) {
411                 printf("CreateAccount failed - %s\n", nt_errstr(status));
412                 return False;
413         }
414
415         if (!test_Delete(p, mem_ctx, &acct_handle)) {
416                 return False;
417         }
418
419         return True;
420 }
421
422
423 static BOOL test_CreateTrustedDomain(struct dcerpc_pipe *p, 
424                                      TALLOC_CTX *mem_ctx, 
425                                      struct policy_handle *handle)
426 {
427         NTSTATUS status;
428         struct lsa_CreateTrustedDomain r;
429         struct lsa_TrustInformation trustinfo;
430         struct dom_sid *domsid;
431         struct policy_handle dom_handle;
432
433         printf("Testing CreateTrustedDomain\n");
434
435         domsid = dom_sid_parse_talloc(mem_ctx, "S-1-5-21-97398-379795-12345");
436
437         trustinfo.sid = domsid;
438         init_lsa_String(&trustinfo.name, "torturedomain");
439
440         r.in.handle = handle;
441         r.in.info = &trustinfo;
442         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
443         r.out.dom_handle = &dom_handle;
444
445         status = dcerpc_lsa_CreateTrustedDomain(p, mem_ctx, &r);
446         if (!NT_STATUS_IS_OK(status)) {
447                 printf("CreateTrustedDomain failed - %s\n", nt_errstr(status));
448                 return False;
449         }
450
451         if (!test_Delete(p, mem_ctx, &dom_handle)) {
452                 return False;
453         }
454
455         return True;
456 }
457
458 static BOOL test_CreateSecret(struct dcerpc_pipe *p, 
459                               TALLOC_CTX *mem_ctx, 
460                               struct policy_handle *handle)
461 {
462         NTSTATUS status;
463         struct lsa_CreateSecret r;
464         struct lsa_OpenSecret r2;
465         struct lsa_SetSecret r3;
466         struct lsa_QuerySecret r4;
467         struct policy_handle sec_handle, sec_handle2;
468         struct lsa_Delete d;
469         struct lsa_DATA_BUF buf1;
470         struct lsa_DATA_BUF_PTR bufp1;
471         DATA_BLOB enc_key;
472         BOOL ret = True;
473         DATA_BLOB session_key;
474         NTTIME old_mtime, new_mtime;
475         DATA_BLOB blob1, blob2;
476         const char *secret1 = "abcdef12345699qwerty";
477         char *secret2;
478         char *secname;
479
480         printf("Testing CreateSecret\n");
481
482         asprintf(&secname, "torturesecret-%u", (uint_t)random());
483
484         init_lsa_String(&r.in.name, secname);
485
486         r.in.handle = handle;
487         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
488         r.out.sec_handle = &sec_handle;
489
490         status = dcerpc_lsa_CreateSecret(p, mem_ctx, &r);
491         if (!NT_STATUS_IS_OK(status)) {
492                 printf("CreateSecret failed - %s\n", nt_errstr(status));
493                 return False;
494         }
495
496         r2.in.handle = handle;
497         r2.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
498         r2.in.name = r.in.name;
499         r2.out.sec_handle = &sec_handle2;
500
501         printf("Testing OpenSecret\n");
502
503         status = dcerpc_lsa_OpenSecret(p, mem_ctx, &r2);
504         if (!NT_STATUS_IS_OK(status)) {
505                 printf("OpenSecret failed - %s\n", nt_errstr(status));
506                 ret = False;
507         }
508
509         status = dcerpc_fetch_session_key(p, &session_key);
510         if (!NT_STATUS_IS_OK(status)) {
511                 printf("dcerpc_fetch_session_key failed - %s\n", nt_errstr(status));
512                 ret = False;
513         }
514
515         enc_key = sess_encrypt_string(secret1, &session_key);
516
517         r3.in.handle = &sec_handle;
518         r3.in.new_val = &buf1;
519         r3.in.old_val = NULL;
520         r3.in.new_val->data = enc_key.data;
521         r3.in.new_val->length = enc_key.length;
522         r3.in.new_val->size = enc_key.length;
523
524         printf("Testing SetSecret\n");
525
526         status = dcerpc_lsa_SetSecret(p, mem_ctx, &r3);
527         if (!NT_STATUS_IS_OK(status)) {
528                 printf("SetSecret failed - %s\n", nt_errstr(status));
529                 ret = False;
530         }
531
532         data_blob_free(&enc_key);
533
534         ZERO_STRUCT(new_mtime);
535         ZERO_STRUCT(old_mtime);
536
537         /* fetch the secret back again */
538         r4.in.handle = &sec_handle;
539         r4.in.new_val = &bufp1;
540         r4.in.new_mtime = &new_mtime;
541         r4.in.old_val = NULL;
542         r4.in.old_mtime = NULL;
543
544         bufp1.buf = NULL;
545
546         status = dcerpc_lsa_QuerySecret(p, mem_ctx, &r4);
547         if (!NT_STATUS_IS_OK(status)) {
548                 printf("QuerySecret failed - %s\n", nt_errstr(status));
549                 ret = False;
550         }
551
552         if (r4.out.new_val->buf == NULL) {
553                 printf("No secret buffer returned\n");
554                 ret = False;
555         } else {
556                 blob1.data = r4.out.new_val->buf->data;
557                 blob1.length = r4.out.new_val->buf->length;
558
559                 blob2 = data_blob(NULL, blob1.length);
560
561                 secret2 = sess_decrypt_string(&blob1, &session_key);
562
563                 printf("returned secret '%s'\n", secret2);
564
565                 if (strcmp(secret1, secret2) != 0) {
566                         printf("Returned secret doesn't match\n");
567                         ret = False;
568                 }
569         }
570
571         if (!test_Delete(p, mem_ctx, &sec_handle)) {
572                 ret = False;
573         }
574
575         d.in.handle = &sec_handle2;
576         status = dcerpc_lsa_Delete(p, mem_ctx, &d);
577         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
578                 printf("Second delete expected INVALID_HANDLE - %s\n", nt_errstr(status));
579                 ret = False;
580         }
581
582         return ret;
583 }
584
585
586 static BOOL test_EnumAccountRights(struct dcerpc_pipe *p, 
587                                    TALLOC_CTX *mem_ctx, 
588                                    struct policy_handle *acct_handle,
589                                    struct dom_sid *sid)
590 {
591         NTSTATUS status;
592         struct lsa_EnumAccountRights r;
593         struct lsa_RightSet rights;
594
595         printf("Testing EnumAccountRights\n");
596
597         r.in.handle = acct_handle;
598         r.in.sid = sid;
599         r.out.rights = &rights;
600
601         status = dcerpc_lsa_EnumAccountRights(p, mem_ctx, &r);
602         if (!NT_STATUS_IS_OK(status)) {
603                 printf("EnumAccountRights failed - %s\n", nt_errstr(status));
604                 return False;
605         }
606
607         return True;
608 }
609
610
611 static BOOL test_QuerySecurity(struct dcerpc_pipe *p, 
612                              TALLOC_CTX *mem_ctx, 
613                              struct policy_handle *handle,
614                              struct policy_handle *acct_handle)
615 {
616         NTSTATUS status;
617         struct lsa_QuerySecurity r;
618
619         printf("Testing QuerySecuriy\n");
620
621         r.in.handle = acct_handle;
622         r.in.sec_info = 7;
623
624         status = dcerpc_lsa_QuerySecurity(p, mem_ctx, &r);
625         if (!NT_STATUS_IS_OK(status)) {
626                 printf("QuerySecurity failed - %s\n", nt_errstr(status));
627                 return False;
628         }
629
630         return True;
631 }
632
633 static BOOL test_OpenAccount(struct dcerpc_pipe *p, 
634                              TALLOC_CTX *mem_ctx, 
635                              struct policy_handle *handle,
636                              struct dom_sid *sid)
637 {
638         NTSTATUS status;
639         struct lsa_OpenAccount r;
640         struct policy_handle acct_handle;
641
642         printf("Testing OpenAccount\n");
643
644         r.in.handle = handle;
645         r.in.sid = sid;
646         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
647         r.out.acct_handle = &acct_handle;
648
649         status = dcerpc_lsa_OpenAccount(p, mem_ctx, &r);
650         if (!NT_STATUS_IS_OK(status)) {
651                 printf("OpenAccount failed - %s\n", nt_errstr(status));
652                 return False;
653         }
654
655         if (!test_EnumPrivsAccount(p, mem_ctx, handle, &acct_handle)) {
656                 return False;
657         }
658
659         if (!test_QuerySecurity(p, mem_ctx, handle, &acct_handle)) {
660                 return False;
661         }
662
663         return True;
664 }
665
666 static BOOL test_EnumAccounts(struct dcerpc_pipe *p, 
667                           TALLOC_CTX *mem_ctx, 
668                           struct policy_handle *handle)
669 {
670         NTSTATUS status;
671         struct lsa_EnumAccounts r;
672         struct lsa_SidArray sids1, sids2;
673         uint32_t resume_handle = 0;
674         int i;
675
676         printf("\ntesting EnumAccounts\n");
677
678         r.in.handle = handle;
679         r.in.resume_handle = &resume_handle;
680         r.in.num_entries = 100;
681         r.out.resume_handle = &resume_handle;
682         r.out.sids = &sids1;
683
684         resume_handle = 0;
685         status = dcerpc_lsa_EnumAccounts(p, mem_ctx, &r);
686         if (!NT_STATUS_IS_OK(status)) {
687                 printf("EnumAccounts failed - %s\n", nt_errstr(status));
688                 return False;
689         }
690
691         if (!test_LookupSids(p, mem_ctx, handle, &sids1)) {
692                 return False;
693         }
694
695         if (!test_LookupSids2(p, mem_ctx, handle, &sids1)) {
696                 return False;
697         }
698
699         printf("testing all accounts\n");
700         for (i=0;i<sids1.num_sids;i++) {
701                 test_OpenAccount(p, mem_ctx, handle, sids1.sids[i].sid);
702                 test_EnumAccountRights(p, mem_ctx, handle, sids1.sids[i].sid);
703         }
704         printf("\n");
705
706         if (sids1.num_sids < 3) {
707                 return True;
708         }
709         
710         printf("trying EnumAccounts partial listing (asking for 1 at 2)\n");
711         resume_handle = 2;
712         r.in.num_entries = 1;
713         r.out.sids = &sids2;
714
715         status = dcerpc_lsa_EnumAccounts(p, mem_ctx, &r);
716         if (!NT_STATUS_IS_OK(status)) {
717                 printf("EnumAccounts failed - %s\n", nt_errstr(status));
718                 return False;
719         }
720
721         if (sids2.num_sids != 1) {
722                 printf("Returned wrong number of entries (%d)\n", sids2.num_sids);
723                 return False;
724         }
725
726         return True;
727 }
728
729 static BOOL test_LookupPrivDisplayName(struct dcerpc_pipe *p,
730                                 TALLOC_CTX *mem_ctx,
731                                 struct policy_handle *handle,
732                                 struct lsa_String *priv_name)
733 {
734         struct lsa_LookupPrivDisplayName r;
735         NTSTATUS status;
736         /* produce a reasonable range of language output without screwing up
737            terminals */
738         uint16 language_id = (random() % 4) + 0x409;
739
740         printf("testing LookupPrivDisplayName(%s)\n", priv_name->string);
741         
742         r.in.handle = handle;
743         r.in.name = priv_name;
744         r.in.language_id = &language_id;
745         r.out.language_id = &language_id;
746         r.in.unknown = 0;
747
748         status = dcerpc_lsa_LookupPrivDisplayName(p, mem_ctx, &r);
749         if (!NT_STATUS_IS_OK(status)) {
750                 printf("LookupPrivDisplayName failed - %s\n", nt_errstr(status));
751                 return False;
752         }
753         printf("%s -> \"%s\"  (language 0x%x/0x%x)\n", 
754                priv_name->string, r.out.disp_name->string, 
755                *r.in.language_id, *r.out.language_id);
756
757         return True;
758 }
759
760 static BOOL test_EnumAccountsWithUserRight(struct dcerpc_pipe *p, 
761                                 TALLOC_CTX *mem_ctx,
762                                 struct policy_handle *handle,
763                                 struct lsa_String *priv_name)
764 {
765         struct lsa_EnumAccountsWithUserRight r;
766         struct lsa_SidArray sids;
767         NTSTATUS status;
768
769         ZERO_STRUCT(sids);
770         
771         printf("testing EnumAccountsWithUserRight(%s)\n", priv_name->string);
772         
773         r.in.handle = handle;
774         r.in.name = priv_name;
775         r.out.sids = &sids;
776
777         status = dcerpc_lsa_EnumAccountsWithUserRight(p, mem_ctx, &r);
778
779         /* NT_STATUS_NO_MORE_ENTRIES means noone has this privilege */
780         if (NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES)) {
781                 return True;
782         }
783
784         if (!NT_STATUS_IS_OK(status)) {
785                 printf("EnumAccountsWithUserRight failed - %s\n", nt_errstr(status));
786                 return False;
787         }
788         
789         return True;
790 }
791
792
793 static BOOL test_EnumPrivs(struct dcerpc_pipe *p, 
794                            TALLOC_CTX *mem_ctx, 
795                            struct policy_handle *handle)
796 {
797         NTSTATUS status;
798         struct lsa_EnumPrivs r;
799         struct lsa_PrivArray privs1;
800         uint32_t resume_handle = 0;
801         int i;
802         BOOL ret = True;
803
804         printf("\ntesting EnumPrivs\n");
805
806         r.in.handle = handle;
807         r.in.resume_handle = &resume_handle;
808         r.in.max_count = 1000;
809         r.out.resume_handle = &resume_handle;
810         r.out.privs = &privs1;
811
812         resume_handle = 0;
813         status = dcerpc_lsa_EnumPrivs(p, mem_ctx, &r);
814         if (!NT_STATUS_IS_OK(status)) {
815                 printf("EnumPrivs failed - %s\n", nt_errstr(status));
816                 return False;
817         }
818
819         for (i = 0; i< privs1.count; i++) {
820                 test_LookupPrivDisplayName(p, mem_ctx, handle, &privs1.privs[i].name);
821                 if (!test_EnumAccountsWithUserRight(p, mem_ctx, handle, &privs1.privs[i].name)) {
822                         ret = False;
823                 }
824         }
825
826         return ret;
827 }
828
829
830 static BOOL test_EnumTrustDom(struct dcerpc_pipe *p, 
831                               TALLOC_CTX *mem_ctx, 
832                               struct policy_handle *handle)
833 {
834         struct lsa_EnumTrustDom r;
835         NTSTATUS status;
836         uint32_t resume_handle = 0;
837         struct lsa_DomainList domains;
838         int i,j;
839         BOOL ret = True;
840
841         printf("\nTesting EnumTrustDom\n");
842
843         r.in.handle = handle;
844         r.in.resume_handle = &resume_handle;
845         r.in.num_entries = 1000;
846         r.out.domains = &domains;
847         r.out.resume_handle = &resume_handle;
848
849         status = dcerpc_lsa_EnumTrustDom(p, mem_ctx, &r);
850
851         /* NO_MORE_ENTRIES is allowed */
852         if (NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES)) {
853                 return True;
854         }
855
856         if (!NT_STATUS_IS_OK(status)) {
857                 printf("EnumTrustDom failed - %s\n", nt_errstr(status));
858                 return False;
859         }
860
861         printf("\nTesting OpenTrustedDomain, OpenTrustedDomainByName and QueryInfoTrustedDomain\n");
862
863         for (i=0; i< domains.count; i++) {
864                 struct lsa_OpenTrustedDomain trust;
865                 struct lsa_OpenTrustedDomainByName trust_by_name;
866                 struct policy_handle trustdom_handle;
867                 struct policy_handle handle2;
868                 struct lsa_Close c;
869                 int levels [] = {1, 3, 6, 8, 12};
870                 
871                 trust.in.handle = handle;
872                 trust.in.sid = domains.domains[i].sid;
873                 trust.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
874                 trust.out.trustdom_handle = &trustdom_handle;
875
876                 status = dcerpc_lsa_OpenTrustedDomain(p, mem_ctx, &trust);
877
878                 if (!NT_STATUS_IS_OK(status)) {
879                         printf("OpenTrustedDomain failed - %s\n", nt_errstr(status));
880                         return False;
881                 }
882
883                 c.in.handle = &trustdom_handle;
884                 c.out.handle = &handle2;
885                 
886                 for (j=0; j < ARRAY_SIZE(levels); j++) {
887                         struct lsa_QueryTrustedDomainInfo q;
888                         union lsa_TrustedDomainInfo info;
889                         q.in.trustdom_handle = &trustdom_handle;
890                         q.in.level = levels[j];
891                         q.out.info = &info;
892                         status = dcerpc_lsa_QueryTrustedDomainInfo(p, mem_ctx, &q);
893                         if (!NT_STATUS_IS_OK(status)) {
894                                 printf("QueryTrustedDomainInfo level %d failed - %s\n", 
895                                        levels[j], nt_errstr(status));
896                                 ret = False;
897                         }
898                 }
899                 
900                 status = dcerpc_lsa_Close(p, mem_ctx, &c);
901                 if (!NT_STATUS_IS_OK(status)) {
902                         printf("Close of trusted domain failed - %s\n", nt_errstr(status));
903                         return False;
904                 }
905
906                 trust_by_name.in.handle = handle;
907                 trust_by_name.in.name = domains.domains[i].name;
908                 trust_by_name.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
909                 trust_by_name.out.trustdom_handle = &trustdom_handle;
910                 
911                 status = dcerpc_lsa_OpenTrustedDomainByName(p, mem_ctx, &trust_by_name);
912
913                 if (!NT_STATUS_IS_OK(status)) {
914                         printf("OpenTrustedDomainByName failed - %s\n", nt_errstr(status));
915                         return False;
916                 }
917
918                 for (j=0; j < ARRAY_SIZE(levels); j++) {
919                         struct lsa_QueryTrustedDomainInfo q;
920                         union lsa_TrustedDomainInfo info;
921                         q.in.trustdom_handle = &trustdom_handle;
922                         q.in.level = levels[j];
923                         q.out.info = &info;
924                         status = dcerpc_lsa_QueryTrustedDomainInfo(p, mem_ctx, &q);
925                         if (!NT_STATUS_IS_OK(status)) {
926                                 printf("QueryTrustedDomainInfo level %d failed - %s\n", 
927                                        levels[j], nt_errstr(status));
928                                 ret = False;
929                         }
930                 }
931                 
932                 c.in.handle = &trustdom_handle;
933                 c.out.handle = &handle2;
934
935                 status = dcerpc_lsa_Close(p, mem_ctx, &c);
936                 if (!NT_STATUS_IS_OK(status)) {
937                         printf("Close of trusted domain failed - %s\n", nt_errstr(status));
938                         return False;
939                 }
940
941                 for (j=0; j < ARRAY_SIZE(levels); j++) {
942                         struct lsa_QueryTrustedDomainInfoBySid q;
943                         union lsa_TrustedDomainInfo info;
944                         q.in.handle  = handle;
945                         q.in.dom_sid = domains.domains[i].sid;
946                         q.in.level   = levels[j];
947                         q.out.info   = &info;
948                         status = dcerpc_lsa_QueryTrustedDomainInfoBySid(p, mem_ctx, &q);
949                         if (!NT_STATUS_IS_OK(status)) {
950                                 printf("QueryTrustedDomainInfoBySid level %d failed - %s\n", 
951                                        levels[j], nt_errstr(status));
952                                 ret = False;
953                         }
954                 }
955                 
956                 for (j=0; j < ARRAY_SIZE(levels); j++) {
957                         struct lsa_QueryTrustedDomainInfoByName q;
958                         union lsa_TrustedDomainInfo info;
959                         q.in.handle         = handle;
960                         q.in.trusted_domain = domains.domains[i].name;
961                         q.in.level          = levels[j];
962                         q.out.info          = &info;
963                         status = dcerpc_lsa_QueryTrustedDomainInfoByName(p, mem_ctx, &q);
964                         if (!NT_STATUS_IS_OK(status)) {
965                                 printf("QueryTrustedDomainInfoByName level %d failed - %s\n", 
966                                        levels[j], nt_errstr(status));
967                                 ret = False;
968                         }
969                 }
970                 
971                 
972
973         }
974
975         return ret;
976 }
977
978 static BOOL test_QueryInfoPolicy(struct dcerpc_pipe *p, 
979                                  TALLOC_CTX *mem_ctx, 
980                                  struct policy_handle *handle)
981 {
982         struct lsa_QueryInfoPolicy r;
983         NTSTATUS status;
984         int i;
985         BOOL ret = True;
986         printf("\nTesting QueryInfoPolicy\n");
987
988         for (i=1;i<13;i++) {
989                 r.in.handle = handle;
990                 r.in.level = i;
991
992                 printf("\ntrying QueryInfoPolicy level %d\n", i);
993
994                 status = dcerpc_lsa_QueryInfoPolicy(p, mem_ctx, &r);
995
996                 if ((i == 9 || i == 10 || i == 11) &&
997                     NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
998                         printf("server failed level %u (OK)\n", i);
999                         continue;
1000                 }
1001
1002                 if (!NT_STATUS_IS_OK(status)) {
1003                         printf("QueryInfoPolicy failed - %s\n", nt_errstr(status));
1004                         ret = False;
1005                         continue;
1006                 }
1007         }
1008
1009         return ret;
1010 }
1011
1012 static BOOL test_QueryInfoPolicy2(struct dcerpc_pipe *p, 
1013                                   TALLOC_CTX *mem_ctx, 
1014                                   struct policy_handle *handle)
1015 {
1016         struct lsa_QueryInfoPolicy2 r;
1017         NTSTATUS status;
1018         int i;
1019         BOOL ret = True;
1020         printf("\nTesting QueryInfoPolicy2\n");
1021
1022         for (i=1;i<13;i++) {
1023                 r.in.handle = handle;
1024                 r.in.level = i;
1025
1026                 printf("\ntrying QueryInfoPolicy2 level %d\n", i);
1027
1028                 status = dcerpc_lsa_QueryInfoPolicy2(p, mem_ctx, &r);
1029
1030                 if ((i == 9 || i == 10 || i == 11) &&
1031                     NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1032                         printf("server failed level %u (OK)\n", i);
1033                         continue;
1034                 }
1035
1036                 if (!NT_STATUS_IS_OK(status)) {
1037                         printf("QueryInfoPolicy2 failed - %s\n", nt_errstr(status));
1038                         ret = False;
1039                         continue;
1040                 }
1041         }
1042
1043         return ret;
1044 }
1045
1046 static BOOL test_Close(struct dcerpc_pipe *p, 
1047                        TALLOC_CTX *mem_ctx, 
1048                        struct policy_handle *handle)
1049 {
1050         NTSTATUS status;
1051         struct lsa_Close r;
1052         struct policy_handle handle2;
1053
1054         printf("\ntesting Close\n");
1055
1056         r.in.handle = handle;
1057         r.out.handle = &handle2;
1058
1059         status = dcerpc_lsa_Close(p, mem_ctx, &r);
1060         if (!NT_STATUS_IS_OK(status)) {
1061                 printf("Close failed - %s\n", nt_errstr(status));
1062                 return False;
1063         }
1064
1065         status = dcerpc_lsa_Close(p, mem_ctx, &r);
1066         /* its really a fault - we need a status code for rpc fault */
1067         if (!NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
1068                 printf("Close failed - %s\n", nt_errstr(status));
1069                 return False;
1070         }
1071
1072         printf("\n");
1073
1074         return True;
1075 }
1076
1077 BOOL torture_rpc_lsa(void)
1078 {
1079         NTSTATUS status;
1080         struct dcerpc_pipe *p;
1081         TALLOC_CTX *mem_ctx;
1082         BOOL ret = True;
1083         struct policy_handle handle;
1084
1085         mem_ctx = talloc_init("torture_rpc_lsa");
1086
1087         status = torture_rpc_connection(&p, 
1088                                         DCERPC_LSARPC_NAME, 
1089                                         DCERPC_LSARPC_UUID, 
1090                                         DCERPC_LSARPC_VERSION);
1091         if (!NT_STATUS_IS_OK(status)) {
1092                 return False;
1093         }
1094
1095         if (!test_OpenPolicy(p, mem_ctx)) {
1096                 ret = False;
1097         }
1098
1099         if (!test_OpenPolicy2(p, mem_ctx, &handle)) {
1100                 ret = False;
1101         }
1102
1103         if (!test_many_LookupSids(p, mem_ctx, &handle)) {
1104                 ret = False;
1105         }
1106
1107         if (!test_CreateAccount(p, mem_ctx, &handle)) {
1108                 ret = False;
1109         }
1110
1111         if (!test_CreateSecret(p, mem_ctx, &handle)) {
1112                 ret = False;
1113         }
1114
1115         if (!test_CreateTrustedDomain(p, mem_ctx, &handle)) {
1116                 ret = False;
1117         }
1118
1119         if (!test_EnumAccounts(p, mem_ctx, &handle)) {
1120                 ret = False;
1121         }
1122
1123         if (!test_EnumPrivs(p, mem_ctx, &handle)) {
1124                 ret = False;
1125         }
1126
1127         if (!test_EnumTrustDom(p, mem_ctx, &handle)) {
1128                 ret = False;
1129         }
1130
1131         if (!test_QueryInfoPolicy(p, mem_ctx, &handle)) {
1132                 ret = False;
1133         }
1134
1135         if (!test_QueryInfoPolicy2(p, mem_ctx, &handle)) {
1136                 ret = False;
1137         }
1138         
1139 #if 0
1140         if (!test_Delete(p, mem_ctx, &handle)) {
1141                 ret = False;
1142         }
1143 #endif
1144         
1145         if (!test_Close(p, mem_ctx, &handle)) {
1146                 ret = False;
1147         }
1148
1149         talloc_destroy(mem_ctx);
1150
1151         torture_rpc_close(p);
1152
1153         return ret;
1154 }