r13924: Split more prototypes out of include/proto.h + initial work on header
[kamenim/samba.git] / source4 / torture / rpc / lsa.c
1 /* 
2    Unix SMB/CIFS implementation.
3    test suite for lsa rpc operations
4
5    Copyright (C) Andrew Tridgell 2003
6    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2005
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "includes.h"
24 #include "torture/torture.h"
25 #include "librpc/gen_ndr/ndr_lsa.h"
26 #include "lib/events/events.h"
27 #include "libcli/security/proto.h"
28 #include "libcli/auth/proto.h"
29
30 static void init_lsa_String(struct lsa_String *name, const char *s)
31 {
32         name->string = s;
33 }
34
35 static BOOL test_OpenPolicy(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
36 {
37         struct lsa_ObjectAttribute attr;
38         struct policy_handle handle;
39         struct lsa_QosInfo qos;
40         struct lsa_OpenPolicy r;
41         NTSTATUS status;
42         uint16_t system_name = '\\';
43
44         printf("\ntesting OpenPolicy\n");
45
46         qos.len = 0;
47         qos.impersonation_level = 2;
48         qos.context_mode = 1;
49         qos.effective_only = 0;
50
51         attr.len = 0;
52         attr.root_dir = NULL;
53         attr.object_name = NULL;
54         attr.attributes = 0;
55         attr.sec_desc = NULL;
56         attr.sec_qos = &qos;
57
58         r.in.system_name = &system_name;
59         r.in.attr = &attr;
60         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
61         r.out.handle = &handle;
62
63         status = dcerpc_lsa_OpenPolicy(p, mem_ctx, &r);
64         if (!NT_STATUS_IS_OK(status)) {
65                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) ||
66                     NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
67                         printf("not considering %s to be an error\n", nt_errstr(status));
68                         return True;
69                 }
70                 printf("OpenPolicy failed - %s\n", nt_errstr(status));
71                 return False;
72         }
73
74         return True;
75 }
76
77
78 BOOL test_lsa_OpenPolicy2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
79                           struct policy_handle **handle)
80 {
81         struct lsa_ObjectAttribute attr;
82         struct lsa_QosInfo qos;
83         struct lsa_OpenPolicy2 r;
84         NTSTATUS status;
85
86         printf("\ntesting OpenPolicy2\n");
87
88         *handle = talloc(mem_ctx, struct policy_handle);
89         if (!*handle) {
90                 return False;
91         }
92
93         qos.len = 0;
94         qos.impersonation_level = 2;
95         qos.context_mode = 1;
96         qos.effective_only = 0;
97
98         attr.len = 0;
99         attr.root_dir = NULL;
100         attr.object_name = NULL;
101         attr.attributes = 0;
102         attr.sec_desc = NULL;
103         attr.sec_qos = &qos;
104
105         r.in.system_name = "\\";
106         r.in.attr = &attr;
107         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
108         r.out.handle = *handle;
109
110         status = dcerpc_lsa_OpenPolicy2(p, mem_ctx, &r);
111         if (!NT_STATUS_IS_OK(status)) {
112                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) ||
113                     NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
114                         printf("not considering %s to be an error\n", nt_errstr(status));
115                         talloc_free(*handle);
116                         *handle = NULL;
117                         return True;
118                 }
119                 printf("OpenPolicy2 failed - %s\n", nt_errstr(status));
120                 return False;
121         }
122
123         return True;
124 }
125
126 static BOOL test_LookupNames(struct dcerpc_pipe *p, 
127                             TALLOC_CTX *mem_ctx, 
128                             struct policy_handle *handle,
129                             struct lsa_TransNameArray *tnames)
130 {
131         struct lsa_LookupNames r;
132         struct lsa_TransSidArray sids;
133         struct lsa_String *names;
134         uint32_t count = 0;
135         NTSTATUS status;
136         int i;
137
138         printf("\nTesting LookupNames with %d names\n", tnames->count);
139
140         sids.count = 0;
141         sids.sids = NULL;
142
143         names = talloc_array(mem_ctx, struct lsa_String, tnames->count);
144         for (i=0;i<tnames->count;i++) {
145                 init_lsa_String(&names[i], tnames->names[i].name.string);
146         }
147
148         r.in.handle = handle;
149         r.in.num_names = tnames->count;
150         r.in.names = names;
151         r.in.sids = &sids;
152         r.in.level = 1;
153         r.in.count = &count;
154         r.out.count = &count;
155         r.out.sids = &sids;
156
157         status = dcerpc_lsa_LookupNames(p, mem_ctx, &r);
158         if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
159                 printf("LookupNames failed - %s\n", nt_errstr(status));
160                 return False;
161         }
162
163         printf("\n");
164
165         return True;
166 }
167
168 static BOOL test_LookupNames2(struct dcerpc_pipe *p, 
169                               TALLOC_CTX *mem_ctx, 
170                               struct policy_handle *handle,
171                               struct lsa_TransNameArray2 *tnames)
172 {
173         struct lsa_LookupNames2 r;
174         struct lsa_TransSidArray2 sids;
175         struct lsa_String *names;
176         uint32_t count = 0;
177         NTSTATUS status;
178         int i;
179
180         printf("\nTesting LookupNames2 with %d names\n", tnames->count);
181
182         sids.count = 0;
183         sids.sids = NULL;
184
185         names = talloc_array(mem_ctx, struct lsa_String, tnames->count);
186         for (i=0;i<tnames->count;i++) {
187                 init_lsa_String(&names[i], tnames->names[i].name.string);
188         }
189
190         r.in.handle = handle;
191         r.in.num_names = tnames->count;
192         r.in.names = names;
193         r.in.sids = &sids;
194         r.in.level = 1;
195         r.in.count = &count;
196         r.in.unknown1 = 0;
197         r.in.unknown2 = 0;
198         r.out.count = &count;
199         r.out.sids = &sids;
200
201         status = dcerpc_lsa_LookupNames2(p, mem_ctx, &r);
202         if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
203                 printf("LookupNames2 failed - %s\n", nt_errstr(status));
204                 return False;
205         }
206
207         printf("\n");
208
209         return True;
210 }
211
212
213 static BOOL test_LookupNames3(struct dcerpc_pipe *p, 
214                               TALLOC_CTX *mem_ctx, 
215                               struct policy_handle *handle,
216                               struct lsa_TransNameArray2 *tnames)
217 {
218         struct lsa_LookupNames3 r;
219         struct lsa_TransSidArray3 sids;
220         struct lsa_String *names;
221         uint32_t count = 0;
222         NTSTATUS status;
223         int i;
224
225         printf("\nTesting LookupNames3 with %d names\n", tnames->count);
226
227         sids.count = 0;
228         sids.sids = NULL;
229
230         names = talloc_array(mem_ctx, struct lsa_String, tnames->count);
231         for (i=0;i<tnames->count;i++) {
232                 init_lsa_String(&names[i], tnames->names[i].name.string);
233         }
234
235         r.in.handle = handle;
236         r.in.num_names = tnames->count;
237         r.in.names = names;
238         r.in.sids = &sids;
239         r.in.level = 1;
240         r.in.count = &count;
241         r.in.unknown1 = 0;
242         r.in.unknown2 = 0;
243         r.out.count = &count;
244         r.out.sids = &sids;
245
246         status = dcerpc_lsa_LookupNames3(p, mem_ctx, &r);
247         if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
248                 printf("LookupNames3 failed - %s\n", nt_errstr(status));
249                 return False;
250         }
251
252         printf("\n");
253
254         return True;
255 }
256
257 static BOOL test_LookupNames4(struct dcerpc_pipe *p, 
258                               TALLOC_CTX *mem_ctx, 
259                               struct lsa_TransNameArray2 *tnames)
260 {
261         struct lsa_LookupNames4 r;
262         struct lsa_TransSidArray3 sids;
263         struct lsa_String *names;
264         uint32_t count = 0;
265         NTSTATUS status;
266         int i;
267
268         printf("\nTesting LookupNames4 with %d names\n", tnames->count);
269
270         sids.count = 0;
271         sids.sids = NULL;
272
273         names = talloc_array(mem_ctx, struct lsa_String, tnames->count);
274         for (i=0;i<tnames->count;i++) {
275                 init_lsa_String(&names[i], tnames->names[i].name.string);
276         }
277
278         r.in.num_names = tnames->count;
279         r.in.names = names;
280         r.in.sids = &sids;
281         r.in.level = 1;
282         r.in.count = &count;
283         r.in.unknown1 = 0;
284         r.in.unknown2 = 0;
285         r.out.count = &count;
286         r.out.sids = &sids;
287
288         status = dcerpc_lsa_LookupNames4(p, mem_ctx, &r);
289         if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
290                 printf("LookupNames4 failed - %s\n", nt_errstr(status));
291                 return False;
292         }
293
294         printf("\n");
295
296         return True;
297 }
298
299
300 static BOOL test_LookupSids(struct dcerpc_pipe *p, 
301                             TALLOC_CTX *mem_ctx, 
302                             struct policy_handle *handle,
303                             struct lsa_SidArray *sids)
304 {
305         struct lsa_LookupSids r;
306         struct lsa_TransNameArray names;
307         uint32_t count = sids->num_sids;
308         NTSTATUS status;
309
310         printf("\nTesting LookupSids\n");
311
312         names.count = 0;
313         names.names = NULL;
314
315         r.in.handle = handle;
316         r.in.sids = sids;
317         r.in.names = &names;
318         r.in.level = 1;
319         r.in.count = &count;
320         r.out.count = &count;
321         r.out.names = &names;
322
323         status = dcerpc_lsa_LookupSids(p, mem_ctx, &r);
324         if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
325                 printf("LookupSids failed - %s\n", nt_errstr(status));
326                 return False;
327         }
328
329         printf("\n");
330
331         if (!test_LookupNames(p, mem_ctx, handle, &names)) {
332                 return False;
333         }
334
335         return True;
336 }
337
338
339 static BOOL test_LookupSids2(struct dcerpc_pipe *p, 
340                             TALLOC_CTX *mem_ctx, 
341                             struct policy_handle *handle,
342                             struct lsa_SidArray *sids)
343 {
344         struct lsa_LookupSids2 r;
345         struct lsa_TransNameArray2 names;
346         uint32_t count = sids->num_sids;
347         NTSTATUS status;
348
349         printf("\nTesting LookupSids2\n");
350
351         names.count = 0;
352         names.names = NULL;
353
354         r.in.handle = handle;
355         r.in.sids = sids;
356         r.in.names = &names;
357         r.in.level = 1;
358         r.in.count = &count;
359         r.in.unknown1 = 0;
360         r.in.unknown2 = 0;
361         r.out.count = &count;
362         r.out.names = &names;
363
364         status = dcerpc_lsa_LookupSids2(p, mem_ctx, &r);
365         if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
366                 printf("LookupSids2 failed - %s\n", nt_errstr(status));
367                 return False;
368         }
369
370         printf("\n");
371
372         if (!test_LookupNames2(p, mem_ctx, handle, &names)) {
373                 return False;
374         }
375
376         if (!test_LookupNames3(p, mem_ctx, handle, &names)) {
377                 return False;
378         }
379
380         return True;
381 }
382
383 static BOOL test_LookupSids3(struct dcerpc_pipe *p, 
384                             TALLOC_CTX *mem_ctx, 
385                             struct lsa_SidArray *sids)
386 {
387         struct lsa_LookupSids3 r;
388         struct lsa_TransNameArray2 names;
389         uint32_t count = sids->num_sids;
390         NTSTATUS status;
391
392         printf("\nTesting LookupSids3\n");
393
394         names.count = 0;
395         names.names = NULL;
396
397         r.in.sids = sids;
398         r.in.names = &names;
399         r.in.level = 1;
400         r.in.count = &count;
401         r.in.unknown1 = 0;
402         r.in.unknown2 = 0;
403         r.out.count = &count;
404         r.out.names = &names;
405
406         status = dcerpc_lsa_LookupSids3(p, mem_ctx, &r);
407         if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
408                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) ||
409                     NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
410                         printf("not considering %s to be an error\n", nt_errstr(status));
411                         return True;
412                 }
413                 printf("LookupSids3 failed - %s - not considered an error\n", 
414                        nt_errstr(status));
415                 return False;
416         }
417
418         printf("\n");
419
420         if (!test_LookupNames4(p, mem_ctx, &names)) {
421                 return False;
422         }
423
424         return True;
425 }
426
427 BOOL test_many_LookupSids(struct dcerpc_pipe *p, 
428                           TALLOC_CTX *mem_ctx, 
429                           struct policy_handle *handle)
430 {
431         uint32_t count;
432         NTSTATUS status;
433         struct lsa_SidArray sids;
434         int i;
435
436         printf("\nTesting LookupSids with lots of SIDs\n");
437
438         sids.num_sids = 100;
439
440         sids.sids = talloc_array(mem_ctx, struct lsa_SidPtr, sids.num_sids);
441
442         for (i=0; i<sids.num_sids; i++) {
443                 const char *sidstr = "S-1-5-32-545";
444                 sids.sids[i].sid = dom_sid_parse_talloc(mem_ctx, sidstr);
445         }
446
447         count = sids.num_sids;
448
449         if (handle) {
450                 struct lsa_LookupSids r;
451                 struct lsa_TransNameArray names;
452                 names.count = 0;
453                 names.names = NULL;
454
455                 r.in.handle = handle;
456                 r.in.sids = &sids;
457                 r.in.names = &names;
458                 r.in.level = 1;
459                 r.in.count = &names.count;
460                 r.out.count = &count;
461                 r.out.names = &names;
462                 
463                 status = dcerpc_lsa_LookupSids(p, mem_ctx, &r);
464                 if (!NT_STATUS_IS_OK(status) &&
465                     !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
466                         printf("LookupSids failed - %s\n", nt_errstr(status));
467                         return False;
468                 }
469                 
470                 printf("\n");
471                 
472                 if (!test_LookupNames(p, mem_ctx, handle, &names)) {
473                         return False;
474                 }
475         } else {
476                 struct lsa_LookupSids3 r;
477                 struct lsa_TransNameArray2 names;
478
479                 names.count = 0;
480                 names.names = NULL;
481
482                 printf("\nTesting LookupSids3\n");
483                 
484                 r.in.sids = &sids;
485                 r.in.names = &names;
486                 r.in.level = 1;
487                 r.in.count = &count;
488                 r.in.unknown1 = 0;
489                 r.in.unknown2 = 0;
490                 r.out.count = &count;
491                 r.out.names = &names;
492                 
493                 status = dcerpc_lsa_LookupSids3(p, mem_ctx, &r);
494                 if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
495                         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) ||
496                             NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
497                                 printf("not considering %s to be an error\n", nt_errstr(status));
498                                 return True;
499                         }
500                         printf("LookupSids3 failed - %s\n", 
501                                nt_errstr(status));
502                         return False;
503                 }
504                 if (!test_LookupNames4(p, mem_ctx, &names)) {
505                         return False;
506                 }
507         }
508
509         printf("\n");
510
511
512
513         return True;
514 }
515
516 #define NUM_ASYNC_REQUESTS 1000
517
518 static void lookupsids_cb(struct rpc_request *req)
519 {
520         int *replies = (int *)req->async.private;
521         NTSTATUS status;
522
523         status = dcerpc_ndr_request_recv(req);
524         DEBUG(3, ("lookupsids returned %s\n", nt_errstr(status)));
525         if (!NT_STATUS_IS_OK(status)) {
526                 *replies = -1;
527         }
528
529         *replies += 1;
530 }
531
532 static BOOL test_LookupSids_async(struct dcerpc_pipe *p, 
533                                   TALLOC_CTX *mem_ctx, 
534                                   struct policy_handle *handle)
535 {
536         struct lsa_SidArray sids;
537         struct lsa_SidPtr sidptr;
538
539         uint32_t count[NUM_ASYNC_REQUESTS];
540         struct lsa_TransNameArray names[NUM_ASYNC_REQUESTS];
541         struct lsa_LookupSids r[NUM_ASYNC_REQUESTS];
542         struct rpc_request **req;
543
544         int i, replies;
545         BOOL ret = True;
546
547         printf("\nTesting %d async lookupsids request\n", 100);
548
549         req = talloc_array(mem_ctx, struct rpc_request *, NUM_ASYNC_REQUESTS);
550
551         sids.num_sids = 1;
552         sids.sids = &sidptr;
553         sidptr.sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-545");
554
555         replies = 0;
556
557         for (i=0; i<NUM_ASYNC_REQUESTS; i++) {
558                 count[i] = 0;
559                 names[i].count = 0;
560                 names[i].names = NULL;
561
562                 r[i].in.handle = handle;
563                 r[i].in.sids = &sids;
564                 r[i].in.names = &names[i];
565                 r[i].in.level = 1;
566                 r[i].in.count = &names[i].count;
567                 r[i].out.count = &count[i];
568                 r[i].out.names = &names[i];
569                 
570                 req[i] = dcerpc_lsa_LookupSids_send(p, req, &r[i]);
571                 if (req[i] == NULL) {
572                         ret = False;
573                         break;
574                 }
575
576                 req[i]->async.callback = lookupsids_cb;
577                 req[i]->async.private = &replies;
578         }
579
580         while (replies < NUM_ASYNC_REQUESTS) {
581                 event_loop_once(p->conn->event_ctx);
582                 if (replies < 0) {
583                         ret = False;
584                         break;
585                 }
586         }
587
588         talloc_free(req);
589
590         return ret;
591 }
592
593 static BOOL test_LookupPrivValue(struct dcerpc_pipe *p, 
594                                  TALLOC_CTX *mem_ctx, 
595                                  struct policy_handle *handle,
596                                  struct lsa_String *name)
597 {
598         NTSTATUS status;
599         struct lsa_LookupPrivValue r;
600         struct lsa_LUID luid;
601
602         r.in.handle = handle;
603         r.in.name = name;
604         r.out.luid = &luid;
605
606         status = dcerpc_lsa_LookupPrivValue(p, mem_ctx, &r);
607         if (!NT_STATUS_IS_OK(status)) {
608                 printf("\nLookupPrivValue failed - %s\n", nt_errstr(status));
609                 return False;
610         }
611
612         return True;
613 }
614
615 static BOOL test_LookupPrivName(struct dcerpc_pipe *p, 
616                                 TALLOC_CTX *mem_ctx, 
617                                 struct policy_handle *handle,
618                                 struct lsa_LUID *luid)
619 {
620         NTSTATUS status;
621         struct lsa_LookupPrivName r;
622
623         r.in.handle = handle;
624         r.in.luid = luid;
625
626         status = dcerpc_lsa_LookupPrivName(p, mem_ctx, &r);
627         if (!NT_STATUS_IS_OK(status)) {
628                 printf("\nLookupPrivName failed - %s\n", nt_errstr(status));
629                 return False;
630         }
631
632         return True;
633 }
634
635 static BOOL test_RemovePrivilegesFromAccount(struct dcerpc_pipe *p, 
636                                              TALLOC_CTX *mem_ctx,                                 
637                                              struct policy_handle *acct_handle,
638                                              struct lsa_LUID *luid)
639 {
640         NTSTATUS status;
641         struct lsa_RemovePrivilegesFromAccount r;
642         struct lsa_PrivilegeSet privs;
643         BOOL ret = True;
644
645         printf("Testing RemovePrivilegesFromAccount\n");
646
647         r.in.handle = acct_handle;
648         r.in.remove_all = 0;
649         r.in.privs = &privs;
650
651         privs.count = 1;
652         privs.unknown = 0;
653         privs.set = talloc_array(mem_ctx, struct lsa_LUIDAttribute, 1);
654         privs.set[0].luid = *luid;
655         privs.set[0].attribute = 0;
656
657         status = dcerpc_lsa_RemovePrivilegesFromAccount(p, mem_ctx, &r);
658         if (!NT_STATUS_IS_OK(status)) {
659                 printf("RemovePrivilegesFromAccount failed - %s\n", nt_errstr(status));
660                 return False;
661         }
662
663         return ret;
664 }
665
666 static BOOL test_AddPrivilegesToAccount(struct dcerpc_pipe *p, 
667                                         TALLOC_CTX *mem_ctx,                              
668                                         struct policy_handle *acct_handle,
669                                         struct lsa_LUID *luid)
670 {
671         NTSTATUS status;
672         struct lsa_AddPrivilegesToAccount r;
673         struct lsa_PrivilegeSet privs;
674         BOOL ret = True;
675
676         printf("Testing AddPrivilegesToAccount\n");
677
678         r.in.handle = acct_handle;
679         r.in.privs = &privs;
680
681         privs.count = 1;
682         privs.unknown = 0;
683         privs.set = talloc_array(mem_ctx, struct lsa_LUIDAttribute, 1);
684         privs.set[0].luid = *luid;
685         privs.set[0].attribute = 0;
686
687         status = dcerpc_lsa_AddPrivilegesToAccount(p, mem_ctx, &r);
688         if (!NT_STATUS_IS_OK(status)) {
689                 printf("AddPrivilegesToAccount failed - %s\n", nt_errstr(status));
690                 return False;
691         }
692
693         return ret;
694 }
695
696 static BOOL test_EnumPrivsAccount(struct dcerpc_pipe *p, 
697                                   TALLOC_CTX *mem_ctx,                            
698                                   struct policy_handle *handle,
699                                   struct policy_handle *acct_handle)
700 {
701         NTSTATUS status;
702         struct lsa_EnumPrivsAccount r;
703         BOOL ret = True;
704
705         printf("Testing EnumPrivsAccount\n");
706
707         r.in.handle = acct_handle;
708
709         status = dcerpc_lsa_EnumPrivsAccount(p, mem_ctx, &r);
710         if (!NT_STATUS_IS_OK(status)) {
711                 printf("EnumPrivsAccount failed - %s\n", nt_errstr(status));
712                 return False;
713         }
714
715         if (r.out.privs && r.out.privs->count > 0) {
716                 int i;
717                 for (i=0;i<r.out.privs->count;i++) {
718                         test_LookupPrivName(p, mem_ctx, handle, 
719                                             &r.out.privs->set[i].luid);
720                 }
721
722                 ret &= test_RemovePrivilegesFromAccount(p, mem_ctx, acct_handle, 
723                                                         &r.out.privs->set[0].luid);
724                 ret &= test_AddPrivilegesToAccount(p, mem_ctx, acct_handle, 
725                                                    &r.out.privs->set[0].luid);
726         }
727
728         return ret;
729 }
730
731 static BOOL test_Delete(struct dcerpc_pipe *p, 
732                        TALLOC_CTX *mem_ctx, 
733                        struct policy_handle *handle)
734 {
735         NTSTATUS status;
736         struct lsa_Delete r;
737
738         printf("testing Delete\n");
739
740         r.in.handle = handle;
741         status = dcerpc_lsa_Delete(p, mem_ctx, &r);
742         if (!NT_STATUS_IS_OK(status)) {
743                 printf("Delete failed - %s\n", nt_errstr(status));
744                 return False;
745         }
746
747         return True;
748 }
749
750
751 static BOOL test_CreateAccount(struct dcerpc_pipe *p, 
752                                TALLOC_CTX *mem_ctx, 
753                                struct policy_handle *handle)
754 {
755         NTSTATUS status;
756         struct lsa_CreateAccount r;
757         struct dom_sid2 *newsid;
758         struct policy_handle acct_handle;
759
760         newsid = dom_sid_parse_talloc(mem_ctx, "S-1-5-12349876-4321-2854");
761
762         printf("Testing CreateAccount\n");
763
764         r.in.handle = handle;
765         r.in.sid = newsid;
766         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
767         r.out.acct_handle = &acct_handle;
768
769         status = dcerpc_lsa_CreateAccount(p, mem_ctx, &r);
770         if (!NT_STATUS_IS_OK(status)) {
771                 printf("CreateAccount failed - %s\n", nt_errstr(status));
772                 return False;
773         }
774
775         if (!test_Delete(p, mem_ctx, &acct_handle)) {
776                 return False;
777         }
778
779         return True;
780 }
781
782 static BOOL test_DeleteTrustedDomain(struct dcerpc_pipe *p, 
783                                      TALLOC_CTX *mem_ctx, 
784                                      struct policy_handle *handle,
785                                      struct lsa_StringLarge name)
786 {
787         NTSTATUS status;
788         struct lsa_OpenTrustedDomainByName r;
789         struct policy_handle trustdom_handle;
790
791         r.in.handle = handle;
792         r.in.name.string = name.string;
793         r.in.access_mask = SEC_STD_DELETE;
794         r.out.trustdom_handle = &trustdom_handle;
795
796         status = dcerpc_lsa_OpenTrustedDomainByName(p, mem_ctx, &r);
797         if (!NT_STATUS_IS_OK(status)) {
798                 printf("lsa_OpenTrustedDomainByName failed - %s\n", nt_errstr(status));
799                 return False;
800         }
801
802         if (!test_Delete(p, mem_ctx, &trustdom_handle)) {
803                 return False;
804         }
805
806         return True;
807 }
808
809
810 static BOOL test_CreateSecret(struct dcerpc_pipe *p, 
811                               TALLOC_CTX *mem_ctx, 
812                               struct policy_handle *handle)
813 {
814         NTSTATUS status;
815         struct lsa_CreateSecret r;
816         struct lsa_OpenSecret r2;
817         struct lsa_SetSecret r3;
818         struct lsa_QuerySecret r4;
819         struct lsa_SetSecret r5;
820         struct lsa_QuerySecret r6;
821         struct lsa_SetSecret r7;
822         struct lsa_QuerySecret r8;
823         struct policy_handle sec_handle, sec_handle2, sec_handle3;
824         struct lsa_Delete d;
825         struct lsa_DATA_BUF buf1;
826         struct lsa_DATA_BUF_PTR bufp1;
827         struct lsa_DATA_BUF_PTR bufp2;
828         DATA_BLOB enc_key;
829         BOOL ret = True;
830         DATA_BLOB session_key;
831         NTTIME old_mtime, new_mtime;
832         DATA_BLOB blob1, blob2;
833         const char *secret1 = "abcdef12345699qwerty";
834         char *secret2;
835         const char *secret3 = "ABCDEF12345699QWERTY";
836         char *secret4;
837         const char *secret5 = "NEW-SAMBA4-SECRET";
838         char *secret6;
839         char *secname[2];
840         int i;
841         const int LOCAL = 0;
842         const int GLOBAL = 1;
843
844         secname[LOCAL] = talloc_asprintf(mem_ctx, "torturesecret-%u", (uint_t)random());
845         secname[GLOBAL] = talloc_asprintf(mem_ctx, "G$torturesecret-%u", (uint_t)random());
846
847         for (i=0; i< 2; i++) {
848                 printf("Testing CreateSecret of %s\n", secname[i]);
849                 
850                 init_lsa_String(&r.in.name, secname[i]);
851                 
852                 r.in.handle = handle;
853                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
854                 r.out.sec_handle = &sec_handle;
855                 
856                 status = dcerpc_lsa_CreateSecret(p, mem_ctx, &r);
857                 if (!NT_STATUS_IS_OK(status)) {
858                         printf("CreateSecret failed - %s\n", nt_errstr(status));
859                         return False;
860                 }
861                 
862                 r.in.handle = handle;
863                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
864                 r.out.sec_handle = &sec_handle3;
865                 
866                 status = dcerpc_lsa_CreateSecret(p, mem_ctx, &r);
867                 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
868                         printf("CreateSecret should have failed OBJECT_NAME_COLLISION - %s\n", nt_errstr(status));
869                         return False;
870                 }
871                 
872                 r2.in.handle = handle;
873                 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
874                 r2.in.name = r.in.name;
875                 r2.out.sec_handle = &sec_handle2;
876                 
877                 printf("Testing OpenSecret\n");
878                 
879                 status = dcerpc_lsa_OpenSecret(p, mem_ctx, &r2);
880                 if (!NT_STATUS_IS_OK(status)) {
881                         printf("OpenSecret failed - %s\n", nt_errstr(status));
882                         return False;
883                 }
884                 
885                 status = dcerpc_fetch_session_key(p, &session_key);
886                 if (!NT_STATUS_IS_OK(status)) {
887                         printf("dcerpc_fetch_session_key failed - %s\n", nt_errstr(status));
888                         return False;
889                 }
890                 
891                 enc_key = sess_encrypt_string(secret1, &session_key);
892                 
893                 r3.in.sec_handle = &sec_handle;
894                 r3.in.new_val = &buf1;
895                 r3.in.old_val = NULL;
896                 r3.in.new_val->data = enc_key.data;
897                 r3.in.new_val->length = enc_key.length;
898                 r3.in.new_val->size = enc_key.length;
899                 
900                 printf("Testing SetSecret\n");
901                 
902                 status = dcerpc_lsa_SetSecret(p, mem_ctx, &r3);
903                 if (!NT_STATUS_IS_OK(status)) {
904                         printf("SetSecret failed - %s\n", nt_errstr(status));
905                         return False;
906                 }
907                 
908                 r3.in.sec_handle = &sec_handle;
909                 r3.in.new_val = &buf1;
910                 r3.in.old_val = NULL;
911                 r3.in.new_val->data = enc_key.data;
912                 r3.in.new_val->length = enc_key.length;
913                 r3.in.new_val->size = enc_key.length;
914                 
915                 /* break the encrypted data */
916                 enc_key.data[0]++;
917
918                 printf("Testing SetSecret with broken key\n");
919                 
920                 status = dcerpc_lsa_SetSecret(p, mem_ctx, &r3);
921                 if (!NT_STATUS_EQUAL(status, NT_STATUS_UNKNOWN_REVISION)) {
922                         printf("SetSecret should have failed UNKNOWN_REVISION - %s\n", nt_errstr(status));
923                         ret = False;
924                 }
925                 
926                 data_blob_free(&enc_key);
927                 
928                 ZERO_STRUCT(new_mtime);
929                 ZERO_STRUCT(old_mtime);
930                 
931                 /* fetch the secret back again */
932                 r4.in.sec_handle = &sec_handle;
933                 r4.in.new_val = &bufp1;
934                 r4.in.new_mtime = &new_mtime;
935                 r4.in.old_val = NULL;
936                 r4.in.old_mtime = NULL;
937                 
938                 bufp1.buf = NULL;
939                 
940                 printf("Testing QuerySecret\n");
941                 status = dcerpc_lsa_QuerySecret(p, mem_ctx, &r4);
942                 if (!NT_STATUS_IS_OK(status)) {
943                         printf("QuerySecret failed - %s\n", nt_errstr(status));
944                         ret = False;
945                 } else {
946                         if (r4.out.new_val == NULL || r4.out.new_val->buf == NULL) {
947                                 printf("No secret buffer returned\n");
948                                 ret = False;
949                         } else {
950                                 blob1.data = r4.out.new_val->buf->data;
951                                 blob1.length = r4.out.new_val->buf->size;
952                                 
953                                 blob2 = data_blob_talloc(mem_ctx, NULL, blob1.length);
954                                 
955                                 secret2 = sess_decrypt_string(&blob1, &session_key);
956                                 
957                                 if (strcmp(secret1, secret2) != 0) {
958                                         printf("Returned secret '%s' doesn't match '%s'\n", 
959                                                secret2, secret1);
960                                         ret = False;
961                                 }
962                         }
963                 }
964                 
965                 enc_key = sess_encrypt_string(secret3, &session_key);
966                 
967                 r5.in.sec_handle = &sec_handle;
968                 r5.in.new_val = &buf1;
969                 r5.in.old_val = NULL;
970                 r5.in.new_val->data = enc_key.data;
971                 r5.in.new_val->length = enc_key.length;
972                 r5.in.new_val->size = enc_key.length;
973                 
974                 printf("Testing SetSecret (existing value should move to old)\n");
975                 
976                 status = dcerpc_lsa_SetSecret(p, mem_ctx, &r5);
977                 if (!NT_STATUS_IS_OK(status)) {
978                         printf("SetSecret failed - %s\n", nt_errstr(status));
979                         ret = False;
980                 }
981                 
982                 data_blob_free(&enc_key);
983                 
984                 ZERO_STRUCT(new_mtime);
985                 ZERO_STRUCT(old_mtime);
986                 
987                 /* fetch the secret back again */
988                 r6.in.sec_handle = &sec_handle;
989                 r6.in.new_val = &bufp1;
990                 r6.in.new_mtime = &new_mtime;
991                 r6.in.old_val = &bufp2;
992                 r6.in.old_mtime = &old_mtime;
993                 
994                 bufp1.buf = NULL;
995                 bufp2.buf = NULL;
996                 
997                 status = dcerpc_lsa_QuerySecret(p, mem_ctx, &r6);
998                 if (!NT_STATUS_IS_OK(status)) {
999                         printf("QuerySecret failed - %s\n", nt_errstr(status));
1000                         ret = False;
1001                         secret4 = NULL;
1002                 } else {
1003
1004                         if (r6.out.new_val->buf == NULL || r6.out.old_val->buf == NULL 
1005                                 || r6.out.new_mtime == NULL || r6.out.old_mtime == NULL) {
1006                                 printf("Both secret buffers and both times not returned\n");
1007                                 ret = False;
1008                                 secret4 = NULL;
1009                         } else {
1010                                 blob1.data = r6.out.new_val->buf->data;
1011                                 blob1.length = r6.out.new_val->buf->size;
1012                                 
1013                                 blob2 = data_blob_talloc(mem_ctx, NULL, blob1.length);
1014                                 
1015                                 secret4 = sess_decrypt_string(&blob1, &session_key);
1016                                 
1017                                 if (strcmp(secret3, secret4) != 0) {
1018                                         printf("Returned NEW secret %s doesn't match %s\n", secret4, secret3);
1019                                         ret = False;
1020                                 }
1021
1022                                 blob1.data = r6.out.old_val->buf->data;
1023                                 blob1.length = r6.out.old_val->buf->length;
1024                                 
1025                                 blob2 = data_blob_talloc(mem_ctx, NULL, blob1.length);
1026                                 
1027                                 secret2 = sess_decrypt_string(&blob1, &session_key);
1028                                 
1029                                 if (strcmp(secret1, secret2) != 0) {
1030                                         printf("Returned OLD secret %s doesn't match %s\n", secret2, secret1);
1031                                         ret = False;
1032                                 }
1033                                 
1034                                 if (*r6.out.new_mtime == *r6.out.old_mtime) {
1035                                         printf("Returned secret %s had same mtime for both secrets: %s\n", 
1036                                                secname[i],
1037                                                nt_time_string(mem_ctx, *r6.out.new_mtime));
1038                                         ret = False;
1039                                 }
1040                         }
1041                 }
1042
1043                 enc_key = sess_encrypt_string(secret5, &session_key);
1044                 
1045                 r7.in.sec_handle = &sec_handle;
1046                 r7.in.old_val = &buf1;
1047                 r7.in.old_val->data = enc_key.data;
1048                 r7.in.old_val->length = enc_key.length;
1049                 r7.in.old_val->size = enc_key.length;
1050                 r7.in.new_val = NULL;
1051                 
1052                 printf("Testing SetSecret of old Secret only\n");
1053                 
1054                 status = dcerpc_lsa_SetSecret(p, mem_ctx, &r7);
1055                 if (!NT_STATUS_IS_OK(status)) {
1056                         printf("SetSecret failed - %s\n", nt_errstr(status));
1057                         ret = False;
1058                 }
1059                 
1060                 data_blob_free(&enc_key);
1061                 
1062                 /* fetch the secret back again */
1063                 r8.in.sec_handle = &sec_handle;
1064                 r8.in.new_val = &bufp1;
1065                 r8.in.new_mtime = &new_mtime;
1066                 r8.in.old_val = &bufp2;
1067                 r8.in.old_mtime = &old_mtime;
1068                 
1069                 bufp1.buf = NULL;
1070                 bufp2.buf = NULL;
1071                 
1072                 status = dcerpc_lsa_QuerySecret(p, mem_ctx, &r8);
1073                 if (!NT_STATUS_IS_OK(status)) {
1074                         printf("QuerySecret failed - %s\n", nt_errstr(status));
1075                         ret = False;
1076                 } else {
1077                         if (!r8.out.new_val || !r8.out.old_val) {
1078                                 printf("in/out pointers not returned, despite being set on in for QuerySecret\n");
1079                                 ret = False;
1080                         } else if (r8.out.new_val->buf == NULL) {
1081                                 if (i != LOCAL) { 
1082                                         printf("NEW secret buffer not returned after GLOBAL OLD set\n");
1083                                         ret = False;
1084                                 }
1085                         } else if (r8.out.old_val->buf == NULL) {
1086                                 printf("OLD secret buffer not returned after OLD set\n");
1087                                 ret = False;
1088                         } else if (r8.out.new_mtime == NULL || r8.out.old_mtime == NULL) {
1089                                 printf("Both times not returned after OLD set\n");
1090                                 ret = False;
1091                         } else {
1092                                 if (i == LOCAL) { 
1093                                         printf("NEW secret buffer should not be returned after LOCAL OLD set\n");
1094                                         ret = False;
1095                                 }
1096                                 blob1.data = r8.out.new_val->buf->data;
1097                                 blob1.length = r8.out.new_val->buf->length;
1098                                 
1099                                 blob2 = data_blob_talloc(mem_ctx, NULL, blob1.length);
1100                                 
1101                                 secret6 = sess_decrypt_string(&blob1, &session_key);
1102                                 
1103                                 if (strcmp(secret3, secret4) != 0) {
1104                                         printf("Returned NEW secret '%s' doesn't match '%s'\n", secret4, secret3);
1105                                         ret = False;
1106                                 }
1107
1108                                 blob1.data = r8.out.old_val->buf->data;
1109                                 blob1.length = r8.out.old_val->buf->size;
1110                                 
1111                                 blob2 = data_blob_talloc(mem_ctx, NULL, blob1.length);
1112                                 
1113                                 secret6 = sess_decrypt_string(&blob1, &session_key);
1114                                 
1115                                 if (strcmp(secret5, secret6) != 0) {
1116                                         printf("Returned OLD secret %s doesn't match %s\n", secret5, secret6);
1117                                         ret = False;
1118                                 }
1119                                 
1120                                 if (*r8.out.new_mtime == *r8.out.old_mtime) {
1121                                         if (i != GLOBAL) { 
1122                                                 printf("Returned secret %s had same mtime for both secrets: %s\n", 
1123                                                        secname[i],
1124                                                        nt_time_string(mem_ctx, *r8.out.new_mtime));
1125                                                 ret = False;
1126                                         }
1127                                 } else {
1128                                         printf("Returned secret %s should have had same mtime for both secrets: %s != %s\n", 
1129                                                secname[i],
1130                                                nt_time_string(mem_ctx, *r8.out.old_mtime),
1131                                                nt_time_string(mem_ctx, *r8.out.new_mtime));
1132                                         ret = False;
1133                                 }
1134                         }
1135                 }
1136
1137                 if (!test_Delete(p, mem_ctx, &sec_handle)) {
1138                         ret = False;
1139                 }
1140                 
1141                 d.in.handle = &sec_handle2;
1142                 status = dcerpc_lsa_Delete(p, mem_ctx, &d);
1143                 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
1144                         printf("Second delete expected INVALID_HANDLE - %s\n", nt_errstr(status));
1145                         ret = False;
1146                 } else {
1147
1148                         printf("Testing OpenSecret of just-deleted secret\n");
1149                         
1150                         status = dcerpc_lsa_OpenSecret(p, mem_ctx, &r2);
1151                         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
1152                                 printf("OpenSecret expected OBJECT_NAME_NOT_FOUND - %s\n", nt_errstr(status));
1153                                 ret = False;
1154                         }
1155                 }
1156                 
1157         }
1158
1159         return ret;
1160 }
1161
1162
1163 static BOOL test_EnumAccountRights(struct dcerpc_pipe *p, 
1164                                    TALLOC_CTX *mem_ctx, 
1165                                    struct policy_handle *acct_handle,
1166                                    struct dom_sid *sid)
1167 {
1168         NTSTATUS status;
1169         struct lsa_EnumAccountRights r;
1170         struct lsa_RightSet rights;
1171
1172         printf("Testing EnumAccountRights\n");
1173
1174         r.in.handle = acct_handle;
1175         r.in.sid = sid;
1176         r.out.rights = &rights;
1177
1178         status = dcerpc_lsa_EnumAccountRights(p, mem_ctx, &r);
1179         if (!NT_STATUS_IS_OK(status)) {
1180                 printf("EnumAccountRights failed - %s\n", nt_errstr(status));
1181                 return False;
1182         }
1183
1184         return True;
1185 }
1186
1187
1188 static BOOL test_QuerySecurity(struct dcerpc_pipe *p, 
1189                              TALLOC_CTX *mem_ctx, 
1190                              struct policy_handle *handle,
1191                              struct policy_handle *acct_handle)
1192 {
1193         NTSTATUS status;
1194         struct lsa_QuerySecurity r;
1195
1196         printf("Testing QuerySecurity\n");
1197
1198         r.in.handle = acct_handle;
1199         r.in.sec_info = 7;
1200
1201         status = dcerpc_lsa_QuerySecurity(p, mem_ctx, &r);
1202         if (!NT_STATUS_IS_OK(status)) {
1203                 printf("QuerySecurity failed - %s\n", nt_errstr(status));
1204                 return False;
1205         }
1206
1207         return True;
1208 }
1209
1210 static BOOL test_OpenAccount(struct dcerpc_pipe *p, 
1211                              TALLOC_CTX *mem_ctx, 
1212                              struct policy_handle *handle,
1213                              struct dom_sid *sid)
1214 {
1215         NTSTATUS status;
1216         struct lsa_OpenAccount r;
1217         struct policy_handle acct_handle;
1218
1219         printf("Testing OpenAccount\n");
1220
1221         r.in.handle = handle;
1222         r.in.sid = sid;
1223         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1224         r.out.acct_handle = &acct_handle;
1225
1226         status = dcerpc_lsa_OpenAccount(p, mem_ctx, &r);
1227         if (!NT_STATUS_IS_OK(status)) {
1228                 printf("OpenAccount failed - %s\n", nt_errstr(status));
1229                 return False;
1230         }
1231
1232         if (!test_EnumPrivsAccount(p, mem_ctx, handle, &acct_handle)) {
1233                 return False;
1234         }
1235
1236         if (!test_QuerySecurity(p, mem_ctx, handle, &acct_handle)) {
1237                 return False;
1238         }
1239
1240         return True;
1241 }
1242
1243 static BOOL test_EnumAccounts(struct dcerpc_pipe *p, 
1244                           TALLOC_CTX *mem_ctx, 
1245                           struct policy_handle *handle)
1246 {
1247         NTSTATUS status;
1248         struct lsa_EnumAccounts r;
1249         struct lsa_SidArray sids1, sids2;
1250         uint32_t resume_handle = 0;
1251         int i;
1252
1253         printf("\ntesting EnumAccounts\n");
1254
1255         r.in.handle = handle;
1256         r.in.resume_handle = &resume_handle;
1257         r.in.num_entries = 100;
1258         r.out.resume_handle = &resume_handle;
1259         r.out.sids = &sids1;
1260
1261         resume_handle = 0;
1262         while (True) {
1263                 status = dcerpc_lsa_EnumAccounts(p, mem_ctx, &r);
1264                 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES)) {
1265                         break;
1266                 }
1267                 if (!NT_STATUS_IS_OK(status)) {
1268                         printf("EnumAccounts failed - %s\n", nt_errstr(status));
1269                         return False;
1270                 }
1271
1272                 if (!test_LookupSids(p, mem_ctx, handle, &sids1)) {
1273                         return False;
1274                 }
1275
1276                 if (!test_LookupSids2(p, mem_ctx, handle, &sids1)) {
1277                         return False;
1278                 }
1279
1280                 if (!test_LookupSids3(p, mem_ctx, &sids1)) {
1281                         return False;
1282                 }
1283
1284                 printf("testing all accounts\n");
1285                 for (i=0;i<sids1.num_sids;i++) {
1286                         test_OpenAccount(p, mem_ctx, handle, sids1.sids[i].sid);
1287                         test_EnumAccountRights(p, mem_ctx, handle, sids1.sids[i].sid);
1288                 }
1289                 printf("\n");
1290         }
1291
1292         if (sids1.num_sids < 3) {
1293                 return True;
1294         }
1295         
1296         printf("trying EnumAccounts partial listing (asking for 1 at 2)\n");
1297         resume_handle = 2;
1298         r.in.num_entries = 1;
1299         r.out.sids = &sids2;
1300
1301         status = dcerpc_lsa_EnumAccounts(p, mem_ctx, &r);
1302         if (!NT_STATUS_IS_OK(status)) {
1303                 printf("EnumAccounts failed - %s\n", nt_errstr(status));
1304                 return False;
1305         }
1306
1307         if (sids2.num_sids != 1) {
1308                 printf("Returned wrong number of entries (%d)\n", sids2.num_sids);
1309                 return False;
1310         }
1311
1312         return True;
1313 }
1314
1315 static BOOL test_LookupPrivDisplayName(struct dcerpc_pipe *p,
1316                                 TALLOC_CTX *mem_ctx,
1317                                 struct policy_handle *handle,
1318                                 struct lsa_String *priv_name)
1319 {
1320         struct lsa_LookupPrivDisplayName r;
1321         NTSTATUS status;
1322         /* produce a reasonable range of language output without screwing up
1323            terminals */
1324         uint16_t language_id = (random() % 4) + 0x409;
1325
1326         printf("testing LookupPrivDisplayName(%s)\n", priv_name->string);
1327         
1328         r.in.handle = handle;
1329         r.in.name = priv_name;
1330         r.in.language_id = &language_id;
1331         r.out.language_id = &language_id;
1332         r.in.unknown = 0;
1333
1334         status = dcerpc_lsa_LookupPrivDisplayName(p, mem_ctx, &r);
1335         if (!NT_STATUS_IS_OK(status)) {
1336                 printf("LookupPrivDisplayName failed - %s\n", nt_errstr(status));
1337                 return False;
1338         }
1339         printf("%s -> \"%s\"  (language 0x%x/0x%x)\n", 
1340                priv_name->string, r.out.disp_name->string, 
1341                *r.in.language_id, *r.out.language_id);
1342
1343         return True;
1344 }
1345
1346 static BOOL test_EnumAccountsWithUserRight(struct dcerpc_pipe *p, 
1347                                 TALLOC_CTX *mem_ctx,
1348                                 struct policy_handle *handle,
1349                                 struct lsa_String *priv_name)
1350 {
1351         struct lsa_EnumAccountsWithUserRight r;
1352         struct lsa_SidArray sids;
1353         NTSTATUS status;
1354
1355         ZERO_STRUCT(sids);
1356         
1357         printf("testing EnumAccountsWithUserRight(%s)\n", priv_name->string);
1358         
1359         r.in.handle = handle;
1360         r.in.name = priv_name;
1361         r.out.sids = &sids;
1362
1363         status = dcerpc_lsa_EnumAccountsWithUserRight(p, mem_ctx, &r);
1364
1365         /* NT_STATUS_NO_MORE_ENTRIES means noone has this privilege */
1366         if (NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES)) {
1367                 return True;
1368         }
1369
1370         if (!NT_STATUS_IS_OK(status)) {
1371                 printf("EnumAccountsWithUserRight failed - %s\n", nt_errstr(status));
1372                 return False;
1373         }
1374         
1375         return True;
1376 }
1377
1378
1379 static BOOL test_EnumPrivs(struct dcerpc_pipe *p, 
1380                            TALLOC_CTX *mem_ctx, 
1381                            struct policy_handle *handle)
1382 {
1383         NTSTATUS status;
1384         struct lsa_EnumPrivs r;
1385         struct lsa_PrivArray privs1;
1386         uint32_t resume_handle = 0;
1387         int i;
1388         BOOL ret = True;
1389
1390         printf("\ntesting EnumPrivs\n");
1391
1392         r.in.handle = handle;
1393         r.in.resume_handle = &resume_handle;
1394         r.in.max_count = 100;
1395         r.out.resume_handle = &resume_handle;
1396         r.out.privs = &privs1;
1397
1398         resume_handle = 0;
1399         status = dcerpc_lsa_EnumPrivs(p, mem_ctx, &r);
1400         if (!NT_STATUS_IS_OK(status)) {
1401                 printf("EnumPrivs failed - %s\n", nt_errstr(status));
1402                 return False;
1403         }
1404
1405         for (i = 0; i< privs1.count; i++) {
1406                 test_LookupPrivDisplayName(p, mem_ctx, handle, (struct lsa_String *)&privs1.privs[i].name);
1407                 test_LookupPrivValue(p, mem_ctx, handle, (struct lsa_String *)&privs1.privs[i].name);
1408                 if (!test_EnumAccountsWithUserRight(p, mem_ctx, handle, (struct lsa_String *)&privs1.privs[i].name)) {
1409                         ret = False;
1410                 }
1411         }
1412
1413         return ret;
1414 }
1415
1416 static BOOL test_query_each_TrustDom(struct dcerpc_pipe *p, 
1417                                      TALLOC_CTX *mem_ctx, 
1418                                      struct policy_handle *handle, 
1419                                      struct lsa_DomainList *domains) 
1420 {
1421         NTSTATUS status;
1422         int i,j;
1423         BOOL ret = True;
1424                 
1425         printf("\nTesting OpenTrustedDomain, OpenTrustedDomainByName and QueryInfoTrustedDomain\n");
1426         for (i=0; i< domains->count; i++) {
1427                 struct lsa_OpenTrustedDomain trust;
1428                 struct lsa_OpenTrustedDomainByName trust_by_name;
1429                 struct policy_handle trustdom_handle;
1430                 struct policy_handle handle2;
1431                 struct lsa_Close c;
1432                 int levels [] = {1, 3, 6, 8, 12};
1433                         
1434                 if (domains->domains[i].sid) {
1435                         trust.in.handle = handle;
1436                         trust.in.sid = domains->domains[i].sid;
1437                         trust.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1438                         trust.out.trustdom_handle = &trustdom_handle;
1439                         
1440                         status = dcerpc_lsa_OpenTrustedDomain(p, mem_ctx, &trust);
1441                         
1442                         if (!NT_STATUS_IS_OK(status)) {
1443                                 printf("OpenTrustedDomain failed - %s\n", nt_errstr(status));
1444                                 return False;
1445                         }
1446                         
1447                         c.in.handle = &trustdom_handle;
1448                         c.out.handle = &handle2;
1449                         
1450                         for (j=0; j < ARRAY_SIZE(levels); j++) {
1451                                 struct lsa_QueryTrustedDomainInfo q;
1452                                 union lsa_TrustedDomainInfo info;
1453                                 q.in.trustdom_handle = &trustdom_handle;
1454                                 q.in.level = levels[j];
1455                                 q.out.info = &info;
1456                                 status = dcerpc_lsa_QueryTrustedDomainInfo(p, mem_ctx, &q);
1457                                 if (!NT_STATUS_IS_OK(status)) {
1458                                         printf("QueryTrustedDomainInfo level %d failed - %s\n", 
1459                                                levels[j], nt_errstr(status));
1460                                         ret = False;
1461                                 }
1462                         }
1463                         
1464                         status = dcerpc_lsa_Close(p, mem_ctx, &c);
1465                         if (!NT_STATUS_IS_OK(status)) {
1466                                 printf("Close of trusted domain failed - %s\n", nt_errstr(status));
1467                                 return False;
1468                         }
1469                 }
1470
1471                 trust_by_name.in.handle = handle;
1472                 trust_by_name.in.name.string = domains->domains[i].name.string;
1473                 trust_by_name.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1474                 trust_by_name.out.trustdom_handle = &trustdom_handle;
1475                         
1476                 status = dcerpc_lsa_OpenTrustedDomainByName(p, mem_ctx, &trust_by_name);
1477                         
1478                 if (!NT_STATUS_IS_OK(status)) {
1479                         printf("OpenTrustedDomainByName failed - %s\n", nt_errstr(status));
1480                         return False;
1481                 }
1482
1483                 for (j=0; j < ARRAY_SIZE(levels); j++) {
1484                         struct lsa_QueryTrustedDomainInfo q;
1485                         union lsa_TrustedDomainInfo info;
1486                         q.in.trustdom_handle = &trustdom_handle;
1487                         q.in.level = levels[j];
1488                         q.out.info = &info;
1489                         status = dcerpc_lsa_QueryTrustedDomainInfo(p, mem_ctx, &q);
1490                         if (!NT_STATUS_IS_OK(status)) {
1491                                 printf("QueryTrustedDomainInfo level %d failed - %s\n", 
1492                                        levels[j], nt_errstr(status));
1493                                 ret = False;
1494                         }
1495                 }
1496                 
1497                 c.in.handle = &trustdom_handle;
1498                 c.out.handle = &handle2;
1499
1500                 status = dcerpc_lsa_Close(p, mem_ctx, &c);
1501                 if (!NT_STATUS_IS_OK(status)) {
1502                         printf("Close of trusted domain failed - %s\n", nt_errstr(status));
1503                         return False;
1504                 }
1505
1506                 for (j=0; j < ARRAY_SIZE(levels); j++) {
1507                         struct lsa_QueryTrustedDomainInfoBySid q;
1508                         union lsa_TrustedDomainInfo info;
1509
1510                         if (!domains->domains[i].sid) {
1511                                 continue;
1512                         }
1513
1514                         q.in.handle  = handle;
1515                         q.in.dom_sid = domains->domains[i].sid;
1516                         q.in.level   = levels[j];
1517                         q.out.info   = &info;
1518                         status = dcerpc_lsa_QueryTrustedDomainInfoBySid(p, mem_ctx, &q);
1519                         if (!NT_STATUS_IS_OK(status)) {
1520                                 printf("QueryTrustedDomainInfoBySid level %d failed - %s\n", 
1521                                        levels[j], nt_errstr(status));
1522                                 ret = False;
1523                         }
1524                 }
1525                 
1526                 for (j=0; j < ARRAY_SIZE(levels); j++) {
1527                         struct lsa_QueryTrustedDomainInfoByName q;
1528                         union lsa_TrustedDomainInfo info;
1529                         q.in.handle         = handle;
1530                         q.in.trusted_domain.string = domains->domains[i].name.string;
1531                         q.in.level          = levels[j];
1532                         q.out.info          = &info;
1533                         status = dcerpc_lsa_QueryTrustedDomainInfoByName(p, mem_ctx, &q);
1534                         if (!NT_STATUS_IS_OK(status)) {
1535                                 printf("QueryTrustedDomainInfoByName level %d failed - %s\n", 
1536                                        levels[j], nt_errstr(status));
1537                                 ret = False;
1538                         }
1539                 }
1540         }
1541         return ret;
1542 }
1543
1544 static BOOL test_EnumTrustDom(struct dcerpc_pipe *p, 
1545                               TALLOC_CTX *mem_ctx, 
1546                               struct policy_handle *handle)
1547 {
1548         struct lsa_EnumTrustDom r;
1549         NTSTATUS enum_status;
1550         uint32_t resume_handle = 0;
1551         struct lsa_DomainList domains;
1552         BOOL ret = True;
1553
1554         printf("\nTesting EnumTrustDom\n");
1555
1556         do {
1557                 r.in.handle = handle;
1558                 r.in.resume_handle = &resume_handle;
1559                 r.in.max_size = LSA_ENUM_TRUST_DOMAIN_MULTIPLIER * 3;
1560                 r.out.domains = &domains;
1561                 r.out.resume_handle = &resume_handle;
1562                 
1563                 enum_status = dcerpc_lsa_EnumTrustDom(p, mem_ctx, &r);
1564                 
1565                 /* NO_MORE_ENTRIES is allowed */
1566                 if (NT_STATUS_EQUAL(enum_status, NT_STATUS_NO_MORE_ENTRIES)) {
1567                         return True;
1568                 } else if (NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES)) {
1569                         /* Windows 2003 gets this off by one on the first run */
1570                         if (r.out.domains->count < 3 || r.out.domains->count > 4) {
1571                                 printf("EnumTrustDom didn't fill the buffer we "
1572                                        "asked it to (got %d, expected %d / %d == %d entries)\n",
1573                                        r.out.domains->count, LSA_ENUM_TRUST_DOMAIN_MULTIPLIER * 3, 
1574                                        LSA_ENUM_TRUST_DOMAIN_MULTIPLIER, r.in.max_size);
1575                                 ret = False;
1576                         }
1577                 } else if (!NT_STATUS_IS_OK(enum_status)) {
1578                         printf("EnumTrustDom failed - %s\n", nt_errstr(enum_status));
1579                         return False;
1580                 }
1581                 
1582                 ret &= test_query_each_TrustDom(p, mem_ctx, handle, &domains);
1583
1584         } while ((NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES)));
1585
1586         return ret;
1587 }
1588
1589 static BOOL test_CreateTrustedDomain(struct dcerpc_pipe *p, 
1590                                      TALLOC_CTX *mem_ctx, 
1591                                      struct policy_handle *handle)
1592 {
1593         NTSTATUS status;
1594         BOOL ret = True;
1595         struct lsa_CreateTrustedDomain r;
1596         struct lsa_TrustInformation trustinfo;
1597         struct dom_sid *domsid[12];
1598         struct policy_handle trustdom_handle[12];
1599         struct lsa_QueryTrustedDomainInfo q;
1600         int i;
1601
1602         printf("Testing CreateTrustedDomain for 12 domains\n");
1603
1604         for (i=0; i< 12; i++) {
1605                 char *trust_name = talloc_asprintf(mem_ctx, "torturedom%02d", i);
1606                 char *trust_sid = talloc_asprintf(mem_ctx, "S-1-5-21-97398-379795-100%02d", i);
1607                 
1608                 domsid[i] = dom_sid_parse_talloc(mem_ctx, trust_sid);
1609
1610                 trustinfo.sid = domsid[i];
1611                 init_lsa_String((struct lsa_String *)&trustinfo.name, trust_name);
1612
1613                 r.in.handle = handle;
1614                 r.in.info = &trustinfo;
1615                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1616                 r.out.trustdom_handle = &trustdom_handle[i];
1617                 
1618                 status = dcerpc_lsa_CreateTrustedDomain(p, mem_ctx, &r);
1619                 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
1620                         test_DeleteTrustedDomain(p, mem_ctx, handle, trustinfo.name);
1621                         status = dcerpc_lsa_CreateTrustedDomain(p, mem_ctx, &r);
1622                 }
1623                 if (!NT_STATUS_IS_OK(status)) {
1624                         printf("CreateTrustedDomain failed - %s\n", nt_errstr(status));
1625                         ret = False;
1626                 } else {
1627                 
1628                         q.in.trustdom_handle = &trustdom_handle[i];
1629                         q.in.level = LSA_TRUSTED_DOMAIN_INFO_NAME;
1630                         status = dcerpc_lsa_QueryTrustedDomainInfo(p, mem_ctx, &q);
1631                         if (!NT_STATUS_IS_OK(status)) {
1632                                 printf("QueryTrustedDomainInfo level 1 failed - %s\n", nt_errstr(status));
1633                                 ret = False;
1634                         } else if (!q.out.info) {
1635                                 ret = False;
1636                         } else {
1637                                 if (strcmp(q.out.info->name.netbios_name.string, trustinfo.name.string) != 0) {
1638                                         printf("QueryTrustedDomainInfo returned inconsistant short name: %s != %s\n",
1639                                                q.out.info->name.netbios_name.string, trustinfo.name.string);
1640                                         ret = False;
1641                                 }
1642                         }
1643                 }
1644         }
1645
1646         /* now that we have some domains to look over, we can test the enum calls */
1647         if (!test_EnumTrustDom(p, mem_ctx, handle)) {
1648                 ret = False;
1649         }
1650         
1651         for (i=0; i<12; i++) {
1652                 if (!test_Delete(p, mem_ctx, &trustdom_handle[i])) {
1653                         ret = False;
1654                 }
1655         }
1656
1657         return ret;
1658 }
1659
1660 static BOOL test_QueryDomainInfoPolicy(struct dcerpc_pipe *p, 
1661                                  TALLOC_CTX *mem_ctx, 
1662                                  struct policy_handle *handle)
1663 {
1664         struct lsa_QueryDomainInformationPolicy r;
1665         NTSTATUS status;
1666         int i;
1667         BOOL ret = True;
1668         printf("\nTesting QueryDomainInformationPolicy\n");
1669
1670         for (i=2;i<4;i++) {
1671                 r.in.handle = handle;
1672                 r.in.level = i;
1673
1674                 printf("\ntrying QueryDomainInformationPolicy level %d\n", i);
1675
1676                 status = dcerpc_lsa_QueryDomainInformationPolicy(p, mem_ctx, &r);
1677
1678                 if (!NT_STATUS_IS_OK(status)) {
1679                         printf("QueryDomainInformationPolicy failed - %s\n", nt_errstr(status));
1680                         ret = False;
1681                         continue;
1682                 }
1683         }
1684
1685         return ret;
1686 }
1687
1688
1689 static BOOL test_QueryInfoPolicy(struct dcerpc_pipe *p, 
1690                                  TALLOC_CTX *mem_ctx, 
1691                                  struct policy_handle *handle)
1692 {
1693         struct lsa_QueryInfoPolicy r;
1694         NTSTATUS status;
1695         int i;
1696         BOOL ret = True;
1697         printf("\nTesting QueryInfoPolicy\n");
1698
1699         for (i=1;i<13;i++) {
1700                 r.in.handle = handle;
1701                 r.in.level = i;
1702
1703                 printf("\ntrying QueryInfoPolicy level %d\n", i);
1704
1705                 status = dcerpc_lsa_QueryInfoPolicy(p, mem_ctx, &r);
1706
1707                 if ((i == 9 || i == 10 || i == 11) &&
1708                     NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1709                         printf("server failed level %u (OK)\n", i);
1710                         continue;
1711                 }
1712
1713                 if (!NT_STATUS_IS_OK(status)) {
1714                         printf("QueryInfoPolicy failed - %s\n", nt_errstr(status));
1715                         ret = False;
1716                         continue;
1717                 }
1718         }
1719
1720         return ret;
1721 }
1722
1723 static BOOL test_QueryInfoPolicy2(struct dcerpc_pipe *p, 
1724                                   TALLOC_CTX *mem_ctx, 
1725                                   struct policy_handle *handle)
1726 {
1727         struct lsa_QueryInfoPolicy2 r;
1728         NTSTATUS status;
1729         int i;
1730         BOOL ret = True;
1731         printf("\nTesting QueryInfoPolicy2\n");
1732
1733         for (i=1;i<13;i++) {
1734                 r.in.handle = handle;
1735                 r.in.level = i;
1736
1737                 printf("\ntrying QueryInfoPolicy2 level %d\n", i);
1738
1739                 status = dcerpc_lsa_QueryInfoPolicy2(p, mem_ctx, &r);
1740
1741                 if ((i == 9 || i == 10 || i == 11) &&
1742                     NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1743                         printf("server failed level %u (OK)\n", i);
1744                         continue;
1745                 }
1746
1747                 if (!NT_STATUS_IS_OK(status)) {
1748                         printf("QueryInfoPolicy2 failed - %s\n", nt_errstr(status));
1749                         ret = False;
1750                         continue;
1751                 }
1752         }
1753
1754         return ret;
1755 }
1756
1757 static BOOL test_GetUserName(struct dcerpc_pipe *p, 
1758                                   TALLOC_CTX *mem_ctx, 
1759                                   struct policy_handle *handle)
1760 {
1761         struct lsa_GetUserName r;
1762         NTSTATUS status;
1763         BOOL ret = True;
1764         struct lsa_StringPointer authority_name_p;
1765
1766         printf("\nTesting GetUserName\n");
1767
1768         r.in.system_name = "\\";        
1769         r.in.account_name = NULL;       
1770         r.in.authority_name = &authority_name_p;
1771         authority_name_p.string = NULL;
1772
1773         status = dcerpc_lsa_GetUserName(p, mem_ctx, &r);
1774
1775         if (!NT_STATUS_IS_OK(status)) {
1776                 printf("GetUserName failed - %s\n", nt_errstr(status));
1777                 ret = False;
1778         }
1779
1780         return ret;
1781 }
1782
1783 BOOL test_lsa_Close(struct dcerpc_pipe *p, 
1784                     TALLOC_CTX *mem_ctx, 
1785                     struct policy_handle *handle)
1786 {
1787         NTSTATUS status;
1788         struct lsa_Close r;
1789         struct policy_handle handle2;
1790
1791         printf("\ntesting Close\n");
1792
1793         r.in.handle = handle;
1794         r.out.handle = &handle2;
1795
1796         status = dcerpc_lsa_Close(p, mem_ctx, &r);
1797         if (!NT_STATUS_IS_OK(status)) {
1798                 printf("Close failed - %s\n", nt_errstr(status));
1799                 return False;
1800         }
1801
1802         status = dcerpc_lsa_Close(p, mem_ctx, &r);
1803         /* its really a fault - we need a status code for rpc fault */
1804         if (!NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
1805                 printf("Close failed - %s\n", nt_errstr(status));
1806                 return False;
1807         }
1808
1809         printf("\n");
1810
1811         return True;
1812 }
1813
1814 BOOL torture_rpc_lsa(void)
1815 {
1816         NTSTATUS status;
1817         struct dcerpc_pipe *p;
1818         TALLOC_CTX *mem_ctx;
1819         BOOL ret = True;
1820         struct policy_handle *handle;
1821
1822         mem_ctx = talloc_init("torture_rpc_lsa");
1823
1824         status = torture_rpc_connection(mem_ctx, &p, &dcerpc_table_lsarpc);
1825         if (!NT_STATUS_IS_OK(status)) {
1826                 talloc_free(mem_ctx);
1827                 return False;
1828         }
1829
1830         if (!test_OpenPolicy(p, mem_ctx)) {
1831                 ret = False;
1832         }
1833
1834         if (!test_lsa_OpenPolicy2(p, mem_ctx, &handle)) {
1835                 ret = False;
1836         }
1837
1838         if (handle) {
1839                 if (!test_LookupSids_async(p, mem_ctx, handle)) {
1840                         ret = False;
1841                 }
1842
1843                 if (!test_QueryDomainInfoPolicy(p, mem_ctx, handle)) {
1844                         ret = False;
1845                 }
1846                 
1847                 if (!test_CreateAccount(p, mem_ctx, handle)) {
1848                         ret = False;
1849                 }
1850                 
1851                 if (!test_CreateSecret(p, mem_ctx, handle)) {
1852                         ret = False;
1853                 }
1854                 
1855                 if (!test_CreateTrustedDomain(p, mem_ctx, handle)) {
1856                         ret = False;
1857                 }
1858                 
1859                 if (!test_EnumAccounts(p, mem_ctx, handle)) {
1860                         ret = False;
1861                 }
1862                 
1863                 if (!test_EnumPrivs(p, mem_ctx, handle)) {
1864                         ret = False;
1865                 }
1866                 
1867                 if (!test_QueryInfoPolicy(p, mem_ctx, handle)) {
1868                         ret = False;
1869                 }
1870                 
1871                 if (!test_QueryInfoPolicy2(p, mem_ctx, handle)) {
1872                         ret = False;
1873                 }
1874                 
1875                 if (!test_GetUserName(p, mem_ctx, handle)) {
1876                         ret = False;
1877                 }
1878                 
1879 #if 0
1880                 if (!test_Delete(p, mem_ctx, handle)) {
1881                         ret = False;
1882                 }
1883 #endif
1884                 
1885                 if (!test_many_LookupSids(p, mem_ctx, handle)) {
1886                         ret = False;
1887                 }
1888                 
1889                 if (!test_lsa_Close(p, mem_ctx, handle)) {
1890                         ret = False;
1891                 }
1892         } else {
1893                 if (!test_many_LookupSids(p, mem_ctx, handle)) {
1894                         ret = False;
1895                 }
1896         }
1897                 
1898         talloc_free(mem_ctx);
1899
1900         return ret;
1901 }