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