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