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