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