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