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