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