r4437: added IDL and test code for lsa_LookupSids3() and lsa_LookupNames3().
[samba.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_LookupNames3(struct dcerpc_pipe *p, 
192                               TALLOC_CTX *mem_ctx, 
193                               struct policy_handle *handle,
194                               struct lsa_TransNameArray2 *tnames)
195 {
196         struct lsa_LookupNames3 r;
197         struct lsa_TransSidArray3 sids;
198         struct lsa_String *names;
199         uint32_t count = 0;
200         NTSTATUS status;
201         int i;
202
203         printf("\nTesting LookupNames3 with %d names\n", tnames->count);
204
205         sids.count = 0;
206         sids.sids = NULL;
207
208         names = talloc_array_p(mem_ctx, struct lsa_String, tnames->count);
209         for (i=0;i<tnames->count;i++) {
210                 init_lsa_String(&names[i], tnames->names[i].name.string);
211         }
212
213         r.in.handle = handle;
214         r.in.num_names = tnames->count;
215         r.in.names = names;
216         r.in.sids = &sids;
217         r.in.level = 1;
218         r.in.count = &count;
219         r.in.unknown1 = 0;
220         r.in.unknown2 = 0;
221         r.out.count = &count;
222         r.out.sids = &sids;
223
224         status = dcerpc_lsa_LookupNames3(p, mem_ctx, &r);
225         if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
226                 printf("LookupNames3 failed - %s\n", nt_errstr(status));
227                 return False;
228         }
229
230         printf("\n");
231
232         return True;
233 }
234
235
236 static BOOL test_LookupSids(struct dcerpc_pipe *p, 
237                             TALLOC_CTX *mem_ctx, 
238                             struct policy_handle *handle,
239                             struct lsa_SidArray *sids)
240 {
241         struct lsa_LookupSids r;
242         struct lsa_TransNameArray names;
243         uint32_t count = sids->num_sids;
244         NTSTATUS status;
245
246         printf("\nTesting LookupSids\n");
247
248         names.count = 0;
249         names.names = NULL;
250
251         r.in.handle = handle;
252         r.in.sids = sids;
253         r.in.names = &names;
254         r.in.level = 1;
255         r.in.count = &count;
256         r.out.count = &count;
257         r.out.names = &names;
258
259         status = dcerpc_lsa_LookupSids(p, mem_ctx, &r);
260         if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
261                 printf("LookupSids failed - %s\n", nt_errstr(status));
262                 return False;
263         }
264
265         printf("\n");
266
267         if (!test_LookupNames(p, mem_ctx, handle, &names)) {
268                 return False;
269         }
270
271         return True;
272 }
273
274
275 static BOOL test_LookupSids2(struct dcerpc_pipe *p, 
276                             TALLOC_CTX *mem_ctx, 
277                             struct policy_handle *handle,
278                             struct lsa_SidArray *sids)
279 {
280         struct lsa_LookupSids2 r;
281         struct lsa_TransNameArray2 names;
282         uint32_t count = sids->num_sids;
283         NTSTATUS status;
284
285         printf("\nTesting LookupSids2\n");
286
287         names.count = 0;
288         names.names = NULL;
289
290         r.in.handle = handle;
291         r.in.sids = sids;
292         r.in.names = &names;
293         r.in.level = 1;
294         r.in.count = &count;
295         r.in.unknown1 = 0;
296         r.in.unknown2 = 0;
297         r.out.count = &count;
298         r.out.names = &names;
299
300         status = dcerpc_lsa_LookupSids2(p, mem_ctx, &r);
301         if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
302                 printf("LookupSids2 failed - %s\n", nt_errstr(status));
303                 return False;
304         }
305
306         printf("\n");
307
308         if (!test_LookupNames2(p, mem_ctx, handle, &names)) {
309                 return False;
310         }
311
312         return True;
313 }
314
315 static BOOL test_LookupSids3(struct dcerpc_pipe *p, 
316                             TALLOC_CTX *mem_ctx, 
317                             struct policy_handle *handle,
318                             struct lsa_SidArray *sids)
319 {
320         struct lsa_LookupSids3 r;
321         struct lsa_TransNameArray2 names;
322         uint32_t count = sids->num_sids;
323         NTSTATUS status;
324
325         printf("\nTesting LookupSids3\n");
326
327         names.count = 0;
328         names.names = NULL;
329
330         r.in.sids = sids;
331         r.in.names = &names;
332         r.in.level = 1;
333         r.in.count = &count;
334         r.in.unknown1 = 0;
335         r.in.unknown2 = 0;
336         r.out.count = &count;
337         r.out.names = &names;
338
339         status = dcerpc_lsa_LookupSids3(p, mem_ctx, &r);
340         if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
341                 printf("LookupSids3 failed - %s\n", nt_errstr(status));
342                 return False;
343         }
344
345         printf("\n");
346
347         if (!test_LookupNames3(p, mem_ctx, handle, &names)) {
348                 return False;
349         }
350
351         return True;
352 }
353
354 static BOOL test_many_LookupSids(struct dcerpc_pipe *p, 
355                                  TALLOC_CTX *mem_ctx, 
356                                  struct policy_handle *handle)
357 {
358         struct lsa_LookupSids r;
359         struct lsa_TransNameArray names;
360         uint32_t count;
361         NTSTATUS status;
362         struct lsa_SidArray sids;
363         int i;
364
365         printf("\nTesting LookupSids with lots of SIDs\n");
366
367         names.count = 0;
368         names.names = NULL;
369
370         sids.num_sids = 100;
371
372         sids.sids = talloc_array_p(mem_ctx, struct lsa_SidPtr, sids.num_sids);
373
374         for (i=0; i<sids.num_sids; i++) {
375                 const char *sidstr = "S-1-5-32-545";
376                 sids.sids[i].sid = dom_sid_parse_talloc(mem_ctx, sidstr);
377         }
378
379         count = sids.num_sids;
380
381         r.in.handle = handle;
382         r.in.sids = &sids;
383         r.in.names = &names;
384         r.in.level = 1;
385         r.in.count = &names.count;
386         r.out.count = &count;
387         r.out.names = &names;
388
389         status = dcerpc_lsa_LookupSids(p, mem_ctx, &r);
390         if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
391                 printf("LookupSids failed - %s\n", nt_errstr(status));
392                 return False;
393         }
394
395         printf("\n");
396
397         if (!test_LookupNames(p, mem_ctx, handle, &names)) {
398                 return False;
399         }
400
401         return True;
402 }
403
404 static BOOL test_LookupPrivValue(struct dcerpc_pipe *p, 
405                                  TALLOC_CTX *mem_ctx, 
406                                  struct policy_handle *handle,
407                                  struct lsa_String *name)
408 {
409         NTSTATUS status;
410         struct lsa_LookupPrivValue r;
411         struct lsa_LUID luid;
412
413         r.in.handle = handle;
414         r.in.name = name;
415         r.out.luid = &luid;
416
417         status = dcerpc_lsa_LookupPrivValue(p, mem_ctx, &r);
418         if (!NT_STATUS_IS_OK(status)) {
419                 printf("\nLookupPrivValue failed - %s\n", nt_errstr(status));
420                 return False;
421         }
422
423         return True;
424 }
425
426 static BOOL test_LookupPrivName(struct dcerpc_pipe *p, 
427                                 TALLOC_CTX *mem_ctx, 
428                                 struct policy_handle *handle,
429                                 struct lsa_LUID *luid)
430 {
431         NTSTATUS status;
432         struct lsa_LookupPrivName r;
433
434         r.in.handle = handle;
435         r.in.luid = luid;
436
437         status = dcerpc_lsa_LookupPrivName(p, mem_ctx, &r);
438         if (!NT_STATUS_IS_OK(status)) {
439                 printf("\nLookupPrivName failed - %s\n", nt_errstr(status));
440                 return False;
441         }
442
443         return True;
444 }
445
446 static BOOL test_RemovePrivilegesFromAccount(struct dcerpc_pipe *p, 
447                                              TALLOC_CTX *mem_ctx,                                 
448                                              struct policy_handle *acct_handle,
449                                              struct lsa_LUID *luid)
450 {
451         NTSTATUS status;
452         struct lsa_RemovePrivilegesFromAccount r;
453         struct lsa_PrivilegeSet privs;
454         BOOL ret = True;
455
456         printf("Testing RemovePrivilegesFromAccount\n");
457
458         r.in.handle = acct_handle;
459         r.in.remove_all = 0;
460         r.in.privs = &privs;
461
462         privs.count = 1;
463         privs.unknown = 0;
464         privs.set = talloc_array_p(mem_ctx, struct lsa_LUIDAttribute, 1);
465         privs.set[0].luid = *luid;
466         privs.set[0].attribute = 0;
467
468         status = dcerpc_lsa_RemovePrivilegesFromAccount(p, mem_ctx, &r);
469         if (!NT_STATUS_IS_OK(status)) {
470                 printf("RemovePrivilegesFromAccount failed - %s\n", nt_errstr(status));
471                 return False;
472         }
473
474         return ret;
475 }
476
477 static BOOL test_AddPrivilegesToAccount(struct dcerpc_pipe *p, 
478                                         TALLOC_CTX *mem_ctx,                              
479                                         struct policy_handle *acct_handle,
480                                         struct lsa_LUID *luid)
481 {
482         NTSTATUS status;
483         struct lsa_AddPrivilegesToAccount r;
484         struct lsa_PrivilegeSet privs;
485         BOOL ret = True;
486
487         printf("Testing AddPrivilegesToAccount\n");
488
489         r.in.handle = acct_handle;
490         r.in.privs = &privs;
491
492         privs.count = 1;
493         privs.unknown = 0;
494         privs.set = talloc_array_p(mem_ctx, struct lsa_LUIDAttribute, 1);
495         privs.set[0].luid = *luid;
496         privs.set[0].attribute = 0;
497
498         status = dcerpc_lsa_AddPrivilegesToAccount(p, mem_ctx, &r);
499         if (!NT_STATUS_IS_OK(status)) {
500                 printf("AddPrivilegesToAccount failed - %s\n", nt_errstr(status));
501                 return False;
502         }
503
504         return ret;
505 }
506
507 static BOOL test_EnumPrivsAccount(struct dcerpc_pipe *p, 
508                                   TALLOC_CTX *mem_ctx,                            
509                                   struct policy_handle *handle,
510                                   struct policy_handle *acct_handle)
511 {
512         NTSTATUS status;
513         struct lsa_EnumPrivsAccount r;
514         BOOL ret = True;
515
516         printf("Testing EnumPrivsAccount\n");
517
518         r.in.handle = acct_handle;
519
520         status = dcerpc_lsa_EnumPrivsAccount(p, mem_ctx, &r);
521         if (!NT_STATUS_IS_OK(status)) {
522                 printf("EnumPrivsAccount failed - %s\n", nt_errstr(status));
523                 return False;
524         }
525
526         if (r.out.privs && r.out.privs->count > 0) {
527                 int i;
528                 for (i=0;i<r.out.privs->count;i++) {
529                         test_LookupPrivName(p, mem_ctx, handle, 
530                                             &r.out.privs->set[i].luid);
531                 }
532
533                 ret &= test_RemovePrivilegesFromAccount(p, mem_ctx, acct_handle, 
534                                                         &r.out.privs->set[0].luid);
535                 ret &= test_AddPrivilegesToAccount(p, mem_ctx, acct_handle, 
536                                                    &r.out.privs->set[0].luid);
537         }
538
539         return ret;
540 }
541
542 static BOOL test_Delete(struct dcerpc_pipe *p, 
543                        TALLOC_CTX *mem_ctx, 
544                        struct policy_handle *handle)
545 {
546         NTSTATUS status;
547         struct lsa_Delete r;
548
549         printf("\ntesting Delete\n");
550
551         r.in.handle = handle;
552         status = dcerpc_lsa_Delete(p, mem_ctx, &r);
553         if (!NT_STATUS_IS_OK(status)) {
554                 printf("Delete failed - %s\n", nt_errstr(status));
555                 return False;
556         }
557
558         printf("\n");
559
560         return True;
561 }
562
563
564 static BOOL test_CreateAccount(struct dcerpc_pipe *p, 
565                                TALLOC_CTX *mem_ctx, 
566                                struct policy_handle *handle)
567 {
568         NTSTATUS status;
569         struct lsa_CreateAccount r;
570         struct dom_sid2 *newsid;
571         struct policy_handle acct_handle;
572
573         newsid = dom_sid_parse_talloc(mem_ctx, "S-1-5-12349876-4321-2854");
574
575         printf("Testing CreateAccount\n");
576
577         r.in.handle = handle;
578         r.in.sid = newsid;
579         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
580         r.out.acct_handle = &acct_handle;
581
582         status = dcerpc_lsa_CreateAccount(p, mem_ctx, &r);
583         if (!NT_STATUS_IS_OK(status)) {
584                 printf("CreateAccount failed - %s\n", nt_errstr(status));
585                 return False;
586         }
587
588         if (!test_Delete(p, mem_ctx, &acct_handle)) {
589                 return False;
590         }
591
592         return True;
593 }
594
595
596 static BOOL test_CreateTrustedDomain(struct dcerpc_pipe *p, 
597                                      TALLOC_CTX *mem_ctx, 
598                                      struct policy_handle *handle)
599 {
600         NTSTATUS status;
601         struct lsa_CreateTrustedDomain r;
602         struct lsa_TrustInformation trustinfo;
603         struct dom_sid *domsid;
604         struct policy_handle dom_handle;
605
606         printf("Testing CreateTrustedDomain\n");
607
608         domsid = dom_sid_parse_talloc(mem_ctx, "S-1-5-21-97398-379795-12345");
609
610         trustinfo.sid = domsid;
611         init_lsa_String(&trustinfo.name, "torturedomain");
612
613         r.in.handle = handle;
614         r.in.info = &trustinfo;
615         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
616         r.out.dom_handle = &dom_handle;
617
618         status = dcerpc_lsa_CreateTrustedDomain(p, mem_ctx, &r);
619         if (!NT_STATUS_IS_OK(status)) {
620                 printf("CreateTrustedDomain failed - %s\n", nt_errstr(status));
621                 return False;
622         }
623
624         if (!test_Delete(p, mem_ctx, &dom_handle)) {
625                 return False;
626         }
627
628         return True;
629 }
630
631 static BOOL test_CreateSecret(struct dcerpc_pipe *p, 
632                               TALLOC_CTX *mem_ctx, 
633                               struct policy_handle *handle)
634 {
635         NTSTATUS status;
636         struct lsa_CreateSecret r;
637         struct lsa_OpenSecret r2;
638         struct lsa_SetSecret r3;
639         struct lsa_QuerySecret r4;
640         struct policy_handle sec_handle, sec_handle2;
641         struct lsa_Delete d;
642         struct lsa_DATA_BUF buf1;
643         struct lsa_DATA_BUF_PTR bufp1;
644         DATA_BLOB enc_key;
645         BOOL ret = True;
646         DATA_BLOB session_key;
647         NTTIME old_mtime, new_mtime;
648         DATA_BLOB blob1, blob2;
649         const char *secret1 = "abcdef12345699qwerty";
650         char *secret2;
651         char *secname;
652
653         printf("Testing CreateSecret\n");
654
655         asprintf(&secname, "torturesecret-%u", (uint_t)random());
656
657         init_lsa_String(&r.in.name, secname);
658
659         r.in.handle = handle;
660         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
661         r.out.sec_handle = &sec_handle;
662
663         status = dcerpc_lsa_CreateSecret(p, mem_ctx, &r);
664         if (!NT_STATUS_IS_OK(status)) {
665                 printf("CreateSecret failed - %s\n", nt_errstr(status));
666                 return False;
667         }
668
669         r2.in.handle = handle;
670         r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
671         r2.in.name = r.in.name;
672         r2.out.sec_handle = &sec_handle2;
673
674         printf("Testing OpenSecret\n");
675
676         status = dcerpc_lsa_OpenSecret(p, mem_ctx, &r2);
677         if (!NT_STATUS_IS_OK(status)) {
678                 printf("OpenSecret failed - %s\n", nt_errstr(status));
679                 ret = False;
680         }
681
682         status = dcerpc_fetch_session_key(p, &session_key);
683         if (!NT_STATUS_IS_OK(status)) {
684                 printf("dcerpc_fetch_session_key failed - %s\n", nt_errstr(status));
685                 ret = False;
686         }
687
688         enc_key = sess_encrypt_string(secret1, &session_key);
689
690         r3.in.handle = &sec_handle;
691         r3.in.new_val = &buf1;
692         r3.in.old_val = NULL;
693         r3.in.new_val->data = enc_key.data;
694         r3.in.new_val->length = enc_key.length;
695         r3.in.new_val->size = enc_key.length;
696
697         printf("Testing SetSecret\n");
698
699         status = dcerpc_lsa_SetSecret(p, mem_ctx, &r3);
700         if (!NT_STATUS_IS_OK(status)) {
701                 printf("SetSecret failed - %s\n", nt_errstr(status));
702                 ret = False;
703         }
704
705         data_blob_free(&enc_key);
706
707         ZERO_STRUCT(new_mtime);
708         ZERO_STRUCT(old_mtime);
709
710         /* fetch the secret back again */
711         r4.in.handle = &sec_handle;
712         r4.in.new_val = &bufp1;
713         r4.in.new_mtime = &new_mtime;
714         r4.in.old_val = NULL;
715         r4.in.old_mtime = NULL;
716
717         bufp1.buf = NULL;
718
719         status = dcerpc_lsa_QuerySecret(p, mem_ctx, &r4);
720         if (!NT_STATUS_IS_OK(status)) {
721                 printf("QuerySecret failed - %s\n", nt_errstr(status));
722                 ret = False;
723         }
724
725         if (r4.out.new_val->buf == NULL) {
726                 printf("No secret buffer returned\n");
727                 ret = False;
728         } else {
729                 blob1.data = r4.out.new_val->buf->data;
730                 blob1.length = r4.out.new_val->buf->length;
731
732                 blob2 = data_blob(NULL, blob1.length);
733
734                 secret2 = sess_decrypt_string(&blob1, &session_key);
735
736                 printf("returned secret '%s'\n", secret2);
737
738                 if (strcmp(secret1, secret2) != 0) {
739                         printf("Returned secret doesn't match\n");
740                         ret = False;
741                 }
742         }
743
744         if (!test_Delete(p, mem_ctx, &sec_handle)) {
745                 ret = False;
746         }
747
748         d.in.handle = &sec_handle2;
749         status = dcerpc_lsa_Delete(p, mem_ctx, &d);
750         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
751                 printf("Second delete expected INVALID_HANDLE - %s\n", nt_errstr(status));
752                 ret = False;
753         }
754
755         return ret;
756 }
757
758
759 static BOOL test_EnumAccountRights(struct dcerpc_pipe *p, 
760                                    TALLOC_CTX *mem_ctx, 
761                                    struct policy_handle *acct_handle,
762                                    struct dom_sid *sid)
763 {
764         NTSTATUS status;
765         struct lsa_EnumAccountRights r;
766         struct lsa_RightSet rights;
767
768         printf("Testing EnumAccountRights\n");
769
770         r.in.handle = acct_handle;
771         r.in.sid = sid;
772         r.out.rights = &rights;
773
774         status = dcerpc_lsa_EnumAccountRights(p, mem_ctx, &r);
775         if (!NT_STATUS_IS_OK(status)) {
776                 printf("EnumAccountRights failed - %s\n", nt_errstr(status));
777                 return False;
778         }
779
780         return True;
781 }
782
783
784 static BOOL test_QuerySecurity(struct dcerpc_pipe *p, 
785                              TALLOC_CTX *mem_ctx, 
786                              struct policy_handle *handle,
787                              struct policy_handle *acct_handle)
788 {
789         NTSTATUS status;
790         struct lsa_QuerySecurity r;
791
792         printf("Testing QuerySecurity\n");
793
794         r.in.handle = acct_handle;
795         r.in.sec_info = 7;
796
797         status = dcerpc_lsa_QuerySecurity(p, mem_ctx, &r);
798         if (!NT_STATUS_IS_OK(status)) {
799                 printf("QuerySecurity failed - %s\n", nt_errstr(status));
800                 return False;
801         }
802
803         return True;
804 }
805
806 static BOOL test_OpenAccount(struct dcerpc_pipe *p, 
807                              TALLOC_CTX *mem_ctx, 
808                              struct policy_handle *handle,
809                              struct dom_sid *sid)
810 {
811         NTSTATUS status;
812         struct lsa_OpenAccount r;
813         struct policy_handle acct_handle;
814
815         printf("Testing OpenAccount\n");
816
817         r.in.handle = handle;
818         r.in.sid = sid;
819         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
820         r.out.acct_handle = &acct_handle;
821
822         status = dcerpc_lsa_OpenAccount(p, mem_ctx, &r);
823         if (!NT_STATUS_IS_OK(status)) {
824                 printf("OpenAccount failed - %s\n", nt_errstr(status));
825                 return False;
826         }
827
828         if (!test_EnumPrivsAccount(p, mem_ctx, handle, &acct_handle)) {
829                 return False;
830         }
831
832         if (!test_QuerySecurity(p, mem_ctx, handle, &acct_handle)) {
833                 return False;
834         }
835
836         return True;
837 }
838
839 static BOOL test_EnumAccounts(struct dcerpc_pipe *p, 
840                           TALLOC_CTX *mem_ctx, 
841                           struct policy_handle *handle)
842 {
843         NTSTATUS status;
844         struct lsa_EnumAccounts r;
845         struct lsa_SidArray sids1, sids2;
846         uint32_t resume_handle = 0;
847         int i;
848
849         printf("\ntesting EnumAccounts\n");
850
851         r.in.handle = handle;
852         r.in.resume_handle = &resume_handle;
853         r.in.num_entries = 100;
854         r.out.resume_handle = &resume_handle;
855         r.out.sids = &sids1;
856
857         resume_handle = 0;
858         while (True) {
859                 status = dcerpc_lsa_EnumAccounts(p, mem_ctx, &r);
860                 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES)) {
861                         break;
862                 }
863                 if (!NT_STATUS_IS_OK(status)) {
864                         printf("EnumAccounts failed - %s\n", nt_errstr(status));
865                         return False;
866                 }
867
868                 if (!test_LookupSids(p, mem_ctx, handle, &sids1)) {
869                         return False;
870                 }
871
872                 if (!test_LookupSids2(p, mem_ctx, handle, &sids1)) {
873                         return False;
874                 }
875
876                 if (!test_LookupSids3(p, mem_ctx, handle, &sids1)) {
877                         return False;
878                 }
879
880                 printf("testing all accounts\n");
881                 for (i=0;i<sids1.num_sids;i++) {
882                         test_OpenAccount(p, mem_ctx, handle, sids1.sids[i].sid);
883                         test_EnumAccountRights(p, mem_ctx, handle, sids1.sids[i].sid);
884                 }
885                 printf("\n");
886         }
887
888         if (sids1.num_sids < 3) {
889                 return True;
890         }
891         
892         printf("trying EnumAccounts partial listing (asking for 1 at 2)\n");
893         resume_handle = 2;
894         r.in.num_entries = 1;
895         r.out.sids = &sids2;
896
897         status = dcerpc_lsa_EnumAccounts(p, mem_ctx, &r);
898         if (!NT_STATUS_IS_OK(status)) {
899                 printf("EnumAccounts failed - %s\n", nt_errstr(status));
900                 return False;
901         }
902
903         if (sids2.num_sids != 1) {
904                 printf("Returned wrong number of entries (%d)\n", sids2.num_sids);
905                 return False;
906         }
907
908         return True;
909 }
910
911 static BOOL test_LookupPrivDisplayName(struct dcerpc_pipe *p,
912                                 TALLOC_CTX *mem_ctx,
913                                 struct policy_handle *handle,
914                                 struct lsa_String *priv_name)
915 {
916         struct lsa_LookupPrivDisplayName r;
917         NTSTATUS status;
918         /* produce a reasonable range of language output without screwing up
919            terminals */
920         uint16 language_id = (random() % 4) + 0x409;
921
922         printf("testing LookupPrivDisplayName(%s)\n", priv_name->string);
923         
924         r.in.handle = handle;
925         r.in.name = priv_name;
926         r.in.language_id = &language_id;
927         r.out.language_id = &language_id;
928         r.in.unknown = 0;
929
930         status = dcerpc_lsa_LookupPrivDisplayName(p, mem_ctx, &r);
931         if (!NT_STATUS_IS_OK(status)) {
932                 printf("LookupPrivDisplayName failed - %s\n", nt_errstr(status));
933                 return False;
934         }
935         printf("%s -> \"%s\"  (language 0x%x/0x%x)\n", 
936                priv_name->string, r.out.disp_name->string, 
937                *r.in.language_id, *r.out.language_id);
938
939         return True;
940 }
941
942 static BOOL test_EnumAccountsWithUserRight(struct dcerpc_pipe *p, 
943                                 TALLOC_CTX *mem_ctx,
944                                 struct policy_handle *handle,
945                                 struct lsa_String *priv_name)
946 {
947         struct lsa_EnumAccountsWithUserRight r;
948         struct lsa_SidArray sids;
949         NTSTATUS status;
950
951         ZERO_STRUCT(sids);
952         
953         printf("testing EnumAccountsWithUserRight(%s)\n", priv_name->string);
954         
955         r.in.handle = handle;
956         r.in.name = priv_name;
957         r.out.sids = &sids;
958
959         status = dcerpc_lsa_EnumAccountsWithUserRight(p, mem_ctx, &r);
960
961         /* NT_STATUS_NO_MORE_ENTRIES means noone has this privilege */
962         if (NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES)) {
963                 return True;
964         }
965
966         if (!NT_STATUS_IS_OK(status)) {
967                 printf("EnumAccountsWithUserRight failed - %s\n", nt_errstr(status));
968                 return False;
969         }
970         
971         return True;
972 }
973
974
975 static BOOL test_EnumPrivs(struct dcerpc_pipe *p, 
976                            TALLOC_CTX *mem_ctx, 
977                            struct policy_handle *handle)
978 {
979         NTSTATUS status;
980         struct lsa_EnumPrivs r;
981         struct lsa_PrivArray privs1;
982         uint32_t resume_handle = 0;
983         int i;
984         BOOL ret = True;
985
986         printf("\ntesting EnumPrivs\n");
987
988         r.in.handle = handle;
989         r.in.resume_handle = &resume_handle;
990         r.in.max_count = 100;
991         r.out.resume_handle = &resume_handle;
992         r.out.privs = &privs1;
993
994         resume_handle = 0;
995         status = dcerpc_lsa_EnumPrivs(p, mem_ctx, &r);
996         if (!NT_STATUS_IS_OK(status)) {
997                 printf("EnumPrivs failed - %s\n", nt_errstr(status));
998                 return False;
999         }
1000
1001         for (i = 0; i< privs1.count; i++) {
1002                 test_LookupPrivDisplayName(p, mem_ctx, handle, &privs1.privs[i].name);
1003                 test_LookupPrivValue(p, mem_ctx, handle, &privs1.privs[i].name);
1004                 if (!test_EnumAccountsWithUserRight(p, mem_ctx, handle, &privs1.privs[i].name)) {
1005                         ret = False;
1006                 }
1007         }
1008
1009         return ret;
1010 }
1011
1012
1013 static BOOL test_EnumTrustDom(struct dcerpc_pipe *p, 
1014                               TALLOC_CTX *mem_ctx, 
1015                               struct policy_handle *handle)
1016 {
1017         struct lsa_EnumTrustDom r;
1018         NTSTATUS status;
1019         uint32_t resume_handle = 0;
1020         struct lsa_DomainList domains;
1021         int i,j;
1022         BOOL ret = True;
1023
1024         printf("\nTesting EnumTrustDom\n");
1025
1026         r.in.handle = handle;
1027         r.in.resume_handle = &resume_handle;
1028         r.in.num_entries = 100;
1029         r.out.domains = &domains;
1030         r.out.resume_handle = &resume_handle;
1031
1032         status = dcerpc_lsa_EnumTrustDom(p, mem_ctx, &r);
1033
1034         /* NO_MORE_ENTRIES is allowed */
1035         if (NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES)) {
1036                 return True;
1037         }
1038
1039         if (!NT_STATUS_IS_OK(status)) {
1040                 printf("EnumTrustDom failed - %s\n", nt_errstr(status));
1041                 return False;
1042         }
1043
1044         printf("\nTesting OpenTrustedDomain, OpenTrustedDomainByName and QueryInfoTrustedDomain\n");
1045
1046         for (i=0; i< domains.count; i++) {
1047                 struct lsa_OpenTrustedDomain trust;
1048                 struct lsa_OpenTrustedDomainByName trust_by_name;
1049                 struct policy_handle trustdom_handle;
1050                 struct policy_handle handle2;
1051                 struct lsa_Close c;
1052                 int levels [] = {1, 3, 6, 8, 12};
1053                 
1054                 trust.in.handle = handle;
1055                 trust.in.sid = domains.domains[i].sid;
1056                 trust.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1057                 trust.out.trustdom_handle = &trustdom_handle;
1058
1059                 status = dcerpc_lsa_OpenTrustedDomain(p, mem_ctx, &trust);
1060
1061                 if (!NT_STATUS_IS_OK(status)) {
1062                         printf("OpenTrustedDomain failed - %s\n", nt_errstr(status));
1063                         return False;
1064                 }
1065
1066                 c.in.handle = &trustdom_handle;
1067                 c.out.handle = &handle2;
1068                 
1069                 for (j=0; j < ARRAY_SIZE(levels); j++) {
1070                         struct lsa_QueryTrustedDomainInfo q;
1071                         union lsa_TrustedDomainInfo info;
1072                         q.in.trustdom_handle = &trustdom_handle;
1073                         q.in.level = levels[j];
1074                         q.out.info = &info;
1075                         status = dcerpc_lsa_QueryTrustedDomainInfo(p, mem_ctx, &q);
1076                         if (!NT_STATUS_IS_OK(status)) {
1077                                 printf("QueryTrustedDomainInfo level %d failed - %s\n", 
1078                                        levels[j], nt_errstr(status));
1079                                 ret = False;
1080                         }
1081                 }
1082                 
1083                 status = dcerpc_lsa_Close(p, mem_ctx, &c);
1084                 if (!NT_STATUS_IS_OK(status)) {
1085                         printf("Close of trusted domain failed - %s\n", nt_errstr(status));
1086                         return False;
1087                 }
1088
1089                 trust_by_name.in.handle = handle;
1090                 trust_by_name.in.name = domains.domains[i].name;
1091                 trust_by_name.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1092                 trust_by_name.out.trustdom_handle = &trustdom_handle;
1093                 
1094                 status = dcerpc_lsa_OpenTrustedDomainByName(p, mem_ctx, &trust_by_name);
1095
1096                 if (!NT_STATUS_IS_OK(status)) {
1097                         printf("OpenTrustedDomainByName failed - %s\n", nt_errstr(status));
1098                         return False;
1099                 }
1100
1101                 for (j=0; j < ARRAY_SIZE(levels); j++) {
1102                         struct lsa_QueryTrustedDomainInfo q;
1103                         union lsa_TrustedDomainInfo info;
1104                         q.in.trustdom_handle = &trustdom_handle;
1105                         q.in.level = levels[j];
1106                         q.out.info = &info;
1107                         status = dcerpc_lsa_QueryTrustedDomainInfo(p, mem_ctx, &q);
1108                         if (!NT_STATUS_IS_OK(status)) {
1109                                 printf("QueryTrustedDomainInfo level %d failed - %s\n", 
1110                                        levels[j], nt_errstr(status));
1111                                 ret = False;
1112                         }
1113                 }
1114                 
1115                 c.in.handle = &trustdom_handle;
1116                 c.out.handle = &handle2;
1117
1118                 status = dcerpc_lsa_Close(p, mem_ctx, &c);
1119                 if (!NT_STATUS_IS_OK(status)) {
1120                         printf("Close of trusted domain failed - %s\n", nt_errstr(status));
1121                         return False;
1122                 }
1123
1124                 for (j=0; j < ARRAY_SIZE(levels); j++) {
1125                         struct lsa_QueryTrustedDomainInfoBySid q;
1126                         union lsa_TrustedDomainInfo info;
1127                         q.in.handle  = handle;
1128                         q.in.dom_sid = domains.domains[i].sid;
1129                         q.in.level   = levels[j];
1130                         q.out.info   = &info;
1131                         status = dcerpc_lsa_QueryTrustedDomainInfoBySid(p, mem_ctx, &q);
1132                         if (!NT_STATUS_IS_OK(status)) {
1133                                 printf("QueryTrustedDomainInfoBySid level %d failed - %s\n", 
1134                                        levels[j], nt_errstr(status));
1135                                 ret = False;
1136                         }
1137                 }
1138                 
1139                 for (j=0; j < ARRAY_SIZE(levels); j++) {
1140                         struct lsa_QueryTrustedDomainInfoByName q;
1141                         union lsa_TrustedDomainInfo info;
1142                         q.in.handle         = handle;
1143                         q.in.trusted_domain = domains.domains[i].name;
1144                         q.in.level          = levels[j];
1145                         q.out.info          = &info;
1146                         status = dcerpc_lsa_QueryTrustedDomainInfoByName(p, mem_ctx, &q);
1147                         if (!NT_STATUS_IS_OK(status)) {
1148                                 printf("QueryTrustedDomainInfoByName level %d failed - %s\n", 
1149                                        levels[j], nt_errstr(status));
1150                                 ret = False;
1151                         }
1152                 }
1153                 
1154                 
1155
1156         }
1157
1158         return ret;
1159 }
1160
1161 static BOOL test_QueryInfoPolicy(struct dcerpc_pipe *p, 
1162                                  TALLOC_CTX *mem_ctx, 
1163                                  struct policy_handle *handle)
1164 {
1165         struct lsa_QueryInfoPolicy r;
1166         NTSTATUS status;
1167         int i;
1168         BOOL ret = True;
1169         printf("\nTesting QueryInfoPolicy\n");
1170
1171         for (i=1;i<13;i++) {
1172                 r.in.handle = handle;
1173                 r.in.level = i;
1174
1175                 printf("\ntrying QueryInfoPolicy level %d\n", i);
1176
1177                 status = dcerpc_lsa_QueryInfoPolicy(p, mem_ctx, &r);
1178
1179                 if ((i == 9 || i == 10 || i == 11) &&
1180                     NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1181                         printf("server failed level %u (OK)\n", i);
1182                         continue;
1183                 }
1184
1185                 if (!NT_STATUS_IS_OK(status)) {
1186                         printf("QueryInfoPolicy failed - %s\n", nt_errstr(status));
1187                         ret = False;
1188                         continue;
1189                 }
1190         }
1191
1192         return ret;
1193 }
1194
1195 static BOOL test_QueryInfoPolicy2(struct dcerpc_pipe *p, 
1196                                   TALLOC_CTX *mem_ctx, 
1197                                   struct policy_handle *handle)
1198 {
1199         struct lsa_QueryInfoPolicy2 r;
1200         NTSTATUS status;
1201         int i;
1202         BOOL ret = True;
1203         printf("\nTesting QueryInfoPolicy2\n");
1204
1205         for (i=1;i<13;i++) {
1206                 r.in.handle = handle;
1207                 r.in.level = i;
1208
1209                 printf("\ntrying QueryInfoPolicy2 level %d\n", i);
1210
1211                 status = dcerpc_lsa_QueryInfoPolicy2(p, mem_ctx, &r);
1212
1213                 if ((i == 9 || i == 10 || i == 11) &&
1214                     NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1215                         printf("server failed level %u (OK)\n", i);
1216                         continue;
1217                 }
1218
1219                 if (!NT_STATUS_IS_OK(status)) {
1220                         printf("QueryInfoPolicy2 failed - %s\n", nt_errstr(status));
1221                         ret = False;
1222                         continue;
1223                 }
1224         }
1225
1226         return ret;
1227 }
1228
1229 static BOOL test_GetUserName(struct dcerpc_pipe *p, 
1230                                   TALLOC_CTX *mem_ctx, 
1231                                   struct policy_handle *handle)
1232 {
1233         struct lsa_GetUserName r;
1234         NTSTATUS status;
1235         BOOL ret = True;
1236         struct lsa_StringPointer authority_name_p;
1237
1238         printf("\nTesting GetUserName\n");
1239
1240         r.in.system_name = "\\";        
1241         r.in.account_name = NULL;       
1242         r.in.authority_name = &authority_name_p;
1243         authority_name_p.string = NULL;
1244
1245         status = dcerpc_lsa_GetUserName(p, mem_ctx, &r);
1246
1247         if (!NT_STATUS_IS_OK(status)) {
1248                 printf("GetUserName failed - %s\n", nt_errstr(status));
1249                 ret = False;
1250         }
1251
1252         return ret;
1253 }
1254
1255 static BOOL test_Close(struct dcerpc_pipe *p, 
1256                        TALLOC_CTX *mem_ctx, 
1257                        struct policy_handle *handle)
1258 {
1259         NTSTATUS status;
1260         struct lsa_Close r;
1261         struct policy_handle handle2;
1262
1263         printf("\ntesting Close\n");
1264
1265         r.in.handle = handle;
1266         r.out.handle = &handle2;
1267
1268         status = dcerpc_lsa_Close(p, mem_ctx, &r);
1269         if (!NT_STATUS_IS_OK(status)) {
1270                 printf("Close failed - %s\n", nt_errstr(status));
1271                 return False;
1272         }
1273
1274         status = dcerpc_lsa_Close(p, mem_ctx, &r);
1275         /* its really a fault - we need a status code for rpc fault */
1276         if (!NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
1277                 printf("Close failed - %s\n", nt_errstr(status));
1278                 return False;
1279         }
1280
1281         printf("\n");
1282
1283         return True;
1284 }
1285
1286 BOOL torture_rpc_lsa(void)
1287 {
1288         NTSTATUS status;
1289         struct dcerpc_pipe *p;
1290         TALLOC_CTX *mem_ctx;
1291         BOOL ret = True;
1292         struct policy_handle handle;
1293
1294         mem_ctx = talloc_init("torture_rpc_lsa");
1295
1296         status = torture_rpc_connection(&p, 
1297                                         DCERPC_LSARPC_NAME, 
1298                                         DCERPC_LSARPC_UUID, 
1299                                         DCERPC_LSARPC_VERSION);
1300         if (!NT_STATUS_IS_OK(status)) {
1301                 return False;
1302         }
1303
1304         if (!test_OpenPolicy(p, mem_ctx)) {
1305                 ret = False;
1306         }
1307
1308         if (!test_OpenPolicy2(p, mem_ctx, &handle)) {
1309                 ret = False;
1310         }
1311
1312         if (!test_many_LookupSids(p, mem_ctx, &handle)) {
1313                 ret = False;
1314         }
1315
1316         if (!test_CreateAccount(p, mem_ctx, &handle)) {
1317                 ret = False;
1318         }
1319
1320         if (!test_CreateSecret(p, mem_ctx, &handle)) {
1321                 ret = False;
1322         }
1323
1324         if (!test_CreateTrustedDomain(p, mem_ctx, &handle)) {
1325                 ret = False;
1326         }
1327
1328         if (!test_EnumAccounts(p, mem_ctx, &handle)) {
1329                 ret = False;
1330         }
1331
1332         if (!test_EnumPrivs(p, mem_ctx, &handle)) {
1333                 ret = False;
1334         }
1335
1336         if (!test_EnumTrustDom(p, mem_ctx, &handle)) {
1337                 ret = False;
1338         }
1339
1340         if (!test_QueryInfoPolicy(p, mem_ctx, &handle)) {
1341                 ret = False;
1342         }
1343
1344         if (!test_QueryInfoPolicy2(p, mem_ctx, &handle)) {
1345                 ret = False;
1346         }
1347
1348         if (!test_GetUserName(p, mem_ctx, &handle)) {
1349                 ret = False;
1350         }
1351
1352 #if 0
1353         if (!test_Delete(p, mem_ctx, &handle)) {
1354                 ret = False;
1355         }
1356 #endif
1357         
1358         if (!test_Close(p, mem_ctx, &handle)) {
1359                 ret = False;
1360         }
1361
1362         talloc_destroy(mem_ctx);
1363
1364         torture_rpc_close(p);
1365
1366         return ret;
1367 }