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