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