s4-torture: Add a lsarpc test_LookupNames4_fail function.
[mat/samba.git] / source4 / torture / rpc / lsa.c
1 /*
2    Unix SMB/CIFS implementation.
3    test suite for lsa rpc operations
4
5    Copyright (C) Andrew Tridgell 2003
6    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2005
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "torture/torture.h"
24 #include "librpc/gen_ndr/ndr_lsa_c.h"
25 #include "librpc/gen_ndr/netlogon.h"
26 #include "librpc/gen_ndr/ndr_drsblobs.h"
27 #include "librpc/gen_ndr/ndr_netlogon_c.h"
28 #include "lib/events/events.h"
29 #include "libcli/security/security.h"
30 #include "libcli/auth/libcli_auth.h"
31 #include "torture/rpc/torture_rpc.h"
32 #include "param/param.h"
33 #include "../lib/crypto/crypto.h"
34 #define TEST_MACHINENAME "lsatestmach"
35 #define TRUSTPW "12345678"
36
37 static void init_lsa_String(struct lsa_String *name, const char *s)
38 {
39         name->string = s;
40 }
41
42 static bool test_OpenPolicy(struct dcerpc_binding_handle *b,
43                             struct torture_context *tctx,
44                             bool test_fail) /* check if the tests fails! */
45 {
46         struct lsa_ObjectAttribute attr;
47         struct policy_handle handle;
48         struct lsa_QosInfo qos;
49         struct lsa_OpenPolicy r;
50         uint16_t system_name = '\\';
51
52         torture_comment(tctx, "\nTesting OpenPolicy\n");
53
54         qos.len = 0;
55         qos.impersonation_level = 2;
56         qos.context_mode = 1;
57         qos.effective_only = 0;
58
59         attr.len = 0;
60         attr.root_dir = NULL;
61         attr.object_name = NULL;
62         attr.attributes = 0;
63         attr.sec_desc = NULL;
64         attr.sec_qos = &qos;
65
66         r.in.system_name = &system_name;
67         r.in.attr = &attr;
68         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
69         r.out.handle = &handle;
70
71         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenPolicy_r(b, tctx, &r),
72                                    "OpenPolicy failed");
73         if (!NT_STATUS_IS_OK(r.out.result)) {
74                 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) ||
75                     NT_STATUS_EQUAL(r.out.result, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
76                         if (test_fail) {
77                                 torture_comment(tctx, "not considering %s to be an error\n",
78                                                 nt_errstr(r.out.result));
79                                 return true;
80                         }
81                 }
82                 torture_comment(tctx, "OpenPolicy failed - %s\n",
83                                 nt_errstr(r.out.result));
84                 return false;
85         }
86
87         return true;
88 }
89
90
91 bool test_lsa_OpenPolicy2_ex(struct dcerpc_binding_handle *b,
92                              struct torture_context *tctx,
93                              struct policy_handle **handle,
94                              NTSTATUS expected_status,
95                              bool test_fail)
96 {
97         struct lsa_ObjectAttribute attr;
98         struct lsa_QosInfo qos;
99         struct lsa_OpenPolicy2 r;
100         NTSTATUS status;
101
102         torture_comment(tctx, "\nTesting OpenPolicy2\n");
103
104         *handle = talloc(tctx, struct policy_handle);
105         if (!*handle) {
106                 return false;
107         }
108
109         qos.len = 0;
110         qos.impersonation_level = 2;
111         qos.context_mode = 1;
112         qos.effective_only = 0;
113
114         attr.len = 0;
115         attr.root_dir = NULL;
116         attr.object_name = NULL;
117         attr.attributes = 0;
118         attr.sec_desc = NULL;
119         attr.sec_qos = &qos;
120
121         r.in.system_name = "\\";
122         r.in.attr = &attr;
123         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
124         r.out.handle = *handle;
125
126         status = dcerpc_lsa_OpenPolicy2_r(b, tctx, &r);
127         torture_assert_ntstatus_equal(tctx, status, expected_status,
128                                    "OpenPolicy2 failed");
129         if (!NT_STATUS_IS_OK(expected_status)) {
130                 return true;
131         }
132         if (!NT_STATUS_IS_OK(r.out.result)) {
133                 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) ||
134                     NT_STATUS_EQUAL(r.out.result, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
135                         if (test_fail) {
136                                 torture_comment(tctx, "not considering %s to be an error\n",
137                                                 nt_errstr(r.out.result));
138                                 talloc_free(*handle);
139                                 *handle = NULL;
140                                 return true;
141                         }
142                 }
143                 torture_comment(tctx, "OpenPolicy2 failed - %s\n",
144                                 nt_errstr(r.out.result));
145                 return false;
146         }
147
148         return true;
149 }
150
151
152 bool test_lsa_OpenPolicy2(struct dcerpc_binding_handle *b,
153                           struct torture_context *tctx,
154                           struct policy_handle **handle)
155 {
156         return test_lsa_OpenPolicy2_ex(b, tctx, handle, NT_STATUS_OK, false);
157 }
158
159 static bool test_LookupNames(struct dcerpc_binding_handle *b,
160                              struct torture_context *tctx,
161                              struct policy_handle *handle,
162                              struct lsa_TransNameArray *tnames)
163 {
164         struct lsa_LookupNames r;
165         struct lsa_TransSidArray sids;
166         struct lsa_RefDomainList *domains = NULL;
167         struct lsa_String *names;
168         uint32_t count = 0;
169         int i;
170         uint32_t *input_idx;
171
172         torture_comment(tctx, "\nTesting LookupNames with %d names\n", tnames->count);
173
174         sids.count = 0;
175         sids.sids = NULL;
176
177
178         r.in.num_names = 0;
179
180         input_idx = talloc_array(tctx, uint32_t, tnames->count);
181         names = talloc_array(tctx, struct lsa_String, tnames->count);
182
183         for (i=0;i<tnames->count;i++) {
184                 if (tnames->names[i].sid_type != SID_NAME_UNKNOWN) {
185                         init_lsa_String(&names[r.in.num_names], tnames->names[i].name.string);
186                         input_idx[r.in.num_names] = i;
187                         r.in.num_names++;
188                 }
189         }
190
191         r.in.handle = handle;
192         r.in.names = names;
193         r.in.sids = &sids;
194         r.in.level = 1;
195         r.in.count = &count;
196         r.out.count = &count;
197         r.out.sids = &sids;
198         r.out.domains = &domains;
199
200         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupNames_r(b, tctx, &r),
201                                    "LookupNames failed");
202         if (NT_STATUS_EQUAL(r.out.result, STATUS_SOME_UNMAPPED) ||
203             NT_STATUS_EQUAL(r.out.result, NT_STATUS_NONE_MAPPED)) {
204                 for (i=0;i< r.in.num_names;i++) {
205                         if (i < count && sids.sids[i].sid_type == SID_NAME_UNKNOWN) {
206                                 torture_comment(tctx, "LookupName of %s was unmapped\n",
207                                        tnames->names[i].name.string);
208                         } else if (i >=count) {
209                                 torture_comment(tctx, "LookupName of %s failed to return a result\n",
210                                        tnames->names[i].name.string);
211                         }
212                 }
213                 torture_comment(tctx, "LookupNames failed - %s\n",
214                                 nt_errstr(r.out.result));
215                 return false;
216         } else if (!NT_STATUS_IS_OK(r.out.result)) {
217                 torture_comment(tctx, "LookupNames failed - %s\n",
218                                 nt_errstr(r.out.result));
219                 return false;
220         }
221
222         for (i=0;i< r.in.num_names;i++) {
223                 if (i < count) {
224                         if (sids.sids[i].sid_type != tnames->names[input_idx[i]].sid_type) {
225                                 torture_comment(tctx, "LookupName of %s got unexpected name type: %s\n",
226                                                 tnames->names[input_idx[i]].name.string,
227                                                 sid_type_lookup(sids.sids[i].sid_type));
228                                 return false;
229                         }
230                         if ((sids.sids[i].sid_type == SID_NAME_DOMAIN) &&
231                             (sids.sids[i].rid != (uint32_t)-1)) {
232                                 torture_comment(tctx, "LookupName of %s got unexpected rid: %d\n",
233                                         tnames->names[input_idx[i]].name.string, sids.sids[i].rid);
234                                 return false;
235                         }
236                 } else if (i >=count) {
237                         torture_comment(tctx, "LookupName of %s failed to return a result\n",
238                                tnames->names[input_idx[i]].name.string);
239                         return false;
240                 }
241         }
242         torture_comment(tctx, "\n");
243
244         return true;
245 }
246
247 static bool test_LookupNames_bogus(struct dcerpc_binding_handle *b,
248                                    struct torture_context *tctx,
249                                    struct policy_handle *handle)
250 {
251         struct lsa_LookupNames r;
252         struct lsa_TransSidArray sids;
253         struct lsa_RefDomainList *domains = NULL;
254         struct lsa_String names[1];
255         uint32_t count = 0;
256
257         torture_comment(tctx, "\nTesting LookupNames with bogus name\n");
258
259         sids.count = 0;
260         sids.sids = NULL;
261
262         init_lsa_String(&names[0], "NT AUTHORITY\\BOGUS");
263
264         r.in.handle = handle;
265         r.in.num_names = 1;
266         r.in.names = names;
267         r.in.sids = &sids;
268         r.in.level = 1;
269         r.in.count = &count;
270         r.out.count = &count;
271         r.out.sids = &sids;
272         r.out.domains = &domains;
273
274         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupNames_r(b, tctx, &r),
275                                    "LookupNames bogus failed");
276         if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_NONE_MAPPED)) {
277                 torture_comment(tctx, "LookupNames failed - %s\n",
278                                 nt_errstr(r.out.result));
279                 return false;
280         }
281
282         torture_comment(tctx, "\n");
283
284         return true;
285 }
286
287 static bool test_LookupNames_NULL(struct dcerpc_binding_handle *b,
288                                   struct torture_context *tctx,
289                                   struct policy_handle *handle)
290 {
291         struct lsa_LookupNames r;
292         struct lsa_TransSidArray sids;
293         struct lsa_RefDomainList *domains = NULL;
294         struct lsa_String names[1];
295         uint32_t count = 0;
296
297         torture_comment(tctx, "\nTesting LookupNames with NULL name\n");
298
299         sids.count = 0;
300         sids.sids = NULL;
301
302         names[0].string = NULL;
303
304         r.in.handle = handle;
305         r.in.num_names = 1;
306         r.in.names = names;
307         r.in.sids = &sids;
308         r.in.level = 1;
309         r.in.count = &count;
310         r.out.count = &count;
311         r.out.sids = &sids;
312         r.out.domains = &domains;
313
314         /* nt4 returns NT_STATUS_NONE_MAPPED with sid_type
315          * SID_NAME_UNKNOWN, rid 0, and sid_index -1;
316          *
317          * w2k3/w2k8 return NT_STATUS_OK with sid_type
318          * SID_NAME_DOMAIN, rid -1 and sid_index 0 and BUILTIN domain
319          */
320
321         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupNames_r(b, tctx, &r),
322                 "LookupNames with NULL name failed");
323         torture_assert_ntstatus_ok(tctx, r.out.result,
324                 "LookupNames with NULL name failed");
325
326         torture_comment(tctx, "\n");
327
328         return true;
329 }
330
331 static bool test_LookupNames_wellknown(struct dcerpc_binding_handle *b,
332                                        struct torture_context *tctx,
333                                        struct policy_handle *handle)
334 {
335         struct lsa_TranslatedName name;
336         struct lsa_TransNameArray tnames;
337         bool ret = true;
338
339         torture_comment(tctx, "Testing LookupNames with well known names\n");
340
341         tnames.names = &name;
342         tnames.count = 1;
343         name.name.string = "NT AUTHORITY\\SYSTEM";
344         name.sid_type = SID_NAME_WKN_GRP;
345         ret &= test_LookupNames(b, tctx, handle, &tnames);
346
347         name.name.string = "NT AUTHORITY\\ANONYMOUS LOGON";
348         name.sid_type = SID_NAME_WKN_GRP;
349         ret &= test_LookupNames(b, tctx, handle, &tnames);
350
351         name.name.string = "NT AUTHORITY\\Authenticated Users";
352         name.sid_type = SID_NAME_WKN_GRP;
353         ret &= test_LookupNames(b, tctx, handle, &tnames);
354
355 #if 0
356         name.name.string = "NT AUTHORITY";
357         ret &= test_LookupNames(b, tctx, handle, &tnames);
358
359         name.name.string = "NT AUTHORITY\\";
360         ret &= test_LookupNames(b, tctx, handle, &tnames);
361 #endif
362
363         name.name.string = "BUILTIN\\";
364         name.sid_type = SID_NAME_DOMAIN;
365         ret &= test_LookupNames(b, tctx, handle, &tnames);
366
367         name.name.string = "BUILTIN\\Administrators";
368         name.sid_type = SID_NAME_ALIAS;
369         ret &= test_LookupNames(b, tctx, handle, &tnames);
370
371         name.name.string = "SYSTEM";
372         name.sid_type = SID_NAME_WKN_GRP;
373         ret &= test_LookupNames(b, tctx, handle, &tnames);
374
375         name.name.string = "Everyone";
376         name.sid_type = SID_NAME_WKN_GRP;
377         ret &= test_LookupNames(b, tctx, handle, &tnames);
378         return ret;
379 }
380
381 static bool test_LookupNames2(struct dcerpc_binding_handle *b,
382                               struct torture_context *tctx,
383                               struct policy_handle *handle,
384                               struct lsa_TransNameArray2 *tnames,
385                               bool check_result)
386 {
387         struct lsa_LookupNames2 r;
388         struct lsa_TransSidArray2 sids;
389         struct lsa_RefDomainList *domains = NULL;
390         struct lsa_String *names;
391         uint32_t *input_idx;
392         uint32_t count = 0;
393         int i;
394
395         torture_comment(tctx, "\nTesting LookupNames2 with %d names\n", tnames->count);
396
397         sids.count = 0;
398         sids.sids = NULL;
399
400         r.in.num_names = 0;
401
402         input_idx = talloc_array(tctx, uint32_t, tnames->count);
403         names = talloc_array(tctx, struct lsa_String, tnames->count);
404
405         for (i=0;i<tnames->count;i++) {
406                 if (tnames->names[i].sid_type != SID_NAME_UNKNOWN) {
407                         init_lsa_String(&names[r.in.num_names], tnames->names[i].name.string);
408                         input_idx[r.in.num_names] = i;
409                         r.in.num_names++;
410                 }
411         }
412
413         r.in.handle = handle;
414         r.in.names = names;
415         r.in.sids = &sids;
416         r.in.level = 1;
417         r.in.count = &count;
418         r.in.lookup_options = 0;
419         r.in.client_revision = 0;
420         r.out.count = &count;
421         r.out.sids = &sids;
422         r.out.domains = &domains;
423
424         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupNames2_r(b, tctx, &r),
425                 "LookupNames2 failed");
426         if (!NT_STATUS_IS_OK(r.out.result)) {
427                 torture_comment(tctx, "LookupNames2 failed - %s\n",
428                                 nt_errstr(r.out.result));
429                 return false;
430         }
431
432         if (check_result) {
433                 torture_assert_int_equal(tctx, count, sids.count,
434                         "unexpected number of results returned");
435                 if (sids.count > 0) {
436                         torture_assert(tctx, sids.sids, "invalid sid buffer");
437                 }
438         }
439
440         torture_comment(tctx, "\n");
441
442         return true;
443 }
444
445
446 static bool test_LookupNames3(struct dcerpc_binding_handle *b,
447                               struct torture_context *tctx,
448                               struct policy_handle *handle,
449                               struct lsa_TransNameArray2 *tnames,
450                               bool check_result)
451 {
452         struct lsa_LookupNames3 r;
453         struct lsa_TransSidArray3 sids;
454         struct lsa_RefDomainList *domains = NULL;
455         struct lsa_String *names;
456         uint32_t count = 0;
457         int i;
458         uint32_t *input_idx;
459
460         torture_comment(tctx, "\nTesting LookupNames3 with %d names\n", tnames->count);
461
462         sids.count = 0;
463         sids.sids = NULL;
464
465         r.in.num_names = 0;
466
467         input_idx = talloc_array(tctx, uint32_t, tnames->count);
468         names = talloc_array(tctx, struct lsa_String, tnames->count);
469         for (i=0;i<tnames->count;i++) {
470                 if (tnames->names[i].sid_type != SID_NAME_UNKNOWN) {
471                         init_lsa_String(&names[r.in.num_names], tnames->names[i].name.string);
472                         input_idx[r.in.num_names] = i;
473                         r.in.num_names++;
474                 }
475         }
476
477         r.in.handle = handle;
478         r.in.names = names;
479         r.in.sids = &sids;
480         r.in.level = 1;
481         r.in.count = &count;
482         r.in.lookup_options = 0;
483         r.in.client_revision = 0;
484         r.out.count = &count;
485         r.out.sids = &sids;
486         r.out.domains = &domains;
487
488         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupNames3_r(b, tctx, &r),
489                 "LookupNames3 failed");
490         if (!NT_STATUS_IS_OK(r.out.result)) {
491                 torture_comment(tctx, "LookupNames3 failed - %s\n",
492                                 nt_errstr(r.out.result));
493                 return false;
494         }
495
496         if (check_result) {
497                 torture_assert_int_equal(tctx, count, sids.count,
498                         "unexpected number of results returned");
499                 if (sids.count > 0) {
500                         torture_assert(tctx, sids.sids, "invalid sid buffer");
501                 }
502         }
503
504         torture_comment(tctx, "\n");
505
506         return true;
507 }
508
509 static bool test_LookupNames4(struct dcerpc_binding_handle *b,
510                               struct torture_context *tctx,
511                               struct lsa_TransNameArray2 *tnames,
512                               bool check_result)
513 {
514         struct lsa_LookupNames4 r;
515         struct lsa_TransSidArray3 sids;
516         struct lsa_RefDomainList *domains = NULL;
517         struct lsa_String *names;
518         uint32_t count = 0;
519         int i;
520         uint32_t *input_idx;
521
522         torture_comment(tctx, "\nTesting LookupNames4 with %d names\n", tnames->count);
523
524         sids.count = 0;
525         sids.sids = NULL;
526
527         r.in.num_names = 0;
528
529         input_idx = talloc_array(tctx, uint32_t, tnames->count);
530         names = talloc_array(tctx, struct lsa_String, tnames->count);
531         for (i=0;i<tnames->count;i++) {
532                 if (tnames->names[i].sid_type != SID_NAME_UNKNOWN) {
533                         init_lsa_String(&names[r.in.num_names], tnames->names[i].name.string);
534                         input_idx[r.in.num_names] = i;
535                         r.in.num_names++;
536                 }
537         }
538
539         r.in.num_names = tnames->count;
540         r.in.names = names;
541         r.in.sids = &sids;
542         r.in.level = 1;
543         r.in.count = &count;
544         r.in.lookup_options = 0;
545         r.in.client_revision = 0;
546         r.out.count = &count;
547         r.out.sids = &sids;
548         r.out.domains = &domains;
549
550         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupNames4_r(b, tctx, &r),
551                 "LookupNames4 failed");
552
553         torture_assert_ntstatus_ok(tctx,
554                                    r.out.result,
555                                    "LookupNames4 failed");
556
557         if (check_result) {
558                 torture_assert_int_equal(tctx, count, sids.count,
559                         "unexpected number of results returned");
560                 if (sids.count > 0) {
561                         torture_assert(tctx, sids.sids, "invalid sid buffer");
562                 }
563         }
564
565         torture_comment(tctx, "\n");
566
567         return true;
568 }
569
570 static bool test_LookupNames4_fail(struct dcerpc_binding_handle *b,
571                                    struct torture_context *tctx)
572 {
573         struct lsa_LookupNames4 r;
574         struct lsa_TransSidArray3 sids;
575         struct lsa_RefDomainList *domains = NULL;
576         struct lsa_String *names;
577         uint32_t count = 0;
578         NTSTATUS status;
579
580         torture_comment(tctx, "\nTesting LookupNames4_fail");
581
582         sids.count = 0;
583         sids.sids = NULL;
584
585         r.in.num_names = 0;
586
587         r.in.num_names = count;
588         r.in.names = names;
589         r.in.sids = &sids;
590         r.in.level = 1;
591         r.in.count = &count;
592         r.in.lookup_options = 0;
593         r.in.client_revision = 0;
594         r.out.count = &count;
595         r.out.sids = &sids;
596         r.out.domains = &domains;
597
598         status = dcerpc_lsa_LookupNames4_r(b, tctx, &r);
599         if (!NT_STATUS_IS_OK(status)) {
600                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
601                         torture_comment(tctx,
602                                         "LookupNames4 correctly returned with "
603                                         "status: %s\n",
604                                         nt_errstr(status));
605                         return true;
606                 }
607
608                 torture_assert_ntstatus_equal(tctx,
609                                               status,
610                                               NT_STATUS_ACCESS_DENIED,
611                                               "LookupNames4 return value should "
612                                               "be ACCESS_DENIED");
613                 return true;
614         }
615
616         if (!NT_STATUS_IS_OK(r.out.result)) {
617                 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) ||
618                     NT_STATUS_EQUAL(r.out.result, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
619                         torture_comment(tctx,
620                                         "LookupSids3 correctly returned with "
621                                         "result: %s\n",
622                                         nt_errstr(r.out.result));
623                         return true;
624                 }
625         }
626
627         torture_assert_ntstatus_equal(tctx,
628                                       r.out.result,
629                                       NT_STATUS_OK,
630                                       "LookupNames4 return value should be "
631                                       "ACCESS_DENIED");
632
633         return false;
634 }
635
636
637 static bool test_LookupSids(struct dcerpc_binding_handle *b,
638                             struct torture_context *tctx,
639                             struct policy_handle *handle,
640                             struct lsa_SidArray *sids)
641 {
642         struct lsa_LookupSids r;
643         struct lsa_TransNameArray names;
644         struct lsa_RefDomainList *domains = NULL;
645         uint32_t count = sids->num_sids;
646
647         torture_comment(tctx, "\nTesting LookupSids\n");
648
649         names.count = 0;
650         names.names = NULL;
651
652         r.in.handle = handle;
653         r.in.sids = sids;
654         r.in.names = &names;
655         r.in.level = 1;
656         r.in.count = &count;
657         r.out.count = &count;
658         r.out.names = &names;
659         r.out.domains = &domains;
660
661         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupSids_r(b, tctx, &r),
662                 "LookupSids failed");
663         if (!NT_STATUS_IS_OK(r.out.result) &&
664             !NT_STATUS_EQUAL(r.out.result, STATUS_SOME_UNMAPPED)) {
665                 torture_comment(tctx, "LookupSids failed - %s\n",
666                                 nt_errstr(r.out.result));
667                 return false;
668         }
669
670         torture_comment(tctx, "\n");
671
672         if (!test_LookupNames(b, tctx, handle, &names)) {
673                 return false;
674         }
675
676         return true;
677 }
678
679
680 static bool test_LookupSids2(struct dcerpc_binding_handle *b,
681                             struct torture_context *tctx,
682                             struct policy_handle *handle,
683                             struct lsa_SidArray *sids)
684 {
685         struct lsa_LookupSids2 r;
686         struct lsa_TransNameArray2 names;
687         struct lsa_RefDomainList *domains = NULL;
688         uint32_t count = sids->num_sids;
689
690         torture_comment(tctx, "\nTesting LookupSids2\n");
691
692         names.count = 0;
693         names.names = NULL;
694
695         r.in.handle = handle;
696         r.in.sids = sids;
697         r.in.names = &names;
698         r.in.level = 1;
699         r.in.count = &count;
700         r.in.lookup_options = 0;
701         r.in.client_revision = 0;
702         r.out.count = &count;
703         r.out.names = &names;
704         r.out.domains = &domains;
705
706         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupSids2_r(b, tctx, &r),
707                 "LookupSids2 failed");
708         if (!NT_STATUS_IS_OK(r.out.result) &&
709             !NT_STATUS_EQUAL(r.out.result, STATUS_SOME_UNMAPPED)) {
710                 torture_comment(tctx, "LookupSids2 failed - %s\n",
711                                 nt_errstr(r.out.result));
712                 return false;
713         }
714
715         torture_comment(tctx, "\n");
716
717         if (!test_LookupNames2(b, tctx, handle, &names, false)) {
718                 return false;
719         }
720
721         if (!test_LookupNames3(b, tctx, handle, &names, false)) {
722                 return false;
723         }
724
725         return true;
726 }
727
728 static bool test_LookupSids3(struct dcerpc_binding_handle *b,
729                             struct torture_context *tctx,
730                             struct lsa_SidArray *sids)
731 {
732         struct lsa_LookupSids3 r;
733         struct lsa_TransNameArray2 names;
734         struct lsa_RefDomainList *domains = NULL;
735         uint32_t count = sids->num_sids;
736
737         torture_comment(tctx, "\nTesting LookupSids3\n");
738
739         names.count = 0;
740         names.names = NULL;
741
742         r.in.sids = sids;
743         r.in.names = &names;
744         r.in.level = 1;
745         r.in.count = &count;
746         r.in.lookup_options = 0;
747         r.in.client_revision = 0;
748         r.out.domains = &domains;
749         r.out.count = &count;
750         r.out.names = &names;
751
752         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupSids3_r(b, tctx, &r),
753                 "LookupSids3 failed");
754
755         torture_assert_ntstatus_ok(tctx,
756                                    r.out.result,
757                                    "LookupSids3 failed");
758
759         torture_comment(tctx, "\n");
760
761         return true;
762 }
763
764 static bool test_LookupSids3_fail(struct dcerpc_binding_handle *b,
765                                   struct torture_context *tctx,
766                                   struct lsa_SidArray *sids)
767 {
768         struct lsa_LookupSids3 r;
769         struct lsa_TransNameArray2 names;
770         struct lsa_RefDomainList *domains = NULL;
771         uint32_t count = sids->num_sids;
772         NTSTATUS status;
773
774         torture_comment(tctx, "\nTesting LookupSids3\n");
775
776         names.count = 0;
777         names.names = NULL;
778
779         r.in.sids = sids;
780         r.in.names = &names;
781         r.in.level = 1;
782         r.in.count = &count;
783         r.in.lookup_options = 0;
784         r.in.client_revision = 0;
785         r.out.domains = &domains;
786         r.out.count = &count;
787         r.out.names = &names;
788
789         status = dcerpc_lsa_LookupSids3_r(b, tctx, &r);
790         if (!NT_STATUS_IS_OK(status)) {
791                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
792                         torture_comment(tctx,
793                                         "LookupSids3 correctly returned with "
794                                         "status: %s\n",
795                                         nt_errstr(status));
796                         return true;
797                 }
798
799                 torture_assert_ntstatus_equal(tctx,
800                                               status,
801                                               NT_STATUS_ACCESS_DENIED,
802                                               "LookupSids3 return value should "
803                                               "be ACCESS_DENIED");
804                 return true;
805         }
806
807         if (!NT_STATUS_IS_OK(r.out.result)) {
808                 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) ||
809                     NT_STATUS_EQUAL(r.out.result, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
810                         torture_comment(tctx,
811                                         "LookupNames4 correctly returned with "
812                                         "result: %s\n",
813                                         nt_errstr(r.out.result));
814                         return true;
815                 }
816         }
817
818         torture_assert_ntstatus_equal(tctx,
819                                       r.out.result,
820                                       NT_STATUS_OK,
821                                       "LookupSids3 return value should be "
822                                       "ACCESS_DENIED");
823
824         return false;
825 }
826
827 bool test_many_LookupSids(struct dcerpc_pipe *p,
828                           struct torture_context *tctx,
829                           struct policy_handle *handle)
830 {
831         uint32_t count;
832         struct lsa_SidArray sids;
833         int i;
834         struct dcerpc_binding_handle *b = p->binding_handle;
835
836         torture_comment(tctx, "\nTesting LookupSids with lots of SIDs\n");
837
838         sids.num_sids = 100;
839
840         sids.sids = talloc_array(tctx, struct lsa_SidPtr, sids.num_sids);
841
842         for (i=0; i<sids.num_sids; i++) {
843                 const char *sidstr = "S-1-5-32-545";
844                 sids.sids[i].sid = dom_sid_parse_talloc(tctx, sidstr);
845         }
846
847         count = sids.num_sids;
848
849         if (handle) {
850                 struct lsa_LookupSids r;
851                 struct lsa_TransNameArray names;
852                 struct lsa_RefDomainList *domains = NULL;
853                 names.count = 0;
854                 names.names = NULL;
855
856                 r.in.handle = handle;
857                 r.in.sids = &sids;
858                 r.in.names = &names;
859                 r.in.level = 1;
860                 r.in.count = &names.count;
861                 r.out.count = &count;
862                 r.out.names = &names;
863                 r.out.domains = &domains;
864
865                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupSids_r(b, tctx, &r),
866                         "LookupSids failed");
867                 if (!NT_STATUS_IS_OK(r.out.result)) {
868                         torture_comment(tctx, "LookupSids failed - %s\n",
869                                         nt_errstr(r.out.result));
870                         return false;
871                 }
872
873                 torture_comment(tctx, "\n");
874
875                 if (!test_LookupNames(b, tctx, handle, &names)) {
876                         return false;
877                 }
878         }
879
880         if (p->binding->transport == NCACN_NP) {
881                 if (!test_LookupSids3_fail(b, tctx, &sids)) {
882                         return false;
883                 }
884                 if (!test_LookupNames4_fail(b, tctx)) {
885                         return false;
886                 }
887         } else if (p->binding->transport == NCACN_IP_TCP) {
888                 struct lsa_TransNameArray2 names;
889
890                 names.count = 0;
891                 names.names = NULL;
892
893                 if (p->conn->security_state.auth_info->auth_type == DCERPC_AUTH_TYPE_SCHANNEL &&
894                    p->conn->security_state.auth_info->auth_level >= DCERPC_AUTH_LEVEL_INTEGRITY) {
895                         if (!test_LookupSids3(b, tctx, &sids)) {
896                                 return false;
897                         }
898                         if (!test_LookupNames4(b, tctx, &names, true)) {
899                                 return false;
900                         }
901                 } else {
902                         /*
903                          * If we don't have a secure channel these tests must
904                          * fail with ACCESS_DENIED.
905                          */
906                         if (!test_LookupSids3_fail(b, tctx, &sids)) {
907                                 return false;
908                         }
909                         if (!test_LookupNames4_fail(b, tctx)) {
910                                 return false;
911                         }
912                 }
913         }
914
915         torture_comment(tctx, "\n");
916
917
918
919         return true;
920 }
921
922 static void lookupsids_cb(struct tevent_req *subreq)
923 {
924         int *replies = (int *)tevent_req_callback_data_void(subreq);
925         NTSTATUS status;
926
927         status = dcerpc_lsa_LookupSids_r_recv(subreq, subreq);
928         TALLOC_FREE(subreq);
929         if (!NT_STATUS_IS_OK(status)) {
930                 printf("lookupsids returned %s\n", nt_errstr(status));
931                 *replies = -1;
932         }
933
934         if (*replies >= 0) {
935                 *replies += 1;
936         }
937 }
938
939 static bool test_LookupSids_async(struct dcerpc_binding_handle *b,
940                                   struct torture_context *tctx,
941                                   struct policy_handle *handle)
942 {
943         struct lsa_SidArray sids;
944         struct lsa_SidPtr sidptr;
945         uint32_t *count;
946         struct lsa_TransNameArray *names;
947         struct lsa_LookupSids *r;
948         struct lsa_RefDomainList *domains = NULL;
949         struct tevent_req **req;
950         int i, replies;
951         bool ret = true;
952         const int num_async_requests = 50;
953
954         count = talloc_array(tctx, uint32_t, num_async_requests);
955         names = talloc_array(tctx, struct lsa_TransNameArray, num_async_requests);
956         r = talloc_array(tctx, struct lsa_LookupSids, num_async_requests);
957
958         torture_comment(tctx, "\nTesting %d async lookupsids request\n", num_async_requests);
959
960         req = talloc_array(tctx, struct tevent_req *, num_async_requests);
961
962         sids.num_sids = 1;
963         sids.sids = &sidptr;
964         sidptr.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-545");
965
966         replies = 0;
967
968         for (i=0; i<num_async_requests; i++) {
969                 count[i] = 0;
970                 names[i].count = 0;
971                 names[i].names = NULL;
972
973                 r[i].in.handle = handle;
974                 r[i].in.sids = &sids;
975                 r[i].in.names = &names[i];
976                 r[i].in.level = 1;
977                 r[i].in.count = &names[i].count;
978                 r[i].out.count = &count[i];
979                 r[i].out.names = &names[i];
980                 r[i].out.domains = &domains;
981
982                 req[i] = dcerpc_lsa_LookupSids_r_send(tctx, tctx->ev, b, &r[i]);
983                 if (req[i] == NULL) {
984                         ret = false;
985                         break;
986                 }
987
988                 tevent_req_set_callback(req[i], lookupsids_cb, &replies);
989         }
990
991         while (replies >= 0 && replies < num_async_requests) {
992                 tevent_loop_once(tctx->ev);
993         }
994
995         talloc_free(req);
996
997         if (replies < 0) {
998                 ret = false;
999         }
1000
1001         return ret;
1002 }
1003
1004 static bool test_LookupPrivValue(struct dcerpc_binding_handle *b,
1005                                  struct torture_context *tctx,
1006                                  struct policy_handle *handle,
1007                                  struct lsa_String *name)
1008 {
1009         struct lsa_LookupPrivValue r;
1010         struct lsa_LUID luid;
1011
1012         r.in.handle = handle;
1013         r.in.name = name;
1014         r.out.luid = &luid;
1015
1016         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupPrivValue_r(b, tctx, &r),
1017                 "LookupPrivValue failed");
1018         if (!NT_STATUS_IS_OK(r.out.result)) {
1019                 torture_comment(tctx, "\nLookupPrivValue failed - %s\n",
1020                                 nt_errstr(r.out.result));
1021                 return false;
1022         }
1023
1024         return true;
1025 }
1026
1027 static bool test_LookupPrivName(struct dcerpc_binding_handle *b,
1028                                 struct torture_context *tctx,
1029                                 struct policy_handle *handle,
1030                                 struct lsa_LUID *luid)
1031 {
1032         struct lsa_LookupPrivName r;
1033         struct lsa_StringLarge *name = NULL;
1034
1035         r.in.handle = handle;
1036         r.in.luid = luid;
1037         r.out.name = &name;
1038
1039         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupPrivName_r(b, tctx, &r),
1040                 "LookupPrivName failed");
1041         if (!NT_STATUS_IS_OK(r.out.result)) {
1042                 torture_comment(tctx, "\nLookupPrivName failed - %s\n",
1043                                 nt_errstr(r.out.result));
1044                 return false;
1045         }
1046
1047         return true;
1048 }
1049
1050 static bool test_RemovePrivilegesFromAccount(struct dcerpc_binding_handle *b,
1051                                              struct torture_context *tctx,
1052                                              struct policy_handle *handle,
1053                                              struct policy_handle *acct_handle,
1054                                              struct lsa_LUID *luid)
1055 {
1056         struct lsa_RemovePrivilegesFromAccount r;
1057         struct lsa_PrivilegeSet privs;
1058         bool ret = true;
1059
1060         torture_comment(tctx, "\nTesting RemovePrivilegesFromAccount\n");
1061
1062         r.in.handle = acct_handle;
1063         r.in.remove_all = 0;
1064         r.in.privs = &privs;
1065
1066         privs.count = 1;
1067         privs.unknown = 0;
1068         privs.set = talloc_array(tctx, struct lsa_LUIDAttribute, 1);
1069         privs.set[0].luid = *luid;
1070         privs.set[0].attribute = 0;
1071
1072         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_RemovePrivilegesFromAccount_r(b, tctx, &r),
1073                 "RemovePrivilegesFromAccount failed");
1074         if (!NT_STATUS_IS_OK(r.out.result)) {
1075
1076                 struct lsa_LookupPrivName r_name;
1077                 struct lsa_StringLarge *name = NULL;
1078
1079                 r_name.in.handle = handle;
1080                 r_name.in.luid = luid;
1081                 r_name.out.name = &name;
1082
1083                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupPrivName_r(b, tctx, &r_name),
1084                         "LookupPrivName failed");
1085                 if (!NT_STATUS_IS_OK(r_name.out.result)) {
1086                         torture_comment(tctx, "\nLookupPrivName failed - %s\n",
1087                                         nt_errstr(r_name.out.result));
1088                         return false;
1089                 }
1090                 /* Windows 2008 does not allow this to be removed */
1091                 if (strcmp("SeAuditPrivilege", name->string) == 0) {
1092                         return ret;
1093                 }
1094
1095                 torture_comment(tctx, "RemovePrivilegesFromAccount failed to remove %s - %s\n",
1096                        name->string,
1097                        nt_errstr(r.out.result));
1098                 return false;
1099         }
1100
1101         return ret;
1102 }
1103
1104 static bool test_AddPrivilegesToAccount(struct dcerpc_binding_handle *b,
1105                                         struct torture_context *tctx,
1106                                         struct policy_handle *acct_handle,
1107                                         struct lsa_LUID *luid)
1108 {
1109         struct lsa_AddPrivilegesToAccount r;
1110         struct lsa_PrivilegeSet privs;
1111         bool ret = true;
1112
1113         torture_comment(tctx, "\nTesting AddPrivilegesToAccount\n");
1114
1115         r.in.handle = acct_handle;
1116         r.in.privs = &privs;
1117
1118         privs.count = 1;
1119         privs.unknown = 0;
1120         privs.set = talloc_array(tctx, struct lsa_LUIDAttribute, 1);
1121         privs.set[0].luid = *luid;
1122         privs.set[0].attribute = 0;
1123
1124         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_AddPrivilegesToAccount_r(b, tctx, &r),
1125                 "AddPrivilegesToAccount failed");
1126         if (!NT_STATUS_IS_OK(r.out.result)) {
1127                 torture_comment(tctx, "AddPrivilegesToAccount failed - %s\n",
1128                                 nt_errstr(r.out.result));
1129                 return false;
1130         }
1131
1132         return ret;
1133 }
1134
1135 static bool test_EnumPrivsAccount(struct dcerpc_binding_handle *b,
1136                                   struct torture_context *tctx,
1137                                   struct policy_handle *handle,
1138                                   struct policy_handle *acct_handle)
1139 {
1140         struct lsa_EnumPrivsAccount r;
1141         struct lsa_PrivilegeSet *privs = NULL;
1142         bool ret = true;
1143
1144         torture_comment(tctx, "\nTesting EnumPrivsAccount\n");
1145
1146         r.in.handle = acct_handle;
1147         r.out.privs = &privs;
1148
1149         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumPrivsAccount_r(b, tctx, &r),
1150                 "EnumPrivsAccount failed");
1151         if (!NT_STATUS_IS_OK(r.out.result)) {
1152                 torture_comment(tctx, "EnumPrivsAccount failed - %s\n",
1153                                 nt_errstr(r.out.result));
1154                 return false;
1155         }
1156
1157         if (privs && privs->count > 0) {
1158                 int i;
1159                 for (i=0;i<privs->count;i++) {
1160                         test_LookupPrivName(b, tctx, handle,
1161                                             &privs->set[i].luid);
1162                 }
1163
1164                 ret &= test_RemovePrivilegesFromAccount(b, tctx, handle, acct_handle,
1165                                                         &privs->set[0].luid);
1166                 ret &= test_AddPrivilegesToAccount(b, tctx, acct_handle,
1167                                                    &privs->set[0].luid);
1168         }
1169
1170         return ret;
1171 }
1172
1173 static bool test_GetSystemAccessAccount(struct dcerpc_binding_handle *b,
1174                                         struct torture_context *tctx,
1175                                         struct policy_handle *handle,
1176                                         struct policy_handle *acct_handle)
1177 {
1178         uint32_t access_mask;
1179         struct lsa_GetSystemAccessAccount r;
1180
1181         torture_comment(tctx, "\nTesting GetSystemAccessAccount\n");
1182
1183         r.in.handle = acct_handle;
1184         r.out.access_mask = &access_mask;
1185
1186         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetSystemAccessAccount_r(b, tctx, &r),
1187                 "GetSystemAccessAccount failed");
1188         if (!NT_STATUS_IS_OK(r.out.result)) {
1189                 torture_comment(tctx, "GetSystemAccessAccount failed - %s\n",
1190                                 nt_errstr(r.out.result));
1191                 return false;
1192         }
1193
1194         if (r.out.access_mask != NULL) {
1195                 torture_comment(tctx, "Rights:");
1196                 if (*(r.out.access_mask) & LSA_POLICY_MODE_INTERACTIVE)
1197                         torture_comment(tctx, " LSA_POLICY_MODE_INTERACTIVE");
1198                 if (*(r.out.access_mask) & LSA_POLICY_MODE_NETWORK)
1199                         torture_comment(tctx, " LSA_POLICY_MODE_NETWORK");
1200                 if (*(r.out.access_mask) & LSA_POLICY_MODE_BATCH)
1201                         torture_comment(tctx, " LSA_POLICY_MODE_BATCH");
1202                 if (*(r.out.access_mask) & LSA_POLICY_MODE_SERVICE)
1203                         torture_comment(tctx, " LSA_POLICY_MODE_SERVICE");
1204                 if (*(r.out.access_mask) & LSA_POLICY_MODE_PROXY)
1205                         torture_comment(tctx, " LSA_POLICY_MODE_PROXY");
1206                 if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_INTERACTIVE)
1207                         torture_comment(tctx, " LSA_POLICY_MODE_DENY_INTERACTIVE");
1208                 if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_NETWORK)
1209                         torture_comment(tctx, " LSA_POLICY_MODE_DENY_NETWORK");
1210                 if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_BATCH)
1211                         torture_comment(tctx, " LSA_POLICY_MODE_DENY_BATCH");
1212                 if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_SERVICE)
1213                         torture_comment(tctx, " LSA_POLICY_MODE_DENY_SERVICE");
1214                 if (*(r.out.access_mask) & LSA_POLICY_MODE_REMOTE_INTERACTIVE)
1215                         torture_comment(tctx, " LSA_POLICY_MODE_REMOTE_INTERACTIVE");
1216                 if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_REMOTE_INTERACTIVE)
1217                         torture_comment(tctx, " LSA_POLICY_MODE_DENY_REMOTE_INTERACTIVE");
1218                 if (*(r.out.access_mask) & LSA_POLICY_MODE_ALL)
1219                         torture_comment(tctx, " LSA_POLICY_MODE_ALL");
1220                 if (*(r.out.access_mask) & LSA_POLICY_MODE_ALL_NT4)
1221                         torture_comment(tctx, " LSA_POLICY_MODE_ALL_NT4");
1222                 torture_comment(tctx, "\n");
1223         }
1224
1225         return true;
1226 }
1227
1228 static bool test_Delete(struct dcerpc_binding_handle *b,
1229                         struct torture_context *tctx,
1230                         struct policy_handle *handle)
1231 {
1232         struct lsa_Delete r;
1233
1234         torture_comment(tctx, "\nTesting Delete\n");
1235
1236         r.in.handle = handle;
1237         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Delete_r(b, tctx, &r),
1238                 "Delete failed");
1239         if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
1240                 torture_comment(tctx, "Delete should have failed NT_STATUS_NOT_SUPPORTED - %s\n", nt_errstr(r.out.result));
1241                 return false;
1242         }
1243
1244         return true;
1245 }
1246
1247 static bool test_DeleteObject(struct dcerpc_binding_handle *b,
1248                               struct torture_context *tctx,
1249                               struct policy_handle *handle)
1250 {
1251         struct lsa_DeleteObject r;
1252
1253         torture_comment(tctx, "\nTesting DeleteObject\n");
1254
1255         r.in.handle = handle;
1256         r.out.handle = handle;
1257         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_DeleteObject_r(b, tctx, &r),
1258                 "DeleteObject failed");
1259         if (!NT_STATUS_IS_OK(r.out.result)) {
1260                 torture_comment(tctx, "DeleteObject failed - %s\n",
1261                                 nt_errstr(r.out.result));
1262                 return false;
1263         }
1264
1265         return true;
1266 }
1267
1268
1269 static bool test_CreateAccount(struct dcerpc_binding_handle *b,
1270                                struct torture_context *tctx,
1271                                struct policy_handle *handle)
1272 {
1273         struct lsa_CreateAccount r;
1274         struct dom_sid2 *newsid;
1275         struct policy_handle acct_handle;
1276
1277         newsid = dom_sid_parse_talloc(tctx, "S-1-5-12349876-4321-2854");
1278
1279         torture_comment(tctx, "\nTesting CreateAccount\n");
1280
1281         r.in.handle = handle;
1282         r.in.sid = newsid;
1283         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1284         r.out.acct_handle = &acct_handle;
1285
1286         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CreateAccount_r(b, tctx, &r),
1287                 "CreateAccount failed");
1288         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_OBJECT_NAME_COLLISION)) {
1289                 struct lsa_OpenAccount r_o;
1290                 r_o.in.handle = handle;
1291                 r_o.in.sid = newsid;
1292                 r_o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1293                 r_o.out.acct_handle = &acct_handle;
1294
1295                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(b, tctx, &r_o),
1296                         "OpenAccount failed");
1297                 if (!NT_STATUS_IS_OK(r_o.out.result)) {
1298                         torture_comment(tctx, "OpenAccount failed - %s\n",
1299                                         nt_errstr(r_o.out.result));
1300                         return false;
1301                 }
1302         } else if (!NT_STATUS_IS_OK(r.out.result)) {
1303                 torture_comment(tctx, "CreateAccount failed - %s\n",
1304                                 nt_errstr(r.out.result));
1305                 return false;
1306         }
1307
1308         if (!test_Delete(b, tctx, &acct_handle)) {
1309                 return false;
1310         }
1311
1312         if (!test_DeleteObject(b, tctx, &acct_handle)) {
1313                 return false;
1314         }
1315
1316         return true;
1317 }
1318
1319 static bool test_DeleteTrustedDomain(struct dcerpc_binding_handle *b,
1320                                      struct torture_context *tctx,
1321                                      struct policy_handle *handle,
1322                                      struct lsa_StringLarge name)
1323 {
1324         struct lsa_OpenTrustedDomainByName r;
1325         struct policy_handle trustdom_handle;
1326
1327         r.in.handle = handle;
1328         r.in.name.string = name.string;
1329         r.in.access_mask = SEC_STD_DELETE;
1330         r.out.trustdom_handle = &trustdom_handle;
1331
1332         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenTrustedDomainByName_r(b, tctx, &r),
1333                 "OpenTrustedDomainByName failed");
1334         if (!NT_STATUS_IS_OK(r.out.result)) {
1335                 torture_comment(tctx, "OpenTrustedDomainByName failed - %s\n", nt_errstr(r.out.result));
1336                 return false;
1337         }
1338
1339         if (!test_Delete(b, tctx, &trustdom_handle)) {
1340                 return false;
1341         }
1342
1343         if (!test_DeleteObject(b, tctx, &trustdom_handle)) {
1344                 return false;
1345         }
1346
1347         return true;
1348 }
1349
1350 static bool test_DeleteTrustedDomainBySid(struct dcerpc_binding_handle *b,
1351                                           struct torture_context *tctx,
1352                                           struct policy_handle *handle,
1353                                           struct dom_sid *sid)
1354 {
1355         struct lsa_DeleteTrustedDomain r;
1356
1357         r.in.handle = handle;
1358         r.in.dom_sid = sid;
1359
1360         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_DeleteTrustedDomain_r(b, tctx, &r),
1361                 "DeleteTrustedDomain failed");
1362         if (!NT_STATUS_IS_OK(r.out.result)) {
1363                 torture_comment(tctx, "DeleteTrustedDomain failed - %s\n", nt_errstr(r.out.result));
1364                 return false;
1365         }
1366
1367         return true;
1368 }
1369
1370
1371 static bool test_CreateSecret(struct dcerpc_pipe *p,
1372                               struct torture_context *tctx,
1373                               struct policy_handle *handle)
1374 {
1375         NTSTATUS status;
1376         struct lsa_CreateSecret r;
1377         struct lsa_OpenSecret r2;
1378         struct lsa_SetSecret r3;
1379         struct lsa_QuerySecret r4;
1380         struct lsa_SetSecret r5;
1381         struct lsa_QuerySecret r6;
1382         struct lsa_SetSecret r7;
1383         struct lsa_QuerySecret r8;
1384         struct policy_handle sec_handle, sec_handle2, sec_handle3;
1385         struct lsa_DeleteObject d_o;
1386         struct lsa_DATA_BUF buf1;
1387         struct lsa_DATA_BUF_PTR bufp1;
1388         struct lsa_DATA_BUF_PTR bufp2;
1389         DATA_BLOB enc_key;
1390         bool ret = true;
1391         DATA_BLOB session_key;
1392         NTTIME old_mtime, new_mtime;
1393         DATA_BLOB blob1;
1394         const char *secret1 = "abcdef12345699qwerty";
1395         char *secret2;
1396         const char *secret3 = "ABCDEF12345699QWERTY";
1397         char *secret4;
1398         const char *secret5 = "NEW-SAMBA4-SECRET";
1399         char *secret6;
1400         char *secname[2];
1401         int i;
1402         const int LOCAL = 0;
1403         const int GLOBAL = 1;
1404         struct dcerpc_binding_handle *b = p->binding_handle;
1405
1406         secname[LOCAL] = talloc_asprintf(tctx, "torturesecret-%u", (unsigned int)random());
1407         secname[GLOBAL] = talloc_asprintf(tctx, "G$torturesecret-%u", (unsigned int)random());
1408
1409         for (i=0; i< 2; i++) {
1410                 torture_comment(tctx, "\nTesting CreateSecret of %s\n", secname[i]);
1411
1412                 init_lsa_String(&r.in.name, secname[i]);
1413
1414                 r.in.handle = handle;
1415                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1416                 r.out.sec_handle = &sec_handle;
1417
1418                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CreateSecret_r(b, tctx, &r),
1419                         "CreateSecret failed");
1420                 if (!NT_STATUS_IS_OK(r.out.result)) {
1421                         torture_comment(tctx, "CreateSecret failed - %s\n", nt_errstr(r.out.result));
1422                         return false;
1423                 }
1424
1425                 r.in.handle = handle;
1426                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1427                 r.out.sec_handle = &sec_handle3;
1428
1429                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CreateSecret_r(b, tctx, &r),
1430                         "CreateSecret failed");
1431                 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_OBJECT_NAME_COLLISION)) {
1432                         torture_comment(tctx, "CreateSecret should have failed OBJECT_NAME_COLLISION - %s\n", nt_errstr(r.out.result));
1433                         return false;
1434                 }
1435
1436                 r2.in.handle = handle;
1437                 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1438                 r2.in.name = r.in.name;
1439                 r2.out.sec_handle = &sec_handle2;
1440
1441                 torture_comment(tctx, "Testing OpenSecret\n");
1442
1443                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenSecret_r(b, tctx, &r2),
1444                         "OpenSecret failed");
1445                 if (!NT_STATUS_IS_OK(r2.out.result)) {
1446                         torture_comment(tctx, "OpenSecret failed - %s\n", nt_errstr(r2.out.result));
1447                         return false;
1448                 }
1449
1450                 status = dcerpc_fetch_session_key(p, &session_key);
1451                 if (!NT_STATUS_IS_OK(status)) {
1452                         torture_comment(tctx, "dcerpc_fetch_session_key failed - %s\n", nt_errstr(status));
1453                         return false;
1454                 }
1455
1456                 enc_key = sess_encrypt_string(secret1, &session_key);
1457
1458                 r3.in.sec_handle = &sec_handle;
1459                 r3.in.new_val = &buf1;
1460                 r3.in.old_val = NULL;
1461                 r3.in.new_val->data = enc_key.data;
1462                 r3.in.new_val->length = enc_key.length;
1463                 r3.in.new_val->size = enc_key.length;
1464
1465                 torture_comment(tctx, "Testing SetSecret\n");
1466
1467                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_SetSecret_r(b, tctx, &r3),
1468                         "SetSecret failed");
1469                 if (!NT_STATUS_IS_OK(r3.out.result)) {
1470                         torture_comment(tctx, "SetSecret failed - %s\n", nt_errstr(r3.out.result));
1471                         return false;
1472                 }
1473
1474                 r3.in.sec_handle = &sec_handle;
1475                 r3.in.new_val = &buf1;
1476                 r3.in.old_val = NULL;
1477                 r3.in.new_val->data = enc_key.data;
1478                 r3.in.new_val->length = enc_key.length;
1479                 r3.in.new_val->size = enc_key.length;
1480
1481                 /* break the encrypted data */
1482                 enc_key.data[0]++;
1483
1484                 torture_comment(tctx, "Testing SetSecret with broken key\n");
1485
1486                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_SetSecret_r(b, tctx, &r3),
1487                         "SetSecret failed");
1488                 if (!NT_STATUS_EQUAL(r3.out.result, NT_STATUS_UNKNOWN_REVISION)) {
1489                         torture_comment(tctx, "SetSecret should have failed UNKNOWN_REVISION - %s\n", nt_errstr(r3.out.result));
1490                         ret = false;
1491                 }
1492
1493                 data_blob_free(&enc_key);
1494
1495                 ZERO_STRUCT(new_mtime);
1496                 ZERO_STRUCT(old_mtime);
1497
1498                 /* fetch the secret back again */
1499                 r4.in.sec_handle = &sec_handle;
1500                 r4.in.new_val = &bufp1;
1501                 r4.in.new_mtime = &new_mtime;
1502                 r4.in.old_val = NULL;
1503                 r4.in.old_mtime = NULL;
1504
1505                 bufp1.buf = NULL;
1506
1507                 torture_comment(tctx, "Testing QuerySecret\n");
1508                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QuerySecret_r(b, tctx, &r4),
1509                         "QuerySecret failed");
1510                 if (!NT_STATUS_IS_OK(r4.out.result)) {
1511                         torture_comment(tctx, "QuerySecret failed - %s\n", nt_errstr(r4.out.result));
1512                         ret = false;
1513                 } else {
1514                         if (r4.out.new_val == NULL || r4.out.new_val->buf == NULL) {
1515                                 torture_comment(tctx, "No secret buffer returned\n");
1516                                 ret = false;
1517                         } else {
1518                                 blob1.data = r4.out.new_val->buf->data;
1519                                 blob1.length = r4.out.new_val->buf->size;
1520
1521                                 secret2 = sess_decrypt_string(tctx,
1522                                                               &blob1, &session_key);
1523
1524                                 if (strcmp(secret1, secret2) != 0) {
1525                                         torture_comment(tctx, "Returned secret (r4) '%s' doesn't match '%s'\n",
1526                                                secret2, secret1);
1527                                         ret = false;
1528                                 }
1529                         }
1530                 }
1531
1532                 enc_key = sess_encrypt_string(secret3, &session_key);
1533
1534                 r5.in.sec_handle = &sec_handle;
1535                 r5.in.new_val = &buf1;
1536                 r5.in.old_val = NULL;
1537                 r5.in.new_val->data = enc_key.data;
1538                 r5.in.new_val->length = enc_key.length;
1539                 r5.in.new_val->size = enc_key.length;
1540
1541
1542                 smb_msleep(200);
1543                 torture_comment(tctx, "Testing SetSecret (existing value should move to old)\n");
1544
1545                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_SetSecret_r(b, tctx, &r5),
1546                         "SetSecret failed");
1547                 if (!NT_STATUS_IS_OK(r5.out.result)) {
1548                         torture_comment(tctx, "SetSecret failed - %s\n", nt_errstr(r5.out.result));
1549                         ret = false;
1550                 }
1551
1552                 data_blob_free(&enc_key);
1553
1554                 ZERO_STRUCT(new_mtime);
1555                 ZERO_STRUCT(old_mtime);
1556
1557                 /* fetch the secret back again */
1558                 r6.in.sec_handle = &sec_handle;
1559                 r6.in.new_val = &bufp1;
1560                 r6.in.new_mtime = &new_mtime;
1561                 r6.in.old_val = &bufp2;
1562                 r6.in.old_mtime = &old_mtime;
1563
1564                 bufp1.buf = NULL;
1565                 bufp2.buf = NULL;
1566
1567                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QuerySecret_r(b, tctx, &r6),
1568                         "QuerySecret failed");
1569                 if (!NT_STATUS_IS_OK(r6.out.result)) {
1570                         torture_comment(tctx, "QuerySecret failed - %s\n", nt_errstr(r6.out.result));
1571                         ret = false;
1572                         secret4 = NULL;
1573                 } else {
1574
1575                         if (r6.out.new_val->buf == NULL || r6.out.old_val->buf == NULL
1576                                 || r6.out.new_mtime == NULL || r6.out.old_mtime == NULL) {
1577                                 torture_comment(tctx, "Both secret buffers and both times not returned\n");
1578                                 ret = false;
1579                                 secret4 = NULL;
1580                         } else {
1581                                 blob1.data = r6.out.new_val->buf->data;
1582                                 blob1.length = r6.out.new_val->buf->size;
1583
1584                                 secret4 = sess_decrypt_string(tctx,
1585                                                               &blob1, &session_key);
1586
1587                                 if (strcmp(secret3, secret4) != 0) {
1588                                         torture_comment(tctx, "Returned NEW secret %s doesn't match %s\n", secret4, secret3);
1589                                         ret = false;
1590                                 }
1591
1592                                 blob1.data = r6.out.old_val->buf->data;
1593                                 blob1.length = r6.out.old_val->buf->length;
1594
1595                                 secret2 = sess_decrypt_string(tctx,
1596                                                               &blob1, &session_key);
1597
1598                                 if (strcmp(secret1, secret2) != 0) {
1599                                         torture_comment(tctx, "Returned OLD secret %s doesn't match %s\n", secret2, secret1);
1600                                         ret = false;
1601                                 }
1602
1603                                 if (*r6.out.new_mtime == *r6.out.old_mtime) {
1604                                         torture_comment(tctx, "Returned secret (r6-%d) %s must not have same mtime for both secrets: %s != %s\n",
1605                                                i,
1606                                                secname[i],
1607                                                nt_time_string(tctx, *r6.out.old_mtime),
1608                                                nt_time_string(tctx, *r6.out.new_mtime));
1609                                         ret = false;
1610                                 }
1611                         }
1612                 }
1613
1614                 enc_key = sess_encrypt_string(secret5, &session_key);
1615
1616                 r7.in.sec_handle = &sec_handle;
1617                 r7.in.old_val = &buf1;
1618                 r7.in.old_val->data = enc_key.data;
1619                 r7.in.old_val->length = enc_key.length;
1620                 r7.in.old_val->size = enc_key.length;
1621                 r7.in.new_val = NULL;
1622
1623                 torture_comment(tctx, "Testing SetSecret of old Secret only\n");
1624
1625                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_SetSecret_r(b, tctx, &r7),
1626                         "SetSecret failed");
1627                 if (!NT_STATUS_IS_OK(r7.out.result)) {
1628                         torture_comment(tctx, "SetSecret failed - %s\n", nt_errstr(r7.out.result));
1629                         ret = false;
1630                 }
1631
1632                 data_blob_free(&enc_key);
1633
1634                 /* fetch the secret back again */
1635                 r8.in.sec_handle = &sec_handle;
1636                 r8.in.new_val = &bufp1;
1637                 r8.in.new_mtime = &new_mtime;
1638                 r8.in.old_val = &bufp2;
1639                 r8.in.old_mtime = &old_mtime;
1640
1641                 bufp1.buf = NULL;
1642                 bufp2.buf = NULL;
1643
1644                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QuerySecret_r(b, tctx, &r8),
1645                         "QuerySecret failed");
1646                 if (!NT_STATUS_IS_OK(r8.out.result)) {
1647                         torture_comment(tctx, "QuerySecret failed - %s\n", nt_errstr(r8.out.result));
1648                         ret = false;
1649                 } else {
1650                         if (!r8.out.new_val || !r8.out.old_val) {
1651                                 torture_comment(tctx, "in/out pointers not returned, despite being set on in for QuerySecret\n");
1652                                 ret = false;
1653                         } else if (r8.out.new_val->buf != NULL) {
1654                                 torture_comment(tctx, "NEW secret buffer must not be returned after OLD set\n");
1655                                 ret = false;
1656                         } else if (r8.out.old_val->buf == NULL) {
1657                                 torture_comment(tctx, "OLD secret buffer was not returned after OLD set\n");
1658                                 ret = false;
1659                         } else if (r8.out.new_mtime == NULL || r8.out.old_mtime == NULL) {
1660                                 torture_comment(tctx, "Both times not returned after OLD set\n");
1661                                 ret = false;
1662                         } else {
1663                                 blob1.data = r8.out.old_val->buf->data;
1664                                 blob1.length = r8.out.old_val->buf->size;
1665
1666                                 secret6 = sess_decrypt_string(tctx,
1667                                                               &blob1, &session_key);
1668
1669                                 if (strcmp(secret5, secret6) != 0) {
1670                                         torture_comment(tctx, "Returned OLD secret %s doesn't match %s\n", secret5, secret6);
1671                                         ret = false;
1672                                 }
1673
1674                                 if (*r8.out.new_mtime != *r8.out.old_mtime) {
1675                                         torture_comment(tctx, "Returned secret (r8) %s did not had same mtime for both secrets: %s != %s\n",
1676                                                secname[i],
1677                                                nt_time_string(tctx, *r8.out.old_mtime),
1678                                                nt_time_string(tctx, *r8.out.new_mtime));
1679                                         ret = false;
1680                                 }
1681                         }
1682                 }
1683
1684                 if (!test_Delete(b, tctx, &sec_handle)) {
1685                         ret = false;
1686                 }
1687
1688                 if (!test_DeleteObject(b, tctx, &sec_handle)) {
1689                         return false;
1690                 }
1691
1692                 d_o.in.handle = &sec_handle2;
1693                 d_o.out.handle = &sec_handle2;
1694                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_DeleteObject_r(b, tctx, &d_o),
1695                         "DeleteObject failed");
1696                 if (!NT_STATUS_EQUAL(d_o.out.result, NT_STATUS_INVALID_HANDLE)) {
1697                         torture_comment(tctx, "Second delete expected INVALID_HANDLE - %s\n", nt_errstr(d_o.out.result));
1698                         ret = false;
1699                 } else {
1700
1701                         torture_comment(tctx, "Testing OpenSecret of just-deleted secret\n");
1702
1703                         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenSecret_r(b, tctx, &r2),
1704                                 "OpenSecret failed");
1705                         if (!NT_STATUS_EQUAL(r2.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
1706                                 torture_comment(tctx, "OpenSecret expected OBJECT_NAME_NOT_FOUND - %s\n", nt_errstr(r2.out.result));
1707                                 ret = false;
1708                         }
1709                 }
1710
1711         }
1712
1713         return ret;
1714 }
1715
1716
1717 static bool test_EnumAccountRights(struct dcerpc_binding_handle *b,
1718                                    struct torture_context *tctx,
1719                                    struct policy_handle *acct_handle,
1720                                    struct dom_sid *sid)
1721 {
1722         struct lsa_EnumAccountRights r;
1723         struct lsa_RightSet rights;
1724
1725         torture_comment(tctx, "\nTesting EnumAccountRights\n");
1726
1727         r.in.handle = acct_handle;
1728         r.in.sid = sid;
1729         r.out.rights = &rights;
1730
1731         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(b, tctx, &r),
1732                 "EnumAccountRights failed");
1733         if (!NT_STATUS_IS_OK(r.out.result)) {
1734                 torture_comment(tctx, "EnumAccountRights of %s failed - %s\n",
1735                        dom_sid_string(tctx, sid), nt_errstr(r.out.result));
1736                 return false;
1737         }
1738
1739         return true;
1740 }
1741
1742
1743 static bool test_QuerySecurity(struct dcerpc_binding_handle *b,
1744                              struct torture_context *tctx,
1745                              struct policy_handle *handle,
1746                              struct policy_handle *acct_handle)
1747 {
1748         struct lsa_QuerySecurity r;
1749         struct sec_desc_buf *sdbuf = NULL;
1750
1751         if (torture_setting_bool(tctx, "samba4", false)) {
1752                 torture_comment(tctx, "\nskipping QuerySecurity test against Samba4\n");
1753                 return true;
1754         }
1755
1756         torture_comment(tctx, "\nTesting QuerySecurity\n");
1757
1758         r.in.handle = acct_handle;
1759         r.in.sec_info = SECINFO_OWNER |
1760                         SECINFO_GROUP |
1761                         SECINFO_DACL;
1762         r.out.sdbuf = &sdbuf;
1763
1764         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QuerySecurity_r(b, tctx, &r),
1765                 "QuerySecurity failed");
1766         if (!NT_STATUS_IS_OK(r.out.result)) {
1767                 torture_comment(tctx, "QuerySecurity failed - %s\n", nt_errstr(r.out.result));
1768                 return false;
1769         }
1770
1771         return true;
1772 }
1773
1774 static bool test_OpenAccount(struct dcerpc_binding_handle *b,
1775                              struct torture_context *tctx,
1776                              struct policy_handle *handle,
1777                              struct dom_sid *sid)
1778 {
1779         struct lsa_OpenAccount r;
1780         struct policy_handle acct_handle;
1781
1782         torture_comment(tctx, "\nTesting OpenAccount\n");
1783
1784         r.in.handle = handle;
1785         r.in.sid = sid;
1786         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1787         r.out.acct_handle = &acct_handle;
1788
1789         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(b, tctx, &r),
1790                 "OpenAccount failed");
1791         if (!NT_STATUS_IS_OK(r.out.result)) {
1792                 torture_comment(tctx, "OpenAccount failed - %s\n", nt_errstr(r.out.result));
1793                 return false;
1794         }
1795
1796         if (!test_EnumPrivsAccount(b, tctx, handle, &acct_handle)) {
1797                 return false;
1798         }
1799
1800         if (!test_GetSystemAccessAccount(b, tctx, handle, &acct_handle)) {
1801                 return false;
1802         }
1803
1804         if (!test_QuerySecurity(b, tctx, handle, &acct_handle)) {
1805                 return false;
1806         }
1807
1808         return true;
1809 }
1810
1811 static bool test_EnumAccounts(struct dcerpc_binding_handle *b,
1812                               struct torture_context *tctx,
1813                               struct policy_handle *handle)
1814 {
1815         struct lsa_EnumAccounts r;
1816         struct lsa_SidArray sids1, sids2;
1817         uint32_t resume_handle = 0;
1818         int i;
1819         bool ret = true;
1820
1821         torture_comment(tctx, "\nTesting EnumAccounts\n");
1822
1823         r.in.handle = handle;
1824         r.in.resume_handle = &resume_handle;
1825         r.in.num_entries = 100;
1826         r.out.resume_handle = &resume_handle;
1827         r.out.sids = &sids1;
1828
1829         resume_handle = 0;
1830         while (true) {
1831                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(b, tctx, &r),
1832                         "EnumAccounts failed");
1833                 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES)) {
1834                         break;
1835                 }
1836                 if (!NT_STATUS_IS_OK(r.out.result)) {
1837                         torture_comment(tctx, "EnumAccounts failed - %s\n", nt_errstr(r.out.result));
1838                         return false;
1839                 }
1840
1841                 if (!test_LookupSids(b, tctx, handle, &sids1)) {
1842                         return false;
1843                 }
1844
1845                 if (!test_LookupSids2(b, tctx, handle, &sids1)) {
1846                         return false;
1847                 }
1848
1849                 /* Can't test lookupSids3 here, as clearly we must not
1850                  * be on schannel, or we would not be able to do the
1851                  * rest */
1852
1853                 torture_comment(tctx, "Testing all accounts\n");
1854                 for (i=0;i<sids1.num_sids;i++) {
1855                         ret &= test_OpenAccount(b, tctx, handle, sids1.sids[i].sid);
1856                         ret &= test_EnumAccountRights(b, tctx, handle, sids1.sids[i].sid);
1857                 }
1858                 torture_comment(tctx, "\n");
1859         }
1860
1861         if (sids1.num_sids < 3) {
1862                 return ret;
1863         }
1864
1865         torture_comment(tctx, "Trying EnumAccounts partial listing (asking for 1 at 2)\n");
1866         resume_handle = 2;
1867         r.in.num_entries = 1;
1868         r.out.sids = &sids2;
1869
1870         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(b, tctx, &r),
1871                 "EnumAccounts failed");
1872         if (!NT_STATUS_IS_OK(r.out.result)) {
1873                 torture_comment(tctx, "EnumAccounts failed - %s\n", nt_errstr(r.out.result));
1874                 return false;
1875         }
1876
1877         if (sids2.num_sids != 1) {
1878                 torture_comment(tctx, "Returned wrong number of entries (%d)\n", sids2.num_sids);
1879                 return false;
1880         }
1881
1882         return true;
1883 }
1884
1885 static bool test_LookupPrivDisplayName(struct dcerpc_binding_handle *b,
1886                                        struct torture_context *tctx,
1887                                        struct policy_handle *handle,
1888                                        struct lsa_String *priv_name)
1889 {
1890         struct lsa_LookupPrivDisplayName r;
1891         /* produce a reasonable range of language output without screwing up
1892            terminals */
1893         uint16_t language_id = (random() % 4) + 0x409;
1894         uint16_t returned_language_id = 0;
1895         struct lsa_StringLarge *disp_name = NULL;
1896
1897         torture_comment(tctx, "\nTesting LookupPrivDisplayName(%s)\n", priv_name->string);
1898
1899         r.in.handle = handle;
1900         r.in.name = priv_name;
1901         r.in.language_id = language_id;
1902         r.in.language_id_sys = 0;
1903         r.out.returned_language_id = &returned_language_id;
1904         r.out.disp_name = &disp_name;
1905
1906         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupPrivDisplayName_r(b, tctx, &r),
1907                 "LookupPrivDisplayName failed");
1908         if (!NT_STATUS_IS_OK(r.out.result)) {
1909                 torture_comment(tctx, "LookupPrivDisplayName failed - %s\n", nt_errstr(r.out.result));
1910                 return false;
1911         }
1912         torture_comment(tctx, "%s -> \"%s\"  (language 0x%x/0x%x)\n",
1913                priv_name->string, disp_name->string,
1914                r.in.language_id, *r.out.returned_language_id);
1915
1916         return true;
1917 }
1918
1919 static bool test_EnumAccountsWithUserRight(struct dcerpc_binding_handle *b,
1920                                            struct torture_context *tctx,
1921                                            struct policy_handle *handle,
1922                                            struct lsa_String *priv_name)
1923 {
1924         struct lsa_EnumAccountsWithUserRight r;
1925         struct lsa_SidArray sids;
1926
1927         ZERO_STRUCT(sids);
1928
1929         torture_comment(tctx, "\nTesting EnumAccountsWithUserRight(%s)\n", priv_name->string);
1930
1931         r.in.handle = handle;
1932         r.in.name = priv_name;
1933         r.out.sids = &sids;
1934
1935         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountsWithUserRight_r(b, tctx, &r),
1936                 "EnumAccountsWithUserRight failed");
1937
1938         /* NT_STATUS_NO_MORE_ENTRIES means noone has this privilege */
1939         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES)) {
1940                 return true;
1941         }
1942
1943         if (!NT_STATUS_IS_OK(r.out.result)) {
1944                 torture_comment(tctx, "EnumAccountsWithUserRight failed - %s\n", nt_errstr(r.out.result));
1945                 return false;
1946         }
1947
1948         return true;
1949 }
1950
1951
1952 static bool test_EnumPrivs(struct dcerpc_binding_handle *b,
1953                            struct torture_context *tctx,
1954                            struct policy_handle *handle)
1955 {
1956         struct lsa_EnumPrivs r;
1957         struct lsa_PrivArray privs1;
1958         uint32_t resume_handle = 0;
1959         int i;
1960         bool ret = true;
1961
1962         torture_comment(tctx, "\nTesting EnumPrivs\n");
1963
1964         r.in.handle = handle;
1965         r.in.resume_handle = &resume_handle;
1966         r.in.max_count = 100;
1967         r.out.resume_handle = &resume_handle;
1968         r.out.privs = &privs1;
1969
1970         resume_handle = 0;
1971         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumPrivs_r(b, tctx, &r),
1972                 "EnumPrivs failed");
1973         if (!NT_STATUS_IS_OK(r.out.result)) {
1974                 torture_comment(tctx, "EnumPrivs failed - %s\n", nt_errstr(r.out.result));
1975                 return false;
1976         }
1977
1978         for (i = 0; i< privs1.count; i++) {
1979                 test_LookupPrivDisplayName(b, tctx, handle, (struct lsa_String *)&privs1.privs[i].name);
1980                 test_LookupPrivValue(b, tctx, handle, (struct lsa_String *)&privs1.privs[i].name);
1981                 if (!test_EnumAccountsWithUserRight(b, tctx, handle, (struct lsa_String *)&privs1.privs[i].name)) {
1982                         ret = false;
1983                 }
1984         }
1985
1986         return ret;
1987 }
1988
1989 static bool test_QueryForestTrustInformation(struct dcerpc_binding_handle *b,
1990                                              struct torture_context *tctx,
1991                                              struct policy_handle *handle,
1992                                              const char *trusted_domain_name)
1993 {
1994         bool ret = true;
1995         struct lsa_lsaRQueryForestTrustInformation r;
1996         struct lsa_String string;
1997         struct lsa_ForestTrustInformation info, *info_ptr;
1998
1999         torture_comment(tctx, "\nTesting lsaRQueryForestTrustInformation\n");
2000
2001         if (torture_setting_bool(tctx, "samba4", false)) {
2002                 torture_comment(tctx, "skipping QueryForestTrustInformation against Samba4\n");
2003                 return true;
2004         }
2005
2006         ZERO_STRUCT(string);
2007
2008         if (trusted_domain_name) {
2009                 init_lsa_String(&string, trusted_domain_name);
2010         }
2011
2012         info_ptr = &info;
2013
2014         r.in.handle = handle;
2015         r.in.trusted_domain_name = &string;
2016         r.in.unknown = 0;
2017         r.out.forest_trust_info = &info_ptr;
2018
2019         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_lsaRQueryForestTrustInformation_r(b, tctx, &r),
2020                 "lsaRQueryForestTrustInformation failed");
2021
2022         if (!NT_STATUS_IS_OK(r.out.result)) {
2023                 torture_comment(tctx, "lsaRQueryForestTrustInformation of %s failed - %s\n", trusted_domain_name, nt_errstr(r.out.result));
2024                 ret = false;
2025         }
2026
2027         return ret;
2028 }
2029
2030 static bool test_query_each_TrustDomEx(struct dcerpc_binding_handle *b,
2031                                        struct torture_context *tctx,
2032                                        struct policy_handle *handle,
2033                                        struct lsa_DomainListEx *domains)
2034 {
2035         int i;
2036         bool ret = true;
2037
2038         for (i=0; i< domains->count; i++) {
2039
2040                 if (domains->domains[i].trust_attributes & NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
2041                         ret &= test_QueryForestTrustInformation(b, tctx, handle,
2042                                                                 domains->domains[i].domain_name.string);
2043                 }
2044         }
2045
2046         return ret;
2047 }
2048
2049 static bool test_query_each_TrustDom(struct dcerpc_binding_handle *b,
2050                                      struct torture_context *tctx,
2051                                      struct policy_handle *handle,
2052                                      struct lsa_DomainList *domains)
2053 {
2054         int i,j;
2055         bool ret = true;
2056
2057         torture_comment(tctx, "\nTesting OpenTrustedDomain, OpenTrustedDomainByName and QueryInfoTrustedDomain\n");
2058         for (i=0; i< domains->count; i++) {
2059                 struct lsa_OpenTrustedDomain trust;
2060                 struct lsa_OpenTrustedDomainByName trust_by_name;
2061                 struct policy_handle trustdom_handle;
2062                 struct policy_handle handle2;
2063                 struct lsa_Close c;
2064                 struct lsa_CloseTrustedDomainEx c_trust;
2065                 int levels [] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
2066                 int ok[]      = {1, 0, 1, 0, 0, 1, 0, 1, 0,  0,  0,  1, 1};
2067
2068                 if (domains->domains[i].sid) {
2069                         trust.in.handle = handle;
2070                         trust.in.sid = domains->domains[i].sid;
2071                         trust.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2072                         trust.out.trustdom_handle = &trustdom_handle;
2073
2074                         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenTrustedDomain_r(b, tctx, &trust),
2075                                 "OpenTrustedDomain failed");
2076
2077                         if (!NT_STATUS_IS_OK(trust.out.result)) {
2078                                 torture_comment(tctx, "OpenTrustedDomain failed - %s\n", nt_errstr(trust.out.result));
2079                                 return false;
2080                         }
2081
2082                         c.in.handle = &trustdom_handle;
2083                         c.out.handle = &handle2;
2084
2085                         c_trust.in.handle = &trustdom_handle;
2086                         c_trust.out.handle = &handle2;
2087
2088                         for (j=0; j < ARRAY_SIZE(levels); j++) {
2089                                 struct lsa_QueryTrustedDomainInfo q;
2090                                 union lsa_TrustedDomainInfo *info = NULL;
2091                                 q.in.trustdom_handle = &trustdom_handle;
2092                                 q.in.level = levels[j];
2093                                 q.out.info = &info;
2094                                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfo_r(b, tctx, &q),
2095                                         "QueryTrustedDomainInfo failed");
2096                                 if (!NT_STATUS_IS_OK(q.out.result) && ok[j]) {
2097                                         torture_comment(tctx, "QueryTrustedDomainInfo level %d failed - %s\n",
2098                                                levels[j], nt_errstr(q.out.result));
2099                                         ret = false;
2100                                 } else if (NT_STATUS_IS_OK(q.out.result) && !ok[j]) {
2101                                         torture_comment(tctx, "QueryTrustedDomainInfo level %d unexpectedly succeeded - %s\n",
2102                                                levels[j], nt_errstr(q.out.result));
2103                                         ret = false;
2104                                 }
2105                         }
2106
2107                         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CloseTrustedDomainEx_r(b, tctx, &c_trust),
2108                                 "CloseTrustedDomainEx failed");
2109                         if (!NT_STATUS_EQUAL(c_trust.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
2110                                 torture_comment(tctx, "Expected CloseTrustedDomainEx to return NT_STATUS_NOT_IMPLEMENTED, instead - %s\n", nt_errstr(c_trust.out.result));
2111                                 return false;
2112                         }
2113
2114                         c.in.handle = &trustdom_handle;
2115                         c.out.handle = &handle2;
2116
2117                         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Close_r(b, tctx, &c),
2118                                 "Close failed");
2119                         if (!NT_STATUS_IS_OK(c.out.result)) {
2120                                 torture_comment(tctx, "Close of trusted domain failed - %s\n", nt_errstr(c.out.result));
2121                                 return false;
2122                         }
2123
2124                         for (j=0; j < ARRAY_SIZE(levels); j++) {
2125                                 struct lsa_QueryTrustedDomainInfoBySid q;
2126                                 union lsa_TrustedDomainInfo *info = NULL;
2127
2128                                 if (!domains->domains[i].sid) {
2129                                         continue;
2130                                 }
2131
2132                                 q.in.handle  = handle;
2133                                 q.in.dom_sid = domains->domains[i].sid;
2134                                 q.in.level   = levels[j];
2135                                 q.out.info   = &info;
2136
2137                                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfoBySid_r(b, tctx, &q),
2138                                         "lsa_QueryTrustedDomainInfoBySid failed");
2139                                 if (!NT_STATUS_IS_OK(q.out.result) && ok[j]) {
2140                                         torture_comment(tctx, "QueryTrustedDomainInfoBySid level %d failed - %s\n",
2141                                                levels[j], nt_errstr(q.out.result));
2142                                         ret = false;
2143                                 } else if (NT_STATUS_IS_OK(q.out.result) && !ok[j]) {
2144                                         torture_comment(tctx, "QueryTrustedDomainInfoBySid level %d unexpectedly succeeded - %s\n",
2145                                                levels[j], nt_errstr(q.out.result));
2146                                         ret = false;
2147                                 }
2148                         }
2149                 }
2150
2151                 trust_by_name.in.handle = handle;
2152                 trust_by_name.in.name.string = domains->domains[i].name.string;
2153                 trust_by_name.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2154                 trust_by_name.out.trustdom_handle = &trustdom_handle;
2155
2156                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenTrustedDomainByName_r(b, tctx, &trust_by_name),
2157                         "OpenTrustedDomainByName failed");
2158
2159                 if (!NT_STATUS_IS_OK(trust_by_name.out.result)) {
2160                         torture_comment(tctx, "OpenTrustedDomainByName failed - %s\n", nt_errstr(trust_by_name.out.result));
2161                         return false;
2162                 }
2163
2164                 for (j=0; j < ARRAY_SIZE(levels); j++) {
2165                         struct lsa_QueryTrustedDomainInfo q;
2166                         union lsa_TrustedDomainInfo *info = NULL;
2167                         q.in.trustdom_handle = &trustdom_handle;
2168                         q.in.level = levels[j];
2169                         q.out.info = &info;
2170                         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfo_r(b, tctx, &q),
2171                                 "QueryTrustedDomainInfo failed");
2172                         if (!NT_STATUS_IS_OK(q.out.result) && ok[j]) {
2173                                 torture_comment(tctx, "QueryTrustedDomainInfo level %d failed - %s\n",
2174                                        levels[j], nt_errstr(q.out.result));
2175                                 ret = false;
2176                         } else if (NT_STATUS_IS_OK(q.out.result) && !ok[j]) {
2177                                 torture_comment(tctx, "QueryTrustedDomainInfo level %d unexpectedly succeeded - %s\n",
2178                                        levels[j], nt_errstr(q.out.result));
2179                                 ret = false;
2180                         }
2181                 }
2182
2183                 c.in.handle = &trustdom_handle;
2184                 c.out.handle = &handle2;
2185
2186                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Close_r(b, tctx, &c),
2187                         "Close failed");
2188                 if (!NT_STATUS_IS_OK(c.out.result)) {
2189                         torture_comment(tctx, "Close of trusted domain failed - %s\n", nt_errstr(c.out.result));
2190                         return false;
2191                 }
2192
2193                 for (j=0; j < ARRAY_SIZE(levels); j++) {
2194                         struct lsa_QueryTrustedDomainInfoByName q;
2195                         union lsa_TrustedDomainInfo *info = NULL;
2196                         struct lsa_String name;
2197
2198                         name.string = domains->domains[i].name.string;
2199
2200                         q.in.handle         = handle;
2201                         q.in.trusted_domain = &name;
2202                         q.in.level          = levels[j];
2203                         q.out.info          = &info;
2204                         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfoByName_r(b, tctx, &q),
2205                                 "QueryTrustedDomainInfoByName failed");
2206                         if (!NT_STATUS_IS_OK(q.out.result) && ok[j]) {
2207                                 torture_comment(tctx, "QueryTrustedDomainInfoByName level %d failed - %s\n",
2208                                        levels[j], nt_errstr(q.out.result));
2209                                 ret = false;
2210                         } else if (NT_STATUS_IS_OK(q.out.result) && !ok[j]) {
2211                                 torture_comment(tctx, "QueryTrustedDomainInfoByName level %d unexpectedly succeeded - %s\n",
2212                                        levels[j], nt_errstr(q.out.result));
2213                                 ret = false;
2214                         }
2215                 }
2216         }
2217         return ret;
2218 }
2219
2220 static bool test_EnumTrustDom(struct dcerpc_binding_handle *b,
2221                               struct torture_context *tctx,
2222                               struct policy_handle *handle)
2223 {
2224         struct lsa_EnumTrustDom r;
2225         uint32_t in_resume_handle = 0;
2226         uint32_t out_resume_handle;
2227         struct lsa_DomainList domains;
2228         bool ret = true;
2229
2230         torture_comment(tctx, "\nTesting EnumTrustDom\n");
2231
2232         r.in.handle = handle;
2233         r.in.resume_handle = &in_resume_handle;
2234         r.in.max_size = 0;
2235         r.out.domains = &domains;
2236         r.out.resume_handle = &out_resume_handle;
2237
2238         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustDom_r(b, tctx, &r),
2239                 "lsa_EnumTrustDom failed");
2240
2241         /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
2242          * always be larger than the previous input resume handle, in
2243          * particular when hitting the last query it is vital to set the
2244          * resume handle correctly to avoid infinite client loops, as
2245          * seen e.g.  with Windows XP SP3 when resume handle is 0 and
2246          * status is NT_STATUS_OK - gd */
2247
2248         if (NT_STATUS_IS_OK(r.out.result) ||
2249             NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES) ||
2250             NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
2251         {
2252                 if (out_resume_handle <= in_resume_handle) {
2253                         torture_comment(tctx, "EnumTrustDom failed - should have returned output resume_handle (0x%08x) larger than input resume handle (0x%08x)\n",
2254                                 out_resume_handle, in_resume_handle);
2255                         return false;
2256                 }
2257         }
2258
2259         if (NT_STATUS_IS_OK(r.out.result)) {
2260                 if (domains.count == 0) {
2261                         torture_comment(tctx, "EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
2262                         return false;
2263                 }
2264         } else if (!(NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) || NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES))) {
2265                 torture_comment(tctx, "EnumTrustDom of zero size failed - %s\n", nt_errstr(r.out.result));
2266                 return false;
2267         }
2268
2269         /* Start from the bottom again */
2270         in_resume_handle = 0;
2271
2272         do {
2273                 r.in.handle = handle;
2274                 r.in.resume_handle = &in_resume_handle;
2275                 r.in.max_size = LSA_ENUM_TRUST_DOMAIN_MULTIPLIER * 3;
2276                 r.out.domains = &domains;
2277                 r.out.resume_handle = &out_resume_handle;
2278
2279                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustDom_r(b, tctx, &r),
2280                         "EnumTrustDom failed");
2281
2282                 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
2283                  * always be larger than the previous input resume handle, in
2284                  * particular when hitting the last query it is vital to set the
2285                  * resume handle correctly to avoid infinite client loops, as
2286                  * seen e.g.  with Windows XP SP3 when resume handle is 0 and
2287                  * status is NT_STATUS_OK - gd */
2288
2289                 if (NT_STATUS_IS_OK(r.out.result) ||
2290                     NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES) ||
2291                     NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
2292                 {
2293                         if (out_resume_handle <= in_resume_handle) {
2294                                 torture_comment(tctx, "EnumTrustDom failed - should have returned output resume_handle (0x%08x) larger than input resume handle (0x%08x)\n",
2295                                         out_resume_handle, in_resume_handle);
2296                                 return false;
2297                         }
2298                 }
2299
2300                 /* NO_MORE_ENTRIES is allowed */
2301                 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES)) {
2302                         if (domains.count == 0) {
2303                                 return true;
2304                         }
2305                         torture_comment(tctx, "EnumTrustDom failed - should have returned 0 trusted domains with 'NT_STATUS_NO_MORE_ENTRIES'\n");
2306                         return false;
2307                 } else if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES)) {
2308                         /* Windows 2003 gets this off by one on the first run */
2309                         if (r.out.domains->count < 3 || r.out.domains->count > 4) {
2310                                 torture_comment(tctx, "EnumTrustDom didn't fill the buffer we "
2311                                        "asked it to (got %d, expected %d / %d == %d entries)\n",
2312                                        r.out.domains->count, LSA_ENUM_TRUST_DOMAIN_MULTIPLIER * 3,
2313                                        LSA_ENUM_TRUST_DOMAIN_MULTIPLIER, r.in.max_size);
2314                                 ret = false;
2315                         }
2316                 } else if (!NT_STATUS_IS_OK(r.out.result)) {
2317                         torture_comment(tctx, "EnumTrustDom failed - %s\n", nt_errstr(r.out.result));
2318                         return false;
2319                 }
2320
2321                 if (domains.count == 0) {
2322                         torture_comment(tctx, "EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
2323                         return false;
2324                 }
2325
2326                 ret &= test_query_each_TrustDom(b, tctx, handle, &domains);
2327
2328                 in_resume_handle = out_resume_handle;
2329
2330         } while ((NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES)));
2331
2332         return ret;
2333 }
2334
2335 static bool test_EnumTrustDomEx(struct dcerpc_binding_handle *b,
2336                                 struct torture_context *tctx,
2337                                 struct policy_handle *handle)
2338 {
2339         struct lsa_EnumTrustedDomainsEx r_ex;
2340         uint32_t resume_handle = 0;
2341         struct lsa_DomainListEx domains_ex;
2342         bool ret = true;
2343
2344         torture_comment(tctx, "\nTesting EnumTrustedDomainsEx\n");
2345
2346         r_ex.in.handle = handle;
2347         r_ex.in.resume_handle = &resume_handle;
2348         r_ex.in.max_size = LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER * 3;
2349         r_ex.out.domains = &domains_ex;
2350         r_ex.out.resume_handle = &resume_handle;
2351
2352         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustedDomainsEx_r(b, tctx, &r_ex),
2353                 "EnumTrustedDomainsEx failed");
2354
2355         if (!(NT_STATUS_EQUAL(r_ex.out.result, STATUS_MORE_ENTRIES) || NT_STATUS_EQUAL(r_ex.out.result, NT_STATUS_NO_MORE_ENTRIES))) {
2356                 torture_comment(tctx, "EnumTrustedDomainEx of zero size failed - %s\n", nt_errstr(r_ex.out.result));
2357                 return false;
2358         }
2359
2360         resume_handle = 0;
2361         do {
2362                 r_ex.in.handle = handle;
2363                 r_ex.in.resume_handle = &resume_handle;
2364                 r_ex.in.max_size = LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER * 3;
2365                 r_ex.out.domains = &domains_ex;
2366                 r_ex.out.resume_handle = &resume_handle;
2367
2368                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustedDomainsEx_r(b, tctx, &r_ex),
2369                         "EnumTrustedDomainsEx failed");
2370
2371                 /* NO_MORE_ENTRIES is allowed */
2372                 if (NT_STATUS_EQUAL(r_ex.out.result, NT_STATUS_NO_MORE_ENTRIES)) {
2373                         if (domains_ex.count == 0) {
2374                                 return true;
2375                         }
2376                         torture_comment(tctx, "EnumTrustDomainsEx failed - should have returned 0 trusted domains with 'NT_STATUS_NO_MORE_ENTRIES'\n");
2377                         return false;
2378                 } else if (NT_STATUS_EQUAL(r_ex.out.result, STATUS_MORE_ENTRIES)) {
2379                         /* Windows 2003 gets this off by one on the first run */
2380                         if (r_ex.out.domains->count < 3 || r_ex.out.domains->count > 4) {
2381                                 torture_comment(tctx, "EnumTrustDom didn't fill the buffer we "
2382                                        "asked it to (got %d, expected %d / %d == %d entries)\n",
2383                                        r_ex.out.domains->count,
2384                                        r_ex.in.max_size,
2385                                        LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER,
2386                                        r_ex.in.max_size / LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER);
2387                         }
2388                 } else if (!NT_STATUS_IS_OK(r_ex.out.result)) {
2389                         torture_comment(tctx, "EnumTrustedDomainEx failed - %s\n", nt_errstr(r_ex.out.result));
2390                         return false;
2391                 }
2392
2393                 if (domains_ex.count == 0) {
2394                         torture_comment(tctx, "EnumTrustDomainEx failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
2395                         return false;
2396                 }
2397
2398                 ret &= test_query_each_TrustDomEx(b, tctx, handle, &domains_ex);
2399
2400         } while ((NT_STATUS_EQUAL(r_ex.out.result, STATUS_MORE_ENTRIES)));
2401
2402         return ret;
2403 }
2404
2405
2406 static bool test_CreateTrustedDomain(struct dcerpc_binding_handle *b,
2407                                      struct torture_context *tctx,
2408                                      struct policy_handle *handle,
2409                                      uint32_t num_trusts)
2410 {
2411         bool ret = true;
2412         struct lsa_CreateTrustedDomain r;
2413         struct lsa_DomainInfo trustinfo;
2414         struct dom_sid **domsid;
2415         struct policy_handle *trustdom_handle;
2416         struct lsa_QueryTrustedDomainInfo q;
2417         union lsa_TrustedDomainInfo *info = NULL;
2418         int i;
2419
2420         torture_comment(tctx, "\nTesting CreateTrustedDomain for %d domains\n", num_trusts);
2421
2422         if (!test_EnumTrustDom(b, tctx, handle)) {
2423                 ret = false;
2424         }
2425
2426         if (!test_EnumTrustDomEx(b, tctx, handle)) {
2427                 ret = false;
2428         }
2429
2430         domsid = talloc_array(tctx, struct dom_sid *, num_trusts);
2431         trustdom_handle = talloc_array(tctx, struct policy_handle, num_trusts);
2432
2433         for (i=0; i< num_trusts; i++) {
2434                 char *trust_name = talloc_asprintf(tctx, "torturedom%02d", i);
2435                 char *trust_sid = talloc_asprintf(tctx, "S-1-5-21-97398-379795-100%02d", i);
2436
2437                 domsid[i] = dom_sid_parse_talloc(tctx, trust_sid);
2438
2439                 trustinfo.sid = domsid[i];
2440                 init_lsa_String((struct lsa_String *)&trustinfo.name, trust_name);
2441
2442                 r.in.policy_handle = handle;
2443                 r.in.info = &trustinfo;
2444                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2445                 r.out.trustdom_handle = &trustdom_handle[i];
2446
2447                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CreateTrustedDomain_r(b, tctx, &r),
2448                         "CreateTrustedDomain failed");
2449                 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_OBJECT_NAME_COLLISION)) {
2450                         test_DeleteTrustedDomain(b, tctx, handle, trustinfo.name);
2451                         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CreateTrustedDomain_r(b, tctx, &r),
2452                                 "CreateTrustedDomain failed");
2453                 }
2454                 if (!NT_STATUS_IS_OK(r.out.result)) {
2455                         torture_comment(tctx, "CreateTrustedDomain failed - %s\n", nt_errstr(r.out.result));
2456                         ret = false;
2457                 } else {
2458
2459                         q.in.trustdom_handle = &trustdom_handle[i];
2460                         q.in.level = LSA_TRUSTED_DOMAIN_INFO_INFO_EX;
2461                         q.out.info = &info;
2462                         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfo_r(b, tctx, &q),
2463                                 "QueryTrustedDomainInfo failed");
2464                         if (!NT_STATUS_IS_OK(q.out.result)) {
2465                                 torture_comment(tctx, "QueryTrustedDomainInfo level %d failed - %s\n", q.in.level, nt_errstr(q.out.result));
2466                                 ret = false;
2467                         } else if (!q.out.info) {
2468                                 ret = false;
2469                         } else {
2470                                 if (strcmp(info->info_ex.netbios_name.string, trustinfo.name.string) != 0) {
2471                                         torture_comment(tctx, "QueryTrustedDomainInfo returned inconsistent short name: %s != %s\n",
2472                                                info->info_ex.netbios_name.string, trustinfo.name.string);
2473                                         ret = false;
2474                                 }
2475                                 if (info->info_ex.trust_type != LSA_TRUST_TYPE_DOWNLEVEL) {
2476                                         torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n",
2477                                                trust_name, info->info_ex.trust_type, LSA_TRUST_TYPE_DOWNLEVEL);
2478                                         ret = false;
2479                                 }
2480                                 if (info->info_ex.trust_attributes != 0) {
2481                                         torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n",
2482                                                trust_name, info->info_ex.trust_attributes, 0);
2483                                         ret = false;
2484                                 }
2485                                 if (info->info_ex.trust_direction != LSA_TRUST_DIRECTION_OUTBOUND) {
2486                                         torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n",
2487                                                trust_name, info->info_ex.trust_direction, LSA_TRUST_DIRECTION_OUTBOUND);
2488                                         ret = false;
2489                                 }
2490                         }
2491                 }
2492         }
2493
2494         /* now that we have some domains to look over, we can test the enum calls */
2495         if (!test_EnumTrustDom(b, tctx, handle)) {
2496                 ret = false;
2497         }
2498
2499         if (!test_EnumTrustDomEx(b, tctx, handle)) {
2500                 ret = false;
2501         }
2502
2503         for (i=0; i<num_trusts; i++) {
2504                 if (!test_DeleteTrustedDomainBySid(b, tctx, handle, domsid[i])) {
2505                         ret = false;
2506                 }
2507         }
2508
2509         return ret;
2510 }
2511
2512 static bool gen_authinfo_internal(TALLOC_CTX *mem_ctx, const char *password,
2513                                   DATA_BLOB session_key,
2514                                   struct lsa_TrustDomainInfoAuthInfoInternal **_authinfo_internal)
2515 {
2516         struct lsa_TrustDomainInfoAuthInfoInternal *authinfo_internal;
2517         struct trustDomainPasswords auth_struct;
2518         struct AuthenticationInformation *auth_info_array;
2519         size_t converted_size;
2520         DATA_BLOB auth_blob;
2521         enum ndr_err_code ndr_err;
2522
2523         authinfo_internal = talloc_zero(mem_ctx, struct lsa_TrustDomainInfoAuthInfoInternal);
2524         if (authinfo_internal == NULL) {
2525                 return false;
2526         }
2527
2528         auth_info_array = talloc_array(mem_ctx,
2529                                        struct AuthenticationInformation, 1);
2530         if (auth_info_array == NULL) {
2531                 return false;
2532         }
2533
2534         generate_random_buffer(auth_struct.confounder, sizeof(auth_struct.confounder));
2535
2536         auth_info_array[0].AuthType = TRUST_AUTH_TYPE_CLEAR;
2537
2538         if (!convert_string_talloc(mem_ctx, CH_UNIX, CH_UTF16, password,
2539                                   strlen(password),
2540                                   &auth_info_array[0].AuthInfo.clear.password,
2541                                   &converted_size)) {
2542                 return false;
2543         }
2544
2545         auth_info_array[0].AuthInfo.clear.size = converted_size;
2546
2547         auth_struct.outgoing.count = 1;
2548         auth_struct.outgoing.current.count = 1;
2549         auth_struct.outgoing.current.array = auth_info_array;
2550         auth_struct.outgoing.previous.count = 0;
2551         auth_struct.outgoing.previous.array = NULL;
2552
2553         auth_struct.incoming.count = 1;
2554         auth_struct.incoming.current.count = 1;
2555         auth_struct.incoming.current.array = auth_info_array;
2556         auth_struct.incoming.previous.count = 0;
2557         auth_struct.incoming.previous.array = NULL;
2558
2559
2560         ndr_err = ndr_push_struct_blob(&auth_blob, mem_ctx, &auth_struct,
2561                                        (ndr_push_flags_fn_t)ndr_push_trustDomainPasswords);
2562         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2563                 return false;
2564         }
2565
2566         arcfour_crypt_blob(auth_blob.data, auth_blob.length, &session_key);
2567
2568         authinfo_internal->auth_blob.size = auth_blob.length;
2569         authinfo_internal->auth_blob.data = auth_blob.data;
2570
2571         *_authinfo_internal = authinfo_internal;
2572
2573         return true;
2574 }
2575
2576 static bool gen_authinfo(TALLOC_CTX *mem_ctx, const char *password,
2577                          struct lsa_TrustDomainInfoAuthInfo **_authinfo)
2578 {
2579         struct lsa_TrustDomainInfoAuthInfo *authinfo;
2580         struct lsa_TrustDomainInfoBuffer *info_buffer;
2581         size_t converted_size;
2582
2583         authinfo = talloc_zero(mem_ctx, struct lsa_TrustDomainInfoAuthInfo);
2584         if (authinfo == NULL) {
2585                 return false;
2586         }
2587
2588         info_buffer = talloc_zero(mem_ctx, struct lsa_TrustDomainInfoBuffer);
2589         if (info_buffer == NULL) {
2590                 return false;
2591         }
2592
2593         info_buffer->AuthType = TRUST_AUTH_TYPE_CLEAR;
2594
2595         if (!convert_string_talloc(mem_ctx, CH_UNIX, CH_UTF16, password,
2596                                   strlen(password),
2597                                   &info_buffer->data.data,
2598                                   &converted_size)) {
2599                 return false;
2600         }
2601
2602         info_buffer->data.size = converted_size;
2603
2604         authinfo->incoming_count = 1;
2605         authinfo->incoming_current_auth_info = info_buffer;
2606         authinfo->incoming_previous_auth_info = NULL;
2607         authinfo->outgoing_count = 1;
2608         authinfo->outgoing_current_auth_info = info_buffer;
2609         authinfo->outgoing_previous_auth_info = NULL;
2610
2611         *_authinfo = authinfo;
2612
2613         return true;
2614 }
2615
2616 static bool check_pw_with_ServerAuthenticate3(struct dcerpc_pipe *p,
2617                                              struct torture_context *tctx,
2618                                              uint32_t negotiate_flags,
2619                                              struct cli_credentials *machine_credentials,
2620                                              struct netlogon_creds_CredentialState **creds_out)
2621 {
2622         struct netr_ServerReqChallenge r;
2623         struct netr_ServerAuthenticate3 a;
2624         struct netr_Credential credentials1, credentials2, credentials3;
2625         struct netlogon_creds_CredentialState *creds;
2626         struct samr_Password mach_password;
2627         uint32_t rid;
2628         const char *machine_name;
2629         const char *plain_pass;
2630         struct dcerpc_binding_handle *b = p->binding_handle;
2631
2632         machine_name = cli_credentials_get_workstation(machine_credentials);
2633         plain_pass = cli_credentials_get_password(machine_credentials);
2634
2635         r.in.server_name = NULL;
2636         r.in.computer_name = machine_name;
2637         r.in.credentials = &credentials1;
2638         r.out.return_credentials = &credentials2;
2639
2640         generate_random_buffer(credentials1.data, sizeof(credentials1.data));
2641
2642         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
2643                 "ServerReqChallenge failed");
2644         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
2645
2646         E_md4hash(plain_pass, mach_password.hash);
2647
2648         a.in.server_name = NULL;
2649         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
2650         a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2651         a.in.computer_name = machine_name;
2652         a.in.negotiate_flags = &negotiate_flags;
2653         a.in.credentials = &credentials3;
2654         a.out.return_credentials = &credentials3;
2655         a.out.negotiate_flags = &negotiate_flags;
2656         a.out.rid = &rid;
2657
2658         creds = netlogon_creds_client_init(tctx, a.in.account_name,
2659                                            a.in.computer_name,
2660                                            &credentials1, &credentials2,
2661                                            &mach_password, &credentials3,
2662                                            negotiate_flags);
2663
2664         torture_assert(tctx, creds != NULL, "memory allocation");
2665
2666         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
2667                 "ServerAuthenticate3 failed");
2668         if (!NT_STATUS_IS_OK(a.out.result)) {
2669                 if (!NT_STATUS_EQUAL(a.out.result, NT_STATUS_ACCESS_DENIED)) {
2670                         torture_assert_ntstatus_ok(tctx, a.out.result,
2671                                                    "ServerAuthenticate3 failed");
2672                 }
2673                 return false;
2674         }
2675         torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
2676
2677         /* Prove that requesting a challenge again won't break it */
2678         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
2679                 "ServerReqChallenge failed");
2680         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
2681
2682         *creds_out = creds;
2683         return true;
2684 }
2685
2686 static bool check_dom_trust_pw(struct dcerpc_pipe *p,
2687                                struct torture_context *tctx,
2688                                const char *trusted_dom_name,
2689                                const char *password)
2690 {
2691         struct cli_credentials *credentials;
2692         char *dummy;
2693         struct netlogon_creds_CredentialState *creds;
2694         struct dcerpc_pipe *pipe;
2695         NTSTATUS status;
2696         bool ok;
2697
2698         credentials = cli_credentials_init(tctx);
2699         if (credentials == NULL) {
2700                 return false;
2701         }
2702
2703         dummy = talloc_asprintf(tctx, "%s$", trusted_dom_name);
2704         if (dummy == NULL) {
2705                 return false;
2706         }
2707
2708         cli_credentials_set_username(credentials, dummy, CRED_SPECIFIED);
2709         cli_credentials_set_password(credentials, password, CRED_SPECIFIED);
2710         cli_credentials_set_workstation(credentials,
2711                                         trusted_dom_name, CRED_SPECIFIED);
2712         cli_credentials_set_secure_channel_type(credentials, SEC_CHAN_DOMAIN);
2713
2714         status = dcerpc_pipe_connect_b(tctx, &pipe, p->binding,
2715                                        &ndr_table_netlogon,
2716                                        cli_credentials_init_anon(tctx),
2717                                        tctx->ev, tctx->lp_ctx);
2718         if (!NT_STATUS_IS_OK(status)) {
2719                 torture_comment(tctx, "dcerpc_pipe_connect_b failed.\n");
2720                 return false;
2721         }
2722
2723         ok = check_pw_with_ServerAuthenticate3(pipe, tctx,
2724                                                NETLOGON_NEG_AUTH2_ADS_FLAGS,
2725                                                credentials, &creds);
2726         talloc_free(pipe);
2727
2728         return ok;
2729 }
2730
2731 static bool test_CreateTrustedDomainEx_common(struct dcerpc_pipe *p,
2732                                               struct torture_context *tctx,
2733                                               struct policy_handle *handle,
2734                                               uint32_t num_trusts,
2735                                               bool ex2_call)
2736 {
2737         NTSTATUS status;
2738         bool ret = true;
2739         struct lsa_CreateTrustedDomainEx r;
2740         struct lsa_CreateTrustedDomainEx2 r2;
2741         struct lsa_TrustDomainInfoInfoEx trustinfo;
2742         struct lsa_TrustDomainInfoAuthInfoInternal *authinfo_internal;
2743         struct lsa_TrustDomainInfoAuthInfo *authinfo;
2744         struct dom_sid **domsid;
2745         struct policy_handle *trustdom_handle;
2746         struct lsa_QueryTrustedDomainInfo q;
2747         union lsa_TrustedDomainInfo *info = NULL;
2748         DATA_BLOB session_key;
2749         int i;
2750         struct dcerpc_binding_handle *b = p->binding_handle;
2751
2752         if (ex2_call) {
2753                 torture_comment(tctx, "\nTesting CreateTrustedDomainEx2 for %d domains\n", num_trusts);
2754         } else {
2755                 torture_comment(tctx, "\nTesting CreateTrustedDomainEx for %d domains\n", num_trusts);
2756         }
2757
2758         domsid = talloc_array(tctx, struct dom_sid *, num_trusts);
2759         trustdom_handle = talloc_array(tctx, struct policy_handle, num_trusts);
2760
2761         status = dcerpc_fetch_session_key(p, &session_key);
2762         if (!NT_STATUS_IS_OK(status)) {
2763                 torture_comment(tctx, "dcerpc_fetch_session_key failed - %s\n", nt_errstr(status));
2764                 return false;
2765         }
2766
2767         for (i=0; i< num_trusts; i++) {
2768                 char *trust_name = talloc_asprintf(tctx, "torturedom%02d", i);
2769                 char *trust_name_dns = talloc_asprintf(tctx, "torturedom%02d.samba.example.com", i);
2770                 char *trust_sid = talloc_asprintf(tctx, "S-1-5-21-97398-379795-100%02d", i);
2771
2772                 domsid[i] = dom_sid_parse_talloc(tctx, trust_sid);
2773
2774                 trustinfo.sid = domsid[i];
2775                 trustinfo.netbios_name.string = trust_name;
2776                 trustinfo.domain_name.string = trust_name_dns;
2777
2778                 /* Create inbound, some outbound, and some
2779                  * bi-directional trusts in a repeating pattern based
2780                  * on i */
2781
2782                 /* 1 == inbound, 2 == outbound, 3 == both */
2783                 trustinfo.trust_direction = (i % 3) + 1;
2784
2785                 /* Try different trust types too */
2786
2787                 /* 1 == downlevel (NT4), 2 == uplevel (ADS), 3 == MIT (kerberos but not AD) */
2788                 trustinfo.trust_type = (((i / 3) + 1) % 3) + 1;
2789
2790                 trustinfo.trust_attributes = LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION;
2791
2792                 if (!gen_authinfo_internal(tctx, TRUSTPW, session_key, &authinfo_internal)) {
2793                         torture_comment(tctx, "gen_authinfo_internal failed");
2794                         ret = false;
2795                 }
2796
2797                 if (!gen_authinfo(tctx, TRUSTPW, &authinfo)) {
2798                         torture_comment(tctx, "gen_authinfonfo failed");
2799                         ret = false;
2800                 }
2801
2802                 if (ex2_call) {
2803
2804                         r2.in.policy_handle = handle;
2805                         r2.in.info = &trustinfo;
2806                         r2.in.auth_info_internal = authinfo_internal;
2807                         r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2808                         r2.out.trustdom_handle = &trustdom_handle[i];
2809
2810                         torture_assert_ntstatus_ok(tctx,
2811                                 dcerpc_lsa_CreateTrustedDomainEx2_r(b, tctx, &r2),
2812                                 "CreateTrustedDomainEx2 failed");
2813
2814                         status = r2.out.result;
2815                 } else {
2816
2817                         r.in.policy_handle = handle;
2818                         r.in.info = &trustinfo;
2819                         r.in.auth_info = authinfo;
2820                         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2821                         r.out.trustdom_handle = &trustdom_handle[i];
2822
2823                         torture_assert_ntstatus_ok(tctx,
2824                                 dcerpc_lsa_CreateTrustedDomainEx_r(b, tctx, &r),
2825                                 "CreateTrustedDomainEx failed");
2826
2827                         status = r.out.result;
2828                 }
2829
2830                 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
2831                         test_DeleteTrustedDomain(b, tctx, handle, trustinfo.netbios_name);
2832                         if (ex2_call) {
2833                                 torture_assert_ntstatus_ok(tctx,
2834                                         dcerpc_lsa_CreateTrustedDomainEx2_r(b, tctx, &r2),
2835                                         "CreateTrustedDomainEx2 failed");
2836                                 status = r2.out.result;
2837                         } else {
2838                                 torture_assert_ntstatus_ok(tctx,
2839                                         dcerpc_lsa_CreateTrustedDomainEx_r(b, tctx, &r),
2840                                         "CreateTrustedDomainEx2 failed");
2841                                 status = r.out.result;
2842                         }
2843                 }
2844                 if (!NT_STATUS_IS_OK(status)) {
2845                         torture_comment(tctx, "CreateTrustedDomainEx failed2 - %s\n", nt_errstr(status));
2846                         ret = false;
2847                 } else {
2848                         /* For outbound and MIT trusts there is no trust account */
2849                         if (trustinfo.trust_direction != 2 &&
2850                             trustinfo.trust_type != 3) {
2851
2852                                 if (torture_setting_bool(tctx, "samba3", false) ||
2853                                     torture_setting_bool(tctx, "samba4", false)) {
2854                                         torture_comment(tctx, "skipping trusted domain auth tests against samba");
2855                                 } else {
2856                                         if (check_dom_trust_pw(p, tctx, trust_name,
2857                                                                 "x" TRUSTPW "x")) {
2858                                                 torture_comment(tctx, "Password check passed unexpectedly\n");
2859                                                 ret = false;
2860                                         }
2861                                         if (!check_dom_trust_pw(p, tctx, trust_name,
2862                                                                 TRUSTPW)) {
2863                                                 torture_comment(tctx, "Password check failed\n");
2864                                                 ret = false;
2865                                         }
2866                                 }
2867                         }
2868
2869                         q.in.trustdom_handle = &trustdom_handle[i];
2870                         q.in.level = LSA_TRUSTED_DOMAIN_INFO_INFO_EX;
2871                         q.out.info = &info;
2872                         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfo_r(b, tctx, &q),
2873                                 "QueryTrustedDomainInfo failed");
2874                         if (!NT_STATUS_IS_OK(q.out.result)) {
2875                                 torture_comment(tctx, "QueryTrustedDomainInfo level 1 failed - %s\n", nt_errstr(q.out.result));
2876                                 ret = false;
2877                         } else if (!q.out.info) {
2878                                 torture_comment(tctx, "QueryTrustedDomainInfo level 1 failed to return an info pointer\n");
2879                                 ret = false;
2880                         } else {
2881                                 if (strcmp(info->info_ex.netbios_name.string, trustinfo.netbios_name.string) != 0) {
2882                                         torture_comment(tctx, "QueryTrustedDomainInfo returned inconsistent short name: %s != %s\n",
2883                                                info->info_ex.netbios_name.string, trustinfo.netbios_name.string);
2884                                         ret = false;
2885                                 }
2886                                 if (info->info_ex.trust_type != trustinfo.trust_type) {
2887                                         torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n",
2888                                                trust_name, info->info_ex.trust_type, trustinfo.trust_type);
2889                                         ret = false;
2890                                 }
2891                                 if (info->info_ex.trust_attributes != LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION) {
2892                                         torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n",
2893                                                trust_name, info->info_ex.trust_attributes, LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION);
2894                                         ret = false;
2895                                 }
2896                                 if (info->info_ex.trust_direction != trustinfo.trust_direction) {
2897                                         torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n",
2898                                                trust_name, info->info_ex.trust_direction, trustinfo.trust_direction);
2899                                         ret = false;
2900                                 }
2901                         }
2902                 }
2903         }
2904
2905         /* now that we have some domains to look over, we can test the enum calls */
2906         if (!test_EnumTrustDom(b, tctx, handle)) {
2907                 torture_comment(tctx, "test_EnumTrustDom failed\n");
2908                 ret = false;
2909         }
2910
2911         if (!test_EnumTrustDomEx(b, tctx, handle)) {
2912                 torture_comment(tctx, "test_EnumTrustDomEx failed\n");
2913                 ret = false;
2914         }
2915
2916         for (i=0; i<num_trusts; i++) {
2917                 if (!test_DeleteTrustedDomainBySid(b, tctx, handle, domsid[i])) {
2918                         torture_comment(tctx, "test_DeleteTrustedDomainBySid failed\n");
2919                         ret = false;
2920                 }
2921         }
2922
2923         return ret;
2924 }
2925
2926 static bool test_CreateTrustedDomainEx2(struct dcerpc_pipe *p,
2927                                         struct torture_context *tctx,
2928                                         struct policy_handle *handle,
2929                                         uint32_t num_trusts)
2930 {
2931         return test_CreateTrustedDomainEx_common(p, tctx, handle, num_trusts, true);
2932 }
2933
2934 static bool test_CreateTrustedDomainEx(struct dcerpc_pipe *p,
2935                                        struct torture_context *tctx,
2936                                        struct policy_handle *handle,
2937                                        uint32_t num_trusts)
2938 {
2939         return test_CreateTrustedDomainEx_common(p, tctx, handle, num_trusts, false);
2940 }
2941
2942 static bool test_QueryDomainInfoPolicy(struct dcerpc_binding_handle *b,
2943                                  struct torture_context *tctx,
2944                                  struct policy_handle *handle)
2945 {
2946         struct lsa_QueryDomainInformationPolicy r;
2947         union lsa_DomainInformationPolicy *info = NULL;
2948         int i;
2949         bool ret = true;
2950
2951         if (torture_setting_bool(tctx, "samba3", false)) {
2952                 torture_skip(tctx, "skipping QueryDomainInformationPolicy test\n");
2953         }
2954
2955         torture_comment(tctx, "\nTesting QueryDomainInformationPolicy\n");
2956
2957         for (i=2;i<4;i++) {
2958                 r.in.handle = handle;
2959                 r.in.level = i;
2960                 r.out.info = &info;
2961
2962                 torture_comment(tctx, "\nTrying QueryDomainInformationPolicy level %d\n", i);
2963
2964                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryDomainInformationPolicy_r(b, tctx, &r),
2965                         "QueryDomainInformationPolicy failed");
2966
2967                 /* If the server does not support EFS, then this is the correct return */
2968                 if (i == LSA_DOMAIN_INFO_POLICY_EFS && NT_STATUS_EQUAL(r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
2969                         continue;
2970                 } else if (!NT_STATUS_IS_OK(r.out.result)) {
2971                         torture_comment(tctx, "QueryDomainInformationPolicy failed - %s\n", nt_errstr(r.out.result));
2972                         ret = false;
2973                         continue;
2974                 }
2975         }
2976
2977         return ret;
2978 }
2979
2980
2981 static bool test_QueryInfoPolicyCalls(  bool version2,
2982                                         struct dcerpc_binding_handle *b,
2983                                         struct torture_context *tctx,
2984                                         struct policy_handle *handle)
2985 {
2986         struct lsa_QueryInfoPolicy r;
2987         union lsa_PolicyInformation *info = NULL;
2988         int i;
2989         bool ret = true;
2990         const char *call = talloc_asprintf(tctx, "QueryInfoPolicy%s", version2 ? "2":"");
2991
2992         torture_comment(tctx, "\nTesting %s\n", call);
2993
2994         if (version2 && torture_setting_bool(tctx, "samba3", false)) {
2995                 torture_skip(tctx, "skipping QueryInfoPolicy2 tests\n");
2996         }
2997
2998         for (i=1;i<=14;i++) {
2999                 r.in.handle = handle;
3000                 r.in.level = i;
3001                 r.out.info = &info;
3002
3003                 torture_comment(tctx, "\nTrying %s level %d\n", call, i);
3004
3005                 if (version2)
3006                         /* We can perform the cast, because both types are
3007                            structurally equal */
3008                         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryInfoPolicy2_r(b, tctx,
3009                                  (struct lsa_QueryInfoPolicy2*) &r),
3010                                  "QueryInfoPolicy2 failed");
3011                 else
3012                         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryInfoPolicy_r(b, tctx, &r),
3013                                 "QueryInfoPolicy2 failed");
3014
3015                 switch (i) {
3016                 case LSA_POLICY_INFO_MOD:
3017                 case LSA_POLICY_INFO_AUDIT_FULL_SET:
3018                 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
3019                         if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
3020                                 torture_comment(tctx, "Server should have failed level %u: %s\n", i, nt_errstr(r.out.result));
3021                                 ret = false;
3022                         }
3023                         break;
3024                 case LSA_POLICY_INFO_DOMAIN:
3025                 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
3026                 case LSA_POLICY_INFO_REPLICA:
3027                 case LSA_POLICY_INFO_QUOTA:
3028                 case LSA_POLICY_INFO_ROLE:
3029                 case LSA_POLICY_INFO_AUDIT_LOG:
3030                 case LSA_POLICY_INFO_AUDIT_EVENTS:
3031                 case LSA_POLICY_INFO_PD:
3032                         if (!NT_STATUS_IS_OK(r.out.result)) {
3033                                 torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
3034                                 ret = false;
3035                         }
3036                         break;
3037                 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
3038                 case LSA_POLICY_INFO_DNS_INT:
3039                 case LSA_POLICY_INFO_DNS:
3040                         if (torture_setting_bool(tctx, "samba3", false)) {
3041                                 /* Other levels not implemented yet */
3042                                 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_INFO_CLASS)) {
3043                                         torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
3044                                         ret = false;
3045                                 }
3046                         } else if (!NT_STATUS_IS_OK(r.out.result)) {
3047                                 torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
3048                                 ret = false;
3049                         }
3050                         break;
3051                 default:
3052                         if (torture_setting_bool(tctx, "samba4", false)) {
3053                                 /* Other levels not implemented yet */
3054                                 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_INFO_CLASS)) {
3055                                         torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
3056                                         ret = false;
3057                                 }
3058                         } else if (!NT_STATUS_IS_OK(r.out.result)) {
3059                                 torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
3060                                 ret = false;
3061                         }
3062                         break;
3063                 }
3064
3065                 if (NT_STATUS_IS_OK(r.out.result) && (i == LSA_POLICY_INFO_DNS
3066                         || i == LSA_POLICY_INFO_DNS_INT)) {
3067                         /* Let's look up some of these names */
3068
3069                         struct lsa_TransNameArray tnames;
3070                         tnames.count = 14;
3071                         tnames.names = talloc_zero_array(tctx, struct lsa_TranslatedName, tnames.count);
3072                         tnames.names[0].name.string = info->dns.name.string;
3073                         tnames.names[0].sid_type = SID_NAME_DOMAIN;
3074                         tnames.names[1].name.string = info->dns.dns_domain.string;
3075                         tnames.names[1].sid_type = SID_NAME_DOMAIN;
3076                         tnames.names[2].name.string = talloc_asprintf(tctx, "%s\\", info->dns.name.string);
3077                         tnames.names[2].sid_type = SID_NAME_DOMAIN;
3078                         tnames.names[3].name.string = talloc_asprintf(tctx, "%s\\", info->dns.dns_domain.string);
3079                         tnames.names[3].sid_type = SID_NAME_DOMAIN;
3080                         tnames.names[4].name.string = talloc_asprintf(tctx, "%s\\guest", info->dns.name.string);
3081                         tnames.names[4].sid_type = SID_NAME_USER;
3082                         tnames.names[5].name.string = talloc_asprintf(tctx, "%s\\krbtgt", info->dns.name.string);
3083                         tnames.names[5].sid_type = SID_NAME_USER;
3084                         tnames.names[6].name.string = talloc_asprintf(tctx, "%s\\guest", info->dns.dns_domain.string);
3085                         tnames.names[6].sid_type = SID_NAME_USER;
3086                         tnames.names[7].name.string = talloc_asprintf(tctx, "%s\\krbtgt", info->dns.dns_domain.string);
3087                         tnames.names[7].sid_type = SID_NAME_USER;
3088                         tnames.names[8].name.string = talloc_asprintf(tctx, "krbtgt@%s", info->dns.name.string);
3089                         tnames.names[8].sid_type = SID_NAME_USER;
3090                         tnames.names[9].name.string = talloc_asprintf(tctx, "krbtgt@%s", info->dns.dns_domain.string);
3091                         tnames.names[9].sid_type = SID_NAME_USER;
3092                         tnames.names[10].name.string = talloc_asprintf(tctx, "%s\\"TEST_MACHINENAME "$", info->dns.name.string);
3093                         tnames.names[10].sid_type = SID_NAME_USER;
3094                         tnames.names[11].name.string = talloc_asprintf(tctx, "%s\\"TEST_MACHINENAME "$", info->dns.dns_domain.string);
3095                         tnames.names[11].sid_type = SID_NAME_USER;
3096                         tnames.names[12].name.string = talloc_asprintf(tctx, TEST_MACHINENAME "$@%s", info->dns.name.string);
3097                         tnames.names[12].sid_type = SID_NAME_USER;
3098                         tnames.names[13].name.string = talloc_asprintf(tctx, TEST_MACHINENAME "$@%s", info->dns.dns_domain.string);
3099                         tnames.names[13].sid_type = SID_NAME_USER;
3100                         ret &= test_LookupNames(b, tctx, handle, &tnames);
3101
3102                 }
3103         }
3104
3105         return ret;
3106 }
3107
3108 static bool test_QueryInfoPolicy(struct dcerpc_binding_handle *b,
3109                                  struct torture_context *tctx,
3110                                  struct policy_handle *handle)
3111 {
3112         return test_QueryInfoPolicyCalls(false, b, tctx, handle);
3113 }
3114
3115 static bool test_QueryInfoPolicy2(struct dcerpc_binding_handle *b,
3116                                   struct torture_context *tctx,
3117                                   struct policy_handle *handle)
3118 {
3119         return test_QueryInfoPolicyCalls(true, b, tctx, handle);
3120 }
3121
3122 static bool test_GetUserName(struct dcerpc_binding_handle *b,
3123                              struct torture_context *tctx)
3124 {
3125         struct lsa_GetUserName r;
3126         bool ret = true;
3127         struct lsa_String *authority_name_p = NULL;
3128         struct lsa_String *account_name_p = NULL;
3129
3130         torture_comment(tctx, "\nTesting GetUserName\n");
3131
3132         r.in.system_name        = "\\";
3133         r.in.account_name       = &account_name_p;
3134         r.in.authority_name     = NULL;
3135         r.out.account_name      = &account_name_p;
3136
3137         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetUserName_r(b, tctx, &r),
3138                 "GetUserName failed");
3139
3140         if (!NT_STATUS_IS_OK(r.out.result)) {
3141                 torture_comment(tctx, "GetUserName failed - %s\n", nt_errstr(r.out.result));
3142                 ret = false;
3143         }
3144
3145         account_name_p = NULL;
3146         r.in.account_name       = &account_name_p;
3147         r.in.authority_name     = &authority_name_p;
3148         r.out.account_name      = &account_name_p;
3149
3150         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetUserName_r(b, tctx, &r),
3151                 "GetUserName failed");
3152
3153         if (!NT_STATUS_IS_OK(r.out.result)) {
3154                 torture_comment(tctx, "GetUserName failed - %s\n", nt_errstr(r.out.result));
3155                 ret = false;
3156         }
3157
3158         return ret;
3159 }
3160
3161 bool test_lsa_Close(struct dcerpc_binding_handle *b,
3162                     struct torture_context *tctx,
3163                     struct policy_handle *handle)
3164 {
3165         struct lsa_Close r;
3166         struct policy_handle handle2;
3167
3168         torture_comment(tctx, "\nTesting Close\n");
3169
3170         r.in.handle = handle;
3171         r.out.handle = &handle2;
3172
3173         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Close_r(b, tctx, &r),
3174                 "Close failed");
3175         if (!NT_STATUS_IS_OK(r.out.result)) {
3176                 torture_comment(tctx, "Close failed - %s\n",
3177                 nt_errstr(r.out.result));
3178                 return false;
3179         }
3180
3181         torture_assert_ntstatus_equal(tctx, dcerpc_lsa_Close_r(b, tctx, &r),
3182                 NT_STATUS_RPC_SS_CONTEXT_MISMATCH, "Close should failed");
3183
3184         torture_comment(tctx, "\n");
3185
3186         return true;
3187 }
3188
3189 bool torture_rpc_lsa(struct torture_context *tctx)
3190 {
3191         NTSTATUS status;
3192         struct dcerpc_pipe *p;
3193         bool ret = true;
3194         struct policy_handle *handle = NULL;
3195         struct test_join *join = NULL;
3196         struct cli_credentials *machine_creds;
3197         struct dcerpc_binding_handle *b;
3198
3199         status = torture_rpc_connection(tctx, &p, &ndr_table_lsarpc);
3200         if (!NT_STATUS_IS_OK(status)) {
3201                 return false;
3202         }
3203         b = p->binding_handle;
3204
3205         /* Test lsaLookupSids3 and lsaLookupNames4 over tcpip */
3206         if (p->binding->transport == NCACN_IP_TCP) {
3207                 if (!test_OpenPolicy(b, tctx, true)) {
3208                         ret = false;
3209                 }
3210
3211                 if (!test_lsa_OpenPolicy2_ex(b, tctx, &handle,
3212                                              NT_STATUS_OK, true)) {
3213                         ret = false;
3214                 }
3215
3216                 if (!test_many_LookupSids(p, tctx, handle)) {
3217                         ret = false;
3218                 }
3219
3220                 return ret;
3221         }
3222
3223         if (!test_OpenPolicy(b, tctx, false)) {
3224                 ret = false;
3225         }
3226
3227         if (!test_lsa_OpenPolicy2(b, tctx, &handle)) {
3228                 ret = false;
3229         }
3230
3231         if (handle) {
3232                 join = torture_join_domain(tctx, TEST_MACHINENAME, ACB_WSTRUST, &machine_creds);
3233                 if (!join) {
3234                         ret = false;
3235                 }
3236
3237                 if (!test_LookupSids_async(b, tctx, handle)) {
3238                         ret = false;
3239                 }
3240
3241                 if (!test_QueryDomainInfoPolicy(b, tctx, handle)) {
3242                         ret = false;
3243                 }
3244
3245                 if (!test_CreateSecret(p, tctx, handle)) {
3246                         ret = false;
3247                 }
3248
3249                 if (!test_QueryInfoPolicy(b, tctx, handle)) {
3250                         ret = false;
3251                 }
3252
3253                 if (!test_QueryInfoPolicy2(b, tctx, handle)) {
3254                         ret = false;
3255                 }
3256
3257                 if (!test_Delete(b, tctx, handle)) {
3258                         ret = false;
3259                 }
3260
3261                 if (!test_many_LookupSids(p, tctx, handle)) {
3262                         ret = false;
3263                 }
3264
3265                 if (!test_lsa_Close(b, tctx, handle)) {
3266                         ret = false;
3267                 }
3268
3269                 torture_leave_domain(tctx, join);
3270
3271         } else {
3272                 if (!test_many_LookupSids(p, tctx, handle)) {
3273                         ret = false;
3274                 }
3275         }
3276
3277         if (!test_GetUserName(b, tctx)) {
3278                 ret = false;
3279         }
3280
3281         return ret;
3282 }
3283
3284 bool torture_rpc_lsa_get_user(struct torture_context *tctx)
3285 {
3286         NTSTATUS status;
3287         struct dcerpc_pipe *p;
3288         bool ret = true;
3289         struct dcerpc_binding_handle *b;
3290
3291         status = torture_rpc_connection(tctx, &p, &ndr_table_lsarpc);
3292         if (!NT_STATUS_IS_OK(status)) {
3293                 return false;
3294         }
3295         b = p->binding_handle;
3296
3297         if (!test_GetUserName(b, tctx)) {
3298                 ret = false;
3299         }
3300
3301         return ret;
3302 }
3303
3304 static bool testcase_LookupNames(struct torture_context *tctx,
3305                                  struct dcerpc_pipe *p)
3306 {
3307         bool ret = true;
3308         struct policy_handle *handle;
3309         struct lsa_TransNameArray tnames;
3310         struct lsa_TransNameArray2 tnames2;
3311         struct dcerpc_binding_handle *b = p->binding_handle;
3312
3313         if (p->binding->transport != NCACN_NP &&
3314             p->binding->transport != NCALRPC) {
3315                 torture_comment(tctx, "testcase_LookupNames is only available "
3316                                 "over NCACN_NP or NCALRPC");
3317                 return true;
3318         }
3319
3320         if (!test_OpenPolicy(b, tctx, false)) {
3321                 ret = false;
3322         }
3323
3324         if (!test_lsa_OpenPolicy2(b, tctx, &handle)) {
3325                 ret = false;
3326         }
3327
3328         if (!handle) {
3329                 ret = false;
3330         }
3331
3332         tnames.count = 1;
3333         tnames.names = talloc_array(tctx, struct lsa_TranslatedName, tnames.count);
3334         ZERO_STRUCT(tnames.names[0]);
3335         tnames.names[0].name.string = "BUILTIN";
3336         tnames.names[0].sid_type = SID_NAME_DOMAIN;
3337
3338         if (!test_LookupNames(b, tctx, handle, &tnames)) {
3339                 ret = false;
3340         }
3341
3342         tnames2.count = 1;
3343         tnames2.names = talloc_array(tctx, struct lsa_TranslatedName2, tnames2.count);
3344         ZERO_STRUCT(tnames2.names[0]);
3345         tnames2.names[0].name.string = "BUILTIN";
3346         tnames2.names[0].sid_type = SID_NAME_DOMAIN;
3347
3348         if (!test_LookupNames2(b, tctx, handle, &tnames2, true)) {
3349                 ret = false;
3350         }
3351
3352         if (!test_LookupNames3(b, tctx, handle, &tnames2, true)) {
3353                 ret = false;
3354         }
3355
3356         if (!test_LookupNames_wellknown(b, tctx, handle)) {
3357                 ret = false;
3358         }
3359
3360         if (!test_LookupNames_NULL(b, tctx, handle)) {
3361                 ret = false;
3362         }
3363
3364         if (!test_LookupNames_bogus(b, tctx, handle)) {
3365                 ret = false;
3366         }
3367
3368         if (!test_lsa_Close(b, tctx, handle)) {
3369                 ret = false;
3370         }
3371
3372         return ret;
3373 }
3374
3375 struct torture_suite *torture_rpc_lsa_lookup_names(TALLOC_CTX *mem_ctx)
3376 {
3377         struct torture_suite *suite;
3378         struct torture_rpc_tcase *tcase;
3379
3380         suite = torture_suite_create(mem_ctx, "lsa.lookupnames");
3381
3382         tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa",
3383                                                   &ndr_table_lsarpc);
3384         torture_rpc_tcase_add_test(tcase, "LookupNames",
3385                                    testcase_LookupNames);
3386
3387         return suite;
3388 }
3389
3390 struct lsa_trustdom_state {
3391         uint32_t num_trusts;
3392 };
3393
3394 static bool testcase_TrustedDomains(struct torture_context *tctx,
3395                                     struct dcerpc_pipe *p,
3396                                     void *data)
3397 {
3398         bool ret = true;
3399         struct policy_handle *handle;
3400         struct lsa_trustdom_state *state =
3401                 talloc_get_type_abort(data, struct lsa_trustdom_state);
3402         struct dcerpc_binding_handle *b = p->binding_handle;
3403
3404         if (p->binding->transport != NCACN_NP &&
3405             p->binding->transport != NCALRPC) {
3406                 torture_comment(tctx, "testcase_TrustedDomains is only available "
3407                                 "over NCACN_NP or NCALRPC");
3408                 return true;
3409         }
3410
3411         torture_comment(tctx, "Testing %d domains\n", state->num_trusts);
3412
3413         if (!test_OpenPolicy(b, tctx, false)) {
3414                 ret = false;
3415         }
3416
3417         if (!test_lsa_OpenPolicy2(b, tctx, &handle)) {
3418                 ret = false;
3419         }
3420
3421         if (!handle) {
3422                 ret = false;
3423         }
3424
3425         if (!test_CreateTrustedDomain(b, tctx, handle, state->num_trusts)) {
3426                 ret = false;
3427         }
3428
3429         if (!test_CreateTrustedDomainEx(p, tctx, handle, state->num_trusts)) {
3430                 ret = false;
3431         }
3432
3433         if (!test_CreateTrustedDomainEx2(p, tctx, handle, state->num_trusts)) {
3434                 ret = false;
3435         }
3436
3437         if (!test_lsa_Close(b, tctx, handle)) {
3438                 ret = false;
3439         }
3440
3441         return ret;
3442 }
3443
3444 struct torture_suite *torture_rpc_lsa_trusted_domains(TALLOC_CTX *mem_ctx)
3445 {
3446         struct torture_suite *suite;
3447         struct torture_rpc_tcase *tcase;
3448         struct lsa_trustdom_state *state;
3449
3450         state = talloc(mem_ctx, struct lsa_trustdom_state);
3451
3452         state->num_trusts = 12;
3453
3454         suite = torture_suite_create(mem_ctx, "lsa.trusted.domains");
3455
3456         tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa",
3457                                                   &ndr_table_lsarpc);
3458         torture_rpc_tcase_add_test_ex(tcase, "TrustedDomains",
3459                                       testcase_TrustedDomains,
3460                                       state);
3461
3462         return suite;
3463 }
3464
3465 static bool testcase_Privileges(struct torture_context *tctx,
3466                                 struct dcerpc_pipe *p)
3467 {
3468         bool ret = true;
3469         struct policy_handle *handle;
3470         struct dcerpc_binding_handle *b = p->binding_handle;
3471
3472         if (p->binding->transport != NCACN_NP &&
3473             p->binding->transport != NCALRPC) {
3474                 torture_comment(tctx, "testcase_Privileges is only available "
3475                                 "over NCACN_NP or NCALRPC");
3476                 return true;
3477         }
3478
3479         if (!test_OpenPolicy(b, tctx, false)) {
3480                 ret = false;
3481         }
3482
3483         if (!test_lsa_OpenPolicy2(b, tctx, &handle)) {
3484                 ret = false;
3485         }
3486
3487         if (!handle) {
3488                 ret = false;
3489         }
3490
3491         if (!test_CreateAccount(b, tctx, handle)) {
3492                 ret = false;
3493         }
3494
3495         if (!test_EnumAccounts(b, tctx, handle)) {
3496                 ret = false;
3497         }
3498
3499         if (!test_EnumPrivs(b, tctx, handle)) {
3500                 ret = false;
3501         }
3502
3503         if (!test_lsa_Close(b, tctx, handle)) {
3504                 ret = false;
3505         }
3506
3507         return ret;
3508 }
3509
3510
3511 struct torture_suite *torture_rpc_lsa_privileges(TALLOC_CTX *mem_ctx)
3512 {
3513         struct torture_suite *suite;
3514         struct torture_rpc_tcase *tcase;
3515
3516         suite = torture_suite_create(mem_ctx, "lsa.privileges");
3517
3518         tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa",
3519                                                   &ndr_table_lsarpc);
3520         torture_rpc_tcase_add_test(tcase, "Privileges",
3521                                    testcase_Privileges);
3522
3523         return suite;
3524 }