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