s4:torture/rpc: make use of dcerpc_binding_handle_auth_info() in lsa.c
[kai/samba-autobuild/.git] / source4 / torture / rpc / lsa.c
1 /*
2    Unix SMB/CIFS implementation.
3    test suite for lsa rpc operations
4
5    Copyright (C) Andrew Tridgell 2003
6    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2005
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "torture/torture.h"
24 #include "librpc/gen_ndr/ndr_lsa_c.h"
25 #include "librpc/gen_ndr/netlogon.h"
26 #include "librpc/gen_ndr/ndr_drsblobs.h"
27 #include "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.unknown = 0;
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 & NETR_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 resume_handle = 0;
2405         struct lsa_DomainListEx domains_ex;
2406         bool ret = true;
2407
2408         torture_comment(tctx, "\nTesting EnumTrustedDomainsEx\n");
2409
2410         r_ex.in.handle = handle;
2411         r_ex.in.resume_handle = &resume_handle;
2412         r_ex.in.max_size = LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER * 3;
2413         r_ex.out.domains = &domains_ex;
2414         r_ex.out.resume_handle = &resume_handle;
2415
2416         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustedDomainsEx_r(b, tctx, &r_ex),
2417                 "EnumTrustedDomainsEx failed");
2418
2419         if (!(NT_STATUS_EQUAL(r_ex.out.result, STATUS_MORE_ENTRIES) || NT_STATUS_EQUAL(r_ex.out.result, NT_STATUS_NO_MORE_ENTRIES))) {
2420                 torture_comment(tctx, "EnumTrustedDomainEx of zero size failed - %s\n", nt_errstr(r_ex.out.result));
2421                 return false;
2422         }
2423
2424         resume_handle = 0;
2425         do {
2426                 r_ex.in.handle = handle;
2427                 r_ex.in.resume_handle = &resume_handle;
2428                 r_ex.in.max_size = LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER * 3;
2429                 r_ex.out.domains = &domains_ex;
2430                 r_ex.out.resume_handle = &resume_handle;
2431
2432                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustedDomainsEx_r(b, tctx, &r_ex),
2433                         "EnumTrustedDomainsEx failed");
2434
2435                 /* NO_MORE_ENTRIES is allowed */
2436                 if (NT_STATUS_EQUAL(r_ex.out.result, NT_STATUS_NO_MORE_ENTRIES)) {
2437                         if (domains_ex.count == 0) {
2438                                 return true;
2439                         }
2440                         torture_comment(tctx, "EnumTrustDomainsEx failed - should have returned 0 trusted domains with 'NT_STATUS_NO_MORE_ENTRIES'\n");
2441                         return false;
2442                 } else if (NT_STATUS_EQUAL(r_ex.out.result, STATUS_MORE_ENTRIES)) {
2443                         /* Windows 2003 gets this off by one on the first run */
2444                         if (r_ex.out.domains->count < 3 || r_ex.out.domains->count > 4) {
2445                                 torture_comment(tctx, "EnumTrustDom didn't fill the buffer we "
2446                                        "asked it to (got %d, expected %d / %d == %d entries)\n",
2447                                        r_ex.out.domains->count,
2448                                        r_ex.in.max_size,
2449                                        LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER,
2450                                        r_ex.in.max_size / LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER);
2451                         }
2452                 } else if (!NT_STATUS_IS_OK(r_ex.out.result)) {
2453                         torture_comment(tctx, "EnumTrustedDomainEx failed - %s\n", nt_errstr(r_ex.out.result));
2454                         return false;
2455                 }
2456
2457                 if (domains_ex.count == 0) {
2458                         torture_comment(tctx, "EnumTrustDomainEx failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
2459                         return false;
2460                 }
2461
2462                 ret &= test_query_each_TrustDomEx(b, tctx, handle, &domains_ex);
2463
2464         } while ((NT_STATUS_EQUAL(r_ex.out.result, STATUS_MORE_ENTRIES)));
2465
2466         return ret;
2467 }
2468
2469
2470 static bool test_CreateTrustedDomain(struct dcerpc_binding_handle *b,
2471                                      struct torture_context *tctx,
2472                                      struct policy_handle *handle,
2473                                      uint32_t num_trusts)
2474 {
2475         bool ret = true;
2476         struct lsa_CreateTrustedDomain r;
2477         struct lsa_DomainInfo trustinfo;
2478         struct dom_sid **domsid;
2479         struct policy_handle *trustdom_handle;
2480         struct lsa_QueryTrustedDomainInfo q;
2481         union lsa_TrustedDomainInfo *info = NULL;
2482         int i;
2483
2484         torture_comment(tctx, "\nTesting CreateTrustedDomain for %d domains\n", num_trusts);
2485
2486         if (!test_EnumTrustDom(b, tctx, handle)) {
2487                 ret = false;
2488         }
2489
2490         if (!test_EnumTrustDomEx(b, tctx, handle)) {
2491                 ret = false;
2492         }
2493
2494         domsid = talloc_array(tctx, struct dom_sid *, num_trusts);
2495         trustdom_handle = talloc_array(tctx, struct policy_handle, num_trusts);
2496
2497         for (i=0; i< num_trusts; i++) {
2498                 char *trust_name = talloc_asprintf(tctx, "torturedom%02d", i);
2499                 char *trust_sid = talloc_asprintf(tctx, "S-1-5-21-97398-379795-100%02d", i);
2500
2501                 domsid[i] = dom_sid_parse_talloc(tctx, trust_sid);
2502
2503                 trustinfo.sid = domsid[i];
2504                 init_lsa_String((struct lsa_String *)&trustinfo.name, trust_name);
2505
2506                 r.in.policy_handle = handle;
2507                 r.in.info = &trustinfo;
2508                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2509                 r.out.trustdom_handle = &trustdom_handle[i];
2510
2511                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CreateTrustedDomain_r(b, tctx, &r),
2512                         "CreateTrustedDomain failed");
2513                 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_OBJECT_NAME_COLLISION)) {
2514                         test_DeleteTrustedDomain(b, tctx, handle, trustinfo.name);
2515                         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CreateTrustedDomain_r(b, tctx, &r),
2516                                 "CreateTrustedDomain failed");
2517                 }
2518                 if (!NT_STATUS_IS_OK(r.out.result)) {
2519                         torture_comment(tctx, "CreateTrustedDomain failed - %s\n", nt_errstr(r.out.result));
2520                         ret = false;
2521                 } else {
2522
2523                         q.in.trustdom_handle = &trustdom_handle[i];
2524                         q.in.level = LSA_TRUSTED_DOMAIN_INFO_INFO_EX;
2525                         q.out.info = &info;
2526                         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfo_r(b, tctx, &q),
2527                                 "QueryTrustedDomainInfo failed");
2528                         if (!NT_STATUS_IS_OK(q.out.result)) {
2529                                 torture_comment(tctx, "QueryTrustedDomainInfo level %d failed - %s\n", q.in.level, nt_errstr(q.out.result));
2530                                 ret = false;
2531                         } else if (!q.out.info) {
2532                                 ret = false;
2533                         } else {
2534                                 if (strcmp(info->info_ex.netbios_name.string, trustinfo.name.string) != 0) {
2535                                         torture_comment(tctx, "QueryTrustedDomainInfo returned inconsistent short name: %s != %s\n",
2536                                                info->info_ex.netbios_name.string, trustinfo.name.string);
2537                                         ret = false;
2538                                 }
2539                                 if (info->info_ex.trust_type != LSA_TRUST_TYPE_DOWNLEVEL) {
2540                                         torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n",
2541                                                trust_name, info->info_ex.trust_type, LSA_TRUST_TYPE_DOWNLEVEL);
2542                                         ret = false;
2543                                 }
2544                                 if (info->info_ex.trust_attributes != 0) {
2545                                         torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n",
2546                                                trust_name, info->info_ex.trust_attributes, 0);
2547                                         ret = false;
2548                                 }
2549                                 if (info->info_ex.trust_direction != LSA_TRUST_DIRECTION_OUTBOUND) {
2550                                         torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n",
2551                                                trust_name, info->info_ex.trust_direction, LSA_TRUST_DIRECTION_OUTBOUND);
2552                                         ret = false;
2553                                 }
2554                         }
2555                 }
2556         }
2557
2558         /* now that we have some domains to look over, we can test the enum calls */
2559         if (!test_EnumTrustDom(b, tctx, handle)) {
2560                 ret = false;
2561         }
2562
2563         if (!test_EnumTrustDomEx(b, tctx, handle)) {
2564                 ret = false;
2565         }
2566
2567         for (i=0; i<num_trusts; i++) {
2568                 if (!test_DeleteTrustedDomainBySid(b, tctx, handle, domsid[i])) {
2569                         ret = false;
2570                 }
2571         }
2572
2573         return ret;
2574 }
2575
2576 static bool gen_authinfo_internal(TALLOC_CTX *mem_ctx, const char *password,
2577                                   DATA_BLOB session_key,
2578                                   struct lsa_TrustDomainInfoAuthInfoInternal **_authinfo_internal)
2579 {
2580         struct lsa_TrustDomainInfoAuthInfoInternal *authinfo_internal;
2581         struct trustDomainPasswords auth_struct;
2582         struct AuthenticationInformation *auth_info_array;
2583         size_t converted_size;
2584         DATA_BLOB auth_blob;
2585         enum ndr_err_code ndr_err;
2586
2587         authinfo_internal = talloc_zero(mem_ctx, struct lsa_TrustDomainInfoAuthInfoInternal);
2588         if (authinfo_internal == NULL) {
2589                 return false;
2590         }
2591
2592         auth_info_array = talloc_array(mem_ctx,
2593                                        struct AuthenticationInformation, 1);
2594         if (auth_info_array == NULL) {
2595                 return false;
2596         }
2597
2598         generate_random_buffer(auth_struct.confounder, sizeof(auth_struct.confounder));
2599
2600         auth_info_array[0].AuthType = TRUST_AUTH_TYPE_CLEAR;
2601
2602         if (!convert_string_talloc(mem_ctx, CH_UNIX, CH_UTF16, password,
2603                                   strlen(password),
2604                                   &auth_info_array[0].AuthInfo.clear.password,
2605                                   &converted_size)) {
2606                 return false;
2607         }
2608
2609         auth_info_array[0].AuthInfo.clear.size = converted_size;
2610
2611         auth_struct.outgoing.count = 1;
2612         auth_struct.outgoing.current.count = 1;
2613         auth_struct.outgoing.current.array = auth_info_array;
2614         auth_struct.outgoing.previous.count = 0;
2615         auth_struct.outgoing.previous.array = NULL;
2616
2617         auth_struct.incoming.count = 1;
2618         auth_struct.incoming.current.count = 1;
2619         auth_struct.incoming.current.array = auth_info_array;
2620         auth_struct.incoming.previous.count = 0;
2621         auth_struct.incoming.previous.array = NULL;
2622
2623
2624         ndr_err = ndr_push_struct_blob(&auth_blob, mem_ctx, &auth_struct,
2625                                        (ndr_push_flags_fn_t)ndr_push_trustDomainPasswords);
2626         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2627                 return false;
2628         }
2629
2630         arcfour_crypt_blob(auth_blob.data, auth_blob.length, &session_key);
2631
2632         authinfo_internal->auth_blob.size = auth_blob.length;
2633         authinfo_internal->auth_blob.data = auth_blob.data;
2634
2635         *_authinfo_internal = authinfo_internal;
2636
2637         return true;
2638 }
2639
2640 static bool gen_authinfo(TALLOC_CTX *mem_ctx, const char *password,
2641                          struct lsa_TrustDomainInfoAuthInfo **_authinfo)
2642 {
2643         struct lsa_TrustDomainInfoAuthInfo *authinfo;
2644         struct lsa_TrustDomainInfoBuffer *info_buffer;
2645         size_t converted_size;
2646
2647         authinfo = talloc_zero(mem_ctx, struct lsa_TrustDomainInfoAuthInfo);
2648         if (authinfo == NULL) {
2649                 return false;
2650         }
2651
2652         info_buffer = talloc_zero(mem_ctx, struct lsa_TrustDomainInfoBuffer);
2653         if (info_buffer == NULL) {
2654                 return false;
2655         }
2656
2657         info_buffer->AuthType = TRUST_AUTH_TYPE_CLEAR;
2658
2659         if (!convert_string_talloc(mem_ctx, CH_UNIX, CH_UTF16, password,
2660                                   strlen(password),
2661                                   &info_buffer->data.data,
2662                                   &converted_size)) {
2663                 return false;
2664         }
2665
2666         info_buffer->data.size = converted_size;
2667
2668         authinfo->incoming_count = 1;
2669         authinfo->incoming_current_auth_info = info_buffer;
2670         authinfo->incoming_previous_auth_info = NULL;
2671         authinfo->outgoing_count = 1;
2672         authinfo->outgoing_current_auth_info = info_buffer;
2673         authinfo->outgoing_previous_auth_info = NULL;
2674
2675         *_authinfo = authinfo;
2676
2677         return true;
2678 }
2679
2680 static bool check_pw_with_ServerAuthenticate3(struct dcerpc_pipe *p,
2681                                              struct torture_context *tctx,
2682                                              uint32_t negotiate_flags,
2683                                              struct cli_credentials *machine_credentials,
2684                                              struct netlogon_creds_CredentialState **creds_out)
2685 {
2686         struct netr_ServerReqChallenge r;
2687         struct netr_ServerAuthenticate3 a;
2688         struct netr_Credential credentials1, credentials2, credentials3;
2689         struct netlogon_creds_CredentialState *creds;
2690         struct samr_Password mach_password;
2691         uint32_t rid;
2692         const char *machine_name;
2693         const char *plain_pass;
2694         struct dcerpc_binding_handle *b = p->binding_handle;
2695
2696         machine_name = cli_credentials_get_workstation(machine_credentials);
2697         plain_pass = cli_credentials_get_password(machine_credentials);
2698
2699         r.in.server_name = NULL;
2700         r.in.computer_name = machine_name;
2701         r.in.credentials = &credentials1;
2702         r.out.return_credentials = &credentials2;
2703
2704         generate_random_buffer(credentials1.data, sizeof(credentials1.data));
2705
2706         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
2707                 "ServerReqChallenge failed");
2708         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
2709
2710         E_md4hash(plain_pass, mach_password.hash);
2711
2712         a.in.server_name = NULL;
2713         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
2714         a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2715         a.in.computer_name = machine_name;
2716         a.in.negotiate_flags = &negotiate_flags;
2717         a.in.credentials = &credentials3;
2718         a.out.return_credentials = &credentials3;
2719         a.out.negotiate_flags = &negotiate_flags;
2720         a.out.rid = &rid;
2721
2722         creds = netlogon_creds_client_init(tctx, a.in.account_name,
2723                                            a.in.computer_name,
2724                                            a.in.secure_channel_type,
2725                                            &credentials1, &credentials2,
2726                                            &mach_password, &credentials3,
2727                                            negotiate_flags);
2728
2729         torture_assert(tctx, creds != NULL, "memory allocation");
2730
2731         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
2732                 "ServerAuthenticate3 failed");
2733         if (!NT_STATUS_IS_OK(a.out.result)) {
2734                 if (!NT_STATUS_EQUAL(a.out.result, NT_STATUS_ACCESS_DENIED)) {
2735                         torture_assert_ntstatus_ok(tctx, a.out.result,
2736                                                    "ServerAuthenticate3 failed");
2737                 }
2738                 return false;
2739         }
2740         torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
2741
2742         /* Prove that requesting a challenge again won't break it */
2743         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
2744                 "ServerReqChallenge failed");
2745         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
2746
2747         *creds_out = creds;
2748         return true;
2749 }
2750
2751 static bool check_dom_trust_pw(struct dcerpc_pipe *p,
2752                                struct torture_context *tctx,
2753                                const char *trusted_dom_name,
2754                                const char *password)
2755 {
2756         struct cli_credentials *credentials;
2757         char *dummy;
2758         struct netlogon_creds_CredentialState *creds;
2759         struct dcerpc_pipe *pipe;
2760         NTSTATUS status;
2761         bool ok;
2762
2763         credentials = cli_credentials_init(tctx);
2764         if (credentials == NULL) {
2765                 return false;
2766         }
2767
2768         dummy = talloc_asprintf(tctx, "%s$", trusted_dom_name);
2769         if (dummy == NULL) {
2770                 return false;
2771         }
2772
2773         cli_credentials_set_username(credentials, dummy, CRED_SPECIFIED);
2774         cli_credentials_set_password(credentials, password, CRED_SPECIFIED);
2775         cli_credentials_set_workstation(credentials,
2776                                         trusted_dom_name, CRED_SPECIFIED);
2777         cli_credentials_set_secure_channel_type(credentials, SEC_CHAN_DOMAIN);
2778
2779         status = dcerpc_pipe_connect_b(tctx, &pipe, p->binding,
2780                                        &ndr_table_netlogon,
2781                                        cli_credentials_init_anon(tctx),
2782                                        tctx->ev, tctx->lp_ctx);
2783         if (!NT_STATUS_IS_OK(status)) {
2784                 torture_comment(tctx, "dcerpc_pipe_connect_b failed.\n");
2785                 return false;
2786         }
2787
2788         ok = check_pw_with_ServerAuthenticate3(pipe, tctx,
2789                                                NETLOGON_NEG_AUTH2_ADS_FLAGS,
2790                                                credentials, &creds);
2791         talloc_free(pipe);
2792
2793         return ok;
2794 }
2795
2796 static bool test_CreateTrustedDomainEx_common(struct dcerpc_pipe *p,
2797                                               struct torture_context *tctx,
2798                                               struct policy_handle *handle,
2799                                               uint32_t num_trusts,
2800                                               bool ex2_call)
2801 {
2802         NTSTATUS status;
2803         bool ret = true;
2804         struct lsa_CreateTrustedDomainEx r;
2805         struct lsa_CreateTrustedDomainEx2 r2;
2806         struct lsa_TrustDomainInfoInfoEx trustinfo;
2807         struct lsa_TrustDomainInfoAuthInfoInternal *authinfo_internal;
2808         struct lsa_TrustDomainInfoAuthInfo *authinfo;
2809         struct dom_sid **domsid;
2810         struct policy_handle *trustdom_handle;
2811         struct lsa_QueryTrustedDomainInfo q;
2812         union lsa_TrustedDomainInfo *info = NULL;
2813         DATA_BLOB session_key;
2814         int i;
2815         struct dcerpc_binding_handle *b = p->binding_handle;
2816
2817         if (ex2_call) {
2818                 torture_comment(tctx, "\nTesting CreateTrustedDomainEx2 for %d domains\n", num_trusts);
2819         } else {
2820                 torture_comment(tctx, "\nTesting CreateTrustedDomainEx for %d domains\n", num_trusts);
2821         }
2822
2823         domsid = talloc_array(tctx, struct dom_sid *, num_trusts);
2824         trustdom_handle = talloc_array(tctx, struct policy_handle, num_trusts);
2825
2826         status = dcerpc_fetch_session_key(p, &session_key);
2827         if (!NT_STATUS_IS_OK(status)) {
2828                 torture_comment(tctx, "dcerpc_fetch_session_key failed - %s\n", nt_errstr(status));
2829                 return false;
2830         }
2831
2832         for (i=0; i< num_trusts; i++) {
2833                 char *trust_name = talloc_asprintf(tctx, "torturedom%02d", i);
2834                 char *trust_name_dns = talloc_asprintf(tctx, "torturedom%02d.samba.example.com", i);
2835                 char *trust_sid = talloc_asprintf(tctx, "S-1-5-21-97398-379795-100%02d", i);
2836
2837                 domsid[i] = dom_sid_parse_talloc(tctx, trust_sid);
2838
2839                 trustinfo.sid = domsid[i];
2840                 trustinfo.netbios_name.string = trust_name;
2841                 trustinfo.domain_name.string = trust_name_dns;
2842
2843                 /* Create inbound, some outbound, and some
2844                  * bi-directional trusts in a repeating pattern based
2845                  * on i */
2846
2847                 /* 1 == inbound, 2 == outbound, 3 == both */
2848                 trustinfo.trust_direction = (i % 3) + 1;
2849
2850                 /* Try different trust types too */
2851
2852                 /* 1 == downlevel (NT4), 2 == uplevel (ADS), 3 == MIT (kerberos but not AD) */
2853                 trustinfo.trust_type = (((i / 3) + 1) % 3) + 1;
2854
2855                 trustinfo.trust_attributes = LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION;
2856
2857                 if (!gen_authinfo_internal(tctx, TRUSTPW, session_key, &authinfo_internal)) {
2858                         torture_comment(tctx, "gen_authinfo_internal failed");
2859                         ret = false;
2860                 }
2861
2862                 if (!gen_authinfo(tctx, TRUSTPW, &authinfo)) {
2863                         torture_comment(tctx, "gen_authinfonfo failed");
2864                         ret = false;
2865                 }
2866
2867                 if (ex2_call) {
2868
2869                         r2.in.policy_handle = handle;
2870                         r2.in.info = &trustinfo;
2871                         r2.in.auth_info_internal = authinfo_internal;
2872                         r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2873                         r2.out.trustdom_handle = &trustdom_handle[i];
2874
2875                         torture_assert_ntstatus_ok(tctx,
2876                                 dcerpc_lsa_CreateTrustedDomainEx2_r(b, tctx, &r2),
2877                                 "CreateTrustedDomainEx2 failed");
2878
2879                         status = r2.out.result;
2880                 } else {
2881
2882                         r.in.policy_handle = handle;
2883                         r.in.info = &trustinfo;
2884                         r.in.auth_info = authinfo;
2885                         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2886                         r.out.trustdom_handle = &trustdom_handle[i];
2887
2888                         torture_assert_ntstatus_ok(tctx,
2889                                 dcerpc_lsa_CreateTrustedDomainEx_r(b, tctx, &r),
2890                                 "CreateTrustedDomainEx failed");
2891
2892                         status = r.out.result;
2893                 }
2894
2895                 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
2896                         test_DeleteTrustedDomain(b, tctx, handle, trustinfo.netbios_name);
2897                         if (ex2_call) {
2898                                 torture_assert_ntstatus_ok(tctx,
2899                                         dcerpc_lsa_CreateTrustedDomainEx2_r(b, tctx, &r2),
2900                                         "CreateTrustedDomainEx2 failed");
2901                                 status = r2.out.result;
2902                         } else {
2903                                 torture_assert_ntstatus_ok(tctx,
2904                                         dcerpc_lsa_CreateTrustedDomainEx_r(b, tctx, &r),
2905                                         "CreateTrustedDomainEx2 failed");
2906                                 status = r.out.result;
2907                         }
2908                 }
2909                 if (!NT_STATUS_IS_OK(status)) {
2910                         torture_comment(tctx, "CreateTrustedDomainEx failed2 - %s\n", nt_errstr(status));
2911                         ret = false;
2912                 } else {
2913                         /* For outbound and MIT trusts there is no trust account */
2914                         if (trustinfo.trust_direction != 2 &&
2915                             trustinfo.trust_type != 3) {
2916
2917                                 if (torture_setting_bool(tctx, "samba3", false) ||
2918                                     torture_setting_bool(tctx, "samba4", false)) {
2919                                         torture_comment(tctx, "skipping trusted domain auth tests against samba");
2920                                 } else {
2921                                         if (check_dom_trust_pw(p, tctx, trust_name,
2922                                                                 "x" TRUSTPW "x")) {
2923                                                 torture_comment(tctx, "Password check passed unexpectedly\n");
2924                                                 ret = false;
2925                                         }
2926                                         if (!check_dom_trust_pw(p, tctx, trust_name,
2927                                                                 TRUSTPW)) {
2928                                                 torture_comment(tctx, "Password check failed\n");
2929                                                 ret = false;
2930                                         }
2931                                 }
2932                         }
2933
2934                         q.in.trustdom_handle = &trustdom_handle[i];
2935                         q.in.level = LSA_TRUSTED_DOMAIN_INFO_INFO_EX;
2936                         q.out.info = &info;
2937                         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfo_r(b, tctx, &q),
2938                                 "QueryTrustedDomainInfo failed");
2939                         if (!NT_STATUS_IS_OK(q.out.result)) {
2940                                 torture_comment(tctx, "QueryTrustedDomainInfo level 1 failed - %s\n", nt_errstr(q.out.result));
2941                                 ret = false;
2942                         } else if (!q.out.info) {
2943                                 torture_comment(tctx, "QueryTrustedDomainInfo level 1 failed to return an info pointer\n");
2944                                 ret = false;
2945                         } else {
2946                                 if (strcmp(info->info_ex.netbios_name.string, trustinfo.netbios_name.string) != 0) {
2947                                         torture_comment(tctx, "QueryTrustedDomainInfo returned inconsistent short name: %s != %s\n",
2948                                                info->info_ex.netbios_name.string, trustinfo.netbios_name.string);
2949                                         ret = false;
2950                                 }
2951                                 if (info->info_ex.trust_type != trustinfo.trust_type) {
2952                                         torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n",
2953                                                trust_name, info->info_ex.trust_type, trustinfo.trust_type);
2954                                         ret = false;
2955                                 }
2956                                 if (info->info_ex.trust_attributes != LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION) {
2957                                         torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n",
2958                                                trust_name, info->info_ex.trust_attributes, LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION);
2959                                         ret = false;
2960                                 }
2961                                 if (info->info_ex.trust_direction != trustinfo.trust_direction) {
2962                                         torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n",
2963                                                trust_name, info->info_ex.trust_direction, trustinfo.trust_direction);
2964                                         ret = false;
2965                                 }
2966                         }
2967                 }
2968         }
2969
2970         /* now that we have some domains to look over, we can test the enum calls */
2971         if (!test_EnumTrustDom(b, tctx, handle)) {
2972                 torture_comment(tctx, "test_EnumTrustDom failed\n");
2973                 ret = false;
2974         }
2975
2976         if (!test_EnumTrustDomEx(b, tctx, handle)) {
2977                 torture_comment(tctx, "test_EnumTrustDomEx failed\n");
2978                 ret = false;
2979         }
2980
2981         for (i=0; i<num_trusts; i++) {
2982                 if (!test_DeleteTrustedDomainBySid(b, tctx, handle, domsid[i])) {
2983                         torture_comment(tctx, "test_DeleteTrustedDomainBySid failed\n");
2984                         ret = false;
2985                 }
2986         }
2987
2988         return ret;
2989 }
2990
2991 static bool test_CreateTrustedDomainEx2(struct dcerpc_pipe *p,
2992                                         struct torture_context *tctx,
2993                                         struct policy_handle *handle,
2994                                         uint32_t num_trusts)
2995 {
2996         return test_CreateTrustedDomainEx_common(p, tctx, handle, num_trusts, true);
2997 }
2998
2999 static bool test_CreateTrustedDomainEx(struct dcerpc_pipe *p,
3000                                        struct torture_context *tctx,
3001                                        struct policy_handle *handle,
3002                                        uint32_t num_trusts)
3003 {
3004         return test_CreateTrustedDomainEx_common(p, tctx, handle, num_trusts, false);
3005 }
3006
3007 static bool test_QueryDomainInfoPolicy(struct dcerpc_binding_handle *b,
3008                                  struct torture_context *tctx,
3009                                  struct policy_handle *handle)
3010 {
3011         struct lsa_QueryDomainInformationPolicy r;
3012         union lsa_DomainInformationPolicy *info = NULL;
3013         int i;
3014         bool ret = true;
3015
3016         if (torture_setting_bool(tctx, "samba3", false)) {
3017                 torture_skip(tctx, "skipping QueryDomainInformationPolicy test\n");
3018         }
3019
3020         torture_comment(tctx, "\nTesting QueryDomainInformationPolicy\n");
3021
3022         for (i=2;i<4;i++) {
3023                 r.in.handle = handle;
3024                 r.in.level = i;
3025                 r.out.info = &info;
3026
3027                 torture_comment(tctx, "\nTrying QueryDomainInformationPolicy level %d\n", i);
3028
3029                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryDomainInformationPolicy_r(b, tctx, &r),
3030                         "QueryDomainInformationPolicy failed");
3031
3032                 /* If the server does not support EFS, then this is the correct return */
3033                 if (i == LSA_DOMAIN_INFO_POLICY_EFS && NT_STATUS_EQUAL(r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
3034                         continue;
3035                 } else if (!NT_STATUS_IS_OK(r.out.result)) {
3036                         torture_comment(tctx, "QueryDomainInformationPolicy failed - %s\n", nt_errstr(r.out.result));
3037                         ret = false;
3038                         continue;
3039                 }
3040         }
3041
3042         return ret;
3043 }
3044
3045
3046 static bool test_QueryInfoPolicyCalls(  bool version2,
3047                                         struct dcerpc_binding_handle *b,
3048                                         struct torture_context *tctx,
3049                                         struct policy_handle *handle)
3050 {
3051         struct lsa_QueryInfoPolicy r;
3052         union lsa_PolicyInformation *info = NULL;
3053         int i;
3054         bool ret = true;
3055         const char *call = talloc_asprintf(tctx, "QueryInfoPolicy%s", version2 ? "2":"");
3056
3057         torture_comment(tctx, "\nTesting %s\n", call);
3058
3059         if (version2 && torture_setting_bool(tctx, "samba3", false)) {
3060                 torture_skip(tctx, "skipping QueryInfoPolicy2 tests\n");
3061         }
3062
3063         for (i=1;i<=14;i++) {
3064                 r.in.handle = handle;
3065                 r.in.level = i;
3066                 r.out.info = &info;
3067
3068                 torture_comment(tctx, "\nTrying %s level %d\n", call, i);
3069
3070                 if (version2)
3071                         /* We can perform the cast, because both types are
3072                            structurally equal */
3073                         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryInfoPolicy2_r(b, tctx,
3074                                  (struct lsa_QueryInfoPolicy2*) &r),
3075                                  "QueryInfoPolicy2 failed");
3076                 else
3077                         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryInfoPolicy_r(b, tctx, &r),
3078                                 "QueryInfoPolicy2 failed");
3079
3080                 switch (i) {
3081                 case LSA_POLICY_INFO_MOD:
3082                 case LSA_POLICY_INFO_AUDIT_FULL_SET:
3083                 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
3084                         if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
3085                                 torture_comment(tctx, "Server should have failed level %u: %s\n", i, nt_errstr(r.out.result));
3086                                 ret = false;
3087                         }
3088                         break;
3089                 case LSA_POLICY_INFO_DOMAIN:
3090                 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
3091                 case LSA_POLICY_INFO_REPLICA:
3092                 case LSA_POLICY_INFO_QUOTA:
3093                 case LSA_POLICY_INFO_ROLE:
3094                 case LSA_POLICY_INFO_AUDIT_LOG:
3095                 case LSA_POLICY_INFO_AUDIT_EVENTS:
3096                 case LSA_POLICY_INFO_PD:
3097                         if (!NT_STATUS_IS_OK(r.out.result)) {
3098                                 torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
3099                                 ret = false;
3100                         }
3101                         break;
3102                 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
3103                 case LSA_POLICY_INFO_DNS_INT:
3104                 case LSA_POLICY_INFO_DNS:
3105                         if (torture_setting_bool(tctx, "samba3", false)) {
3106                                 /* Other levels not implemented yet */
3107                                 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_INFO_CLASS)) {
3108                                         torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
3109                                         ret = false;
3110                                 }
3111                         } else if (!NT_STATUS_IS_OK(r.out.result)) {
3112                                 torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
3113                                 ret = false;
3114                         }
3115                         break;
3116                 default:
3117                         if (torture_setting_bool(tctx, "samba4", false)) {
3118                                 /* Other levels not implemented yet */
3119                                 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_INFO_CLASS)) {
3120                                         torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
3121                                         ret = false;
3122                                 }
3123                         } else if (!NT_STATUS_IS_OK(r.out.result)) {
3124                                 torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
3125                                 ret = false;
3126                         }
3127                         break;
3128                 }
3129
3130                 if (NT_STATUS_IS_OK(r.out.result) && (i == LSA_POLICY_INFO_DNS
3131                         || i == LSA_POLICY_INFO_DNS_INT)) {
3132                         /* Let's look up some of these names */
3133
3134                         struct lsa_TransNameArray tnames;
3135                         tnames.count = 14;
3136                         tnames.names = talloc_zero_array(tctx, struct lsa_TranslatedName, tnames.count);
3137                         tnames.names[0].name.string = info->dns.name.string;
3138                         tnames.names[0].sid_type = SID_NAME_DOMAIN;
3139                         tnames.names[1].name.string = info->dns.dns_domain.string;
3140                         tnames.names[1].sid_type = SID_NAME_DOMAIN;
3141                         tnames.names[2].name.string = talloc_asprintf(tctx, "%s\\", info->dns.name.string);
3142                         tnames.names[2].sid_type = SID_NAME_DOMAIN;
3143                         tnames.names[3].name.string = talloc_asprintf(tctx, "%s\\", info->dns.dns_domain.string);
3144                         tnames.names[3].sid_type = SID_NAME_DOMAIN;
3145                         tnames.names[4].name.string = talloc_asprintf(tctx, "%s\\guest", info->dns.name.string);
3146                         tnames.names[4].sid_type = SID_NAME_USER;
3147                         tnames.names[5].name.string = talloc_asprintf(tctx, "%s\\krbtgt", info->dns.name.string);
3148                         tnames.names[5].sid_type = SID_NAME_USER;
3149                         tnames.names[6].name.string = talloc_asprintf(tctx, "%s\\guest", info->dns.dns_domain.string);
3150                         tnames.names[6].sid_type = SID_NAME_USER;
3151                         tnames.names[7].name.string = talloc_asprintf(tctx, "%s\\krbtgt", info->dns.dns_domain.string);
3152                         tnames.names[7].sid_type = SID_NAME_USER;
3153                         tnames.names[8].name.string = talloc_asprintf(tctx, "krbtgt@%s", info->dns.name.string);
3154                         tnames.names[8].sid_type = SID_NAME_USER;
3155                         tnames.names[9].name.string = talloc_asprintf(tctx, "krbtgt@%s", info->dns.dns_domain.string);
3156                         tnames.names[9].sid_type = SID_NAME_USER;
3157                         tnames.names[10].name.string = talloc_asprintf(tctx, "%s\\"TEST_MACHINENAME "$", info->dns.name.string);
3158                         tnames.names[10].sid_type = SID_NAME_USER;
3159                         tnames.names[11].name.string = talloc_asprintf(tctx, "%s\\"TEST_MACHINENAME "$", info->dns.dns_domain.string);
3160                         tnames.names[11].sid_type = SID_NAME_USER;
3161                         tnames.names[12].name.string = talloc_asprintf(tctx, TEST_MACHINENAME "$@%s", info->dns.name.string);
3162                         tnames.names[12].sid_type = SID_NAME_USER;
3163                         tnames.names[13].name.string = talloc_asprintf(tctx, TEST_MACHINENAME "$@%s", info->dns.dns_domain.string);
3164                         tnames.names[13].sid_type = SID_NAME_USER;
3165                         ret &= test_LookupNames(b, tctx, handle, &tnames);
3166
3167                 }
3168         }
3169
3170         return ret;
3171 }
3172
3173 static bool test_QueryInfoPolicy(struct dcerpc_binding_handle *b,
3174                                  struct torture_context *tctx,
3175                                  struct policy_handle *handle)
3176 {
3177         return test_QueryInfoPolicyCalls(false, b, tctx, handle);
3178 }
3179
3180 static bool test_QueryInfoPolicy2(struct dcerpc_binding_handle *b,
3181                                   struct torture_context *tctx,
3182                                   struct policy_handle *handle)
3183 {
3184         return test_QueryInfoPolicyCalls(true, b, tctx, handle);
3185 }
3186
3187 static bool test_GetUserName(struct dcerpc_binding_handle *b,
3188                              struct torture_context *tctx)
3189 {
3190         struct lsa_GetUserName r;
3191         bool ret = true;
3192         struct lsa_String *authority_name_p = NULL;
3193         struct lsa_String *account_name_p = NULL;
3194
3195         torture_comment(tctx, "\nTesting GetUserName\n");
3196
3197         r.in.system_name        = "\\";
3198         r.in.account_name       = &account_name_p;
3199         r.in.authority_name     = NULL;
3200         r.out.account_name      = &account_name_p;
3201
3202         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetUserName_r(b, tctx, &r),
3203                 "GetUserName failed");
3204
3205         if (!NT_STATUS_IS_OK(r.out.result)) {
3206                 torture_comment(tctx, "GetUserName failed - %s\n", nt_errstr(r.out.result));
3207                 ret = false;
3208         }
3209
3210         account_name_p = NULL;
3211         r.in.account_name       = &account_name_p;
3212         r.in.authority_name     = &authority_name_p;
3213         r.out.account_name      = &account_name_p;
3214
3215         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetUserName_r(b, tctx, &r),
3216                 "GetUserName failed");
3217
3218         if (!NT_STATUS_IS_OK(r.out.result)) {
3219                 torture_comment(tctx, "GetUserName failed - %s\n", nt_errstr(r.out.result));
3220                 ret = false;
3221         }
3222
3223         return ret;
3224 }
3225
3226 static bool test_GetUserName_fail(struct dcerpc_binding_handle *b,
3227                                   struct torture_context *tctx)
3228 {
3229         struct lsa_GetUserName r;
3230         struct lsa_String *account_name_p = NULL;
3231         NTSTATUS status;
3232
3233         torture_comment(tctx, "\nTesting GetUserName_fail\n");
3234
3235         r.in.system_name        = "\\";
3236         r.in.account_name       = &account_name_p;
3237         r.in.authority_name     = NULL;
3238         r.out.account_name      = &account_name_p;
3239
3240         status = dcerpc_lsa_GetUserName_r(b, tctx, &r);
3241         if (!NT_STATUS_IS_OK(status)) {
3242                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
3243                         torture_comment(tctx,
3244                                         "GetUserName correctly returned with "
3245                                         "status: %s\n",
3246                                         nt_errstr(status));
3247                         return true;
3248                 }
3249
3250                 torture_assert_ntstatus_equal(tctx,
3251                                               status,
3252                                               NT_STATUS_ACCESS_DENIED,
3253                                               "GetUserName return value should "
3254                                               "be ACCESS_DENIED");
3255                 return true;
3256         }
3257
3258         if (!NT_STATUS_IS_OK(r.out.result)) {
3259                 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) ||
3260                     NT_STATUS_EQUAL(r.out.result, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
3261                         torture_comment(tctx,
3262                                         "GetUserName correctly returned with "
3263                                         "result: %s\n",
3264                                         nt_errstr(r.out.result));
3265                         return true;
3266                 }
3267         }
3268
3269         torture_assert_ntstatus_equal(tctx,
3270                                       r.out.result,
3271                                       NT_STATUS_OK,
3272                                       "GetUserName return value should be "
3273                                       "ACCESS_DENIED");
3274
3275         return false;
3276 }
3277
3278 bool test_lsa_Close(struct dcerpc_binding_handle *b,
3279                     struct torture_context *tctx,
3280                     struct policy_handle *handle)
3281 {
3282         struct lsa_Close r;
3283         struct policy_handle handle2;
3284
3285         torture_comment(tctx, "\nTesting Close\n");
3286
3287         r.in.handle = handle;
3288         r.out.handle = &handle2;
3289
3290         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Close_r(b, tctx, &r),
3291                 "Close failed");
3292         torture_assert_ntstatus_ok(tctx, r.out.result,
3293                 "Close failed");
3294
3295         torture_assert_ntstatus_equal(tctx, dcerpc_lsa_Close_r(b, tctx, &r),
3296                 NT_STATUS_RPC_SS_CONTEXT_MISMATCH, "Close should failed");
3297
3298         torture_comment(tctx, "\n");
3299
3300         return true;
3301 }
3302
3303 bool torture_rpc_lsa(struct torture_context *tctx)
3304 {
3305         NTSTATUS status;
3306         struct dcerpc_pipe *p;
3307         bool ret = true;
3308         struct policy_handle *handle = NULL;
3309         struct test_join *join = NULL;
3310         struct cli_credentials *machine_creds;
3311         struct dcerpc_binding_handle *b;
3312         enum dcerpc_transport_t transport;
3313
3314         status = torture_rpc_connection(tctx, &p, &ndr_table_lsarpc);
3315         if (!NT_STATUS_IS_OK(status)) {
3316                 return false;
3317         }
3318         b = p->binding_handle;
3319         transport = dcerpc_binding_get_transport(p->binding);
3320
3321         /* Test lsaLookupSids3 and lsaLookupNames4 over tcpip */
3322         if (transport == NCACN_IP_TCP) {
3323                 if (!test_OpenPolicy_fail(b, tctx)) {
3324                         ret = false;
3325                 }
3326
3327                 if (!test_OpenPolicy2_fail(b, tctx)) {
3328                         ret = false;
3329                 }
3330
3331                 if (!test_many_LookupSids(p, tctx, handle)) {
3332                         ret = false;
3333                 }
3334
3335                 return ret;
3336         }
3337
3338         if (!test_OpenPolicy(b, tctx)) {
3339                 ret = false;
3340         }
3341
3342         if (!test_lsa_OpenPolicy2(b, tctx, &handle)) {
3343                 ret = false;
3344         }
3345
3346         if (handle) {
3347                 join = torture_join_domain(tctx, TEST_MACHINENAME, ACB_WSTRUST, &machine_creds);
3348                 if (!join) {
3349                         ret = false;
3350                 }
3351
3352                 if (!test_LookupSids_async(b, tctx, handle)) {
3353                         ret = false;
3354                 }
3355
3356                 if (!test_QueryDomainInfoPolicy(b, tctx, handle)) {
3357                         ret = false;
3358                 }
3359
3360                 if (!test_CreateSecret(p, tctx, handle)) {
3361                         ret = false;
3362                 }
3363
3364                 if (!test_QueryInfoPolicy(b, tctx, handle)) {
3365                         ret = false;
3366                 }
3367
3368                 if (!test_QueryInfoPolicy2(b, tctx, handle)) {
3369                         ret = false;
3370                 }
3371
3372                 if (!test_Delete(b, tctx, handle)) {
3373                         ret = false;
3374                 }
3375
3376                 if (!test_many_LookupSids(p, tctx, handle)) {
3377                         ret = false;
3378                 }
3379
3380                 if (!test_lsa_Close(b, tctx, handle)) {
3381                         ret = false;
3382                 }
3383
3384                 torture_leave_domain(tctx, join);
3385
3386         } else {
3387                 if (!test_many_LookupSids(p, tctx, handle)) {
3388                         ret = false;
3389                 }
3390         }
3391
3392         if (!test_GetUserName(b, tctx)) {
3393                 ret = false;
3394         }
3395
3396         return ret;
3397 }
3398
3399 bool torture_rpc_lsa_get_user(struct torture_context *tctx)
3400 {
3401         NTSTATUS status;
3402         struct dcerpc_pipe *p;
3403         bool ret = true;
3404         struct dcerpc_binding_handle *b;
3405         enum dcerpc_transport_t transport;
3406
3407         status = torture_rpc_connection(tctx, &p, &ndr_table_lsarpc);
3408         if (!NT_STATUS_IS_OK(status)) {
3409                 return false;
3410         }
3411         b = p->binding_handle;
3412         transport = dcerpc_binding_get_transport(p->binding);
3413
3414         if (transport == NCACN_IP_TCP) {
3415                 if (!test_GetUserName_fail(b, tctx)) {
3416                         ret = false;
3417                 }
3418                 return ret;
3419         }
3420
3421         if (!test_GetUserName(b, tctx)) {
3422                 ret = false;
3423         }
3424
3425         return ret;
3426 }
3427
3428 static bool testcase_LookupNames(struct torture_context *tctx,
3429                                  struct dcerpc_pipe *p)
3430 {
3431         bool ret = true;
3432         struct policy_handle *handle;
3433         struct lsa_TransNameArray tnames;
3434         struct lsa_TransNameArray2 tnames2;
3435         struct dcerpc_binding_handle *b = p->binding_handle;
3436         enum dcerpc_transport_t transport = dcerpc_binding_get_transport(p->binding);
3437
3438         if (transport != NCACN_NP && transport != NCALRPC) {
3439                 torture_comment(tctx, "testcase_LookupNames is only available "
3440                                 "over NCACN_NP or NCALRPC");
3441                 return true;
3442         }
3443
3444         if (!test_OpenPolicy(b, tctx)) {
3445                 ret = false;
3446         }
3447
3448         if (!test_lsa_OpenPolicy2(b, tctx, &handle)) {
3449                 ret = false;
3450         }
3451
3452         if (!handle) {
3453                 ret = false;
3454         }
3455
3456         tnames.count = 1;
3457         tnames.names = talloc_array(tctx, struct lsa_TranslatedName, tnames.count);
3458         ZERO_STRUCT(tnames.names[0]);
3459         tnames.names[0].name.string = "BUILTIN";
3460         tnames.names[0].sid_type = SID_NAME_DOMAIN;
3461
3462         if (!test_LookupNames(b, tctx, handle, &tnames)) {
3463                 ret = false;
3464         }
3465
3466         tnames2.count = 1;
3467         tnames2.names = talloc_array(tctx, struct lsa_TranslatedName2, tnames2.count);
3468         ZERO_STRUCT(tnames2.names[0]);
3469         tnames2.names[0].name.string = "BUILTIN";
3470         tnames2.names[0].sid_type = SID_NAME_DOMAIN;
3471
3472         if (!test_LookupNames2(b, tctx, handle, &tnames2, true)) {
3473                 ret = false;
3474         }
3475
3476         if (!test_LookupNames3(b, tctx, handle, &tnames2, true)) {
3477                 ret = false;
3478         }
3479
3480         if (!test_LookupNames_wellknown(b, tctx, handle)) {
3481                 ret = false;
3482         }
3483
3484         if (!test_LookupNames_NULL(b, tctx, handle)) {
3485                 ret = false;
3486         }
3487
3488         if (!test_LookupNames_bogus(b, tctx, handle)) {
3489                 ret = false;
3490         }
3491
3492         if (!test_lsa_Close(b, tctx, handle)) {
3493                 ret = false;
3494         }
3495
3496         return ret;
3497 }
3498
3499 struct torture_suite *torture_rpc_lsa_lookup_names(TALLOC_CTX *mem_ctx)
3500 {
3501         struct torture_suite *suite;
3502         struct torture_rpc_tcase *tcase;
3503
3504         suite = torture_suite_create(mem_ctx, "lsa.lookupnames");
3505
3506         tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa",
3507                                                   &ndr_table_lsarpc);
3508         torture_rpc_tcase_add_test(tcase, "LookupNames",
3509                                    testcase_LookupNames);
3510
3511         return suite;
3512 }
3513
3514 struct lsa_trustdom_state {
3515         uint32_t num_trusts;
3516 };
3517
3518 static bool testcase_TrustedDomains(struct torture_context *tctx,
3519                                     struct dcerpc_pipe *p,
3520                                     void *data)
3521 {
3522         bool ret = true;
3523         struct policy_handle *handle;
3524         struct lsa_trustdom_state *state =
3525                 talloc_get_type_abort(data, struct lsa_trustdom_state);
3526         struct dcerpc_binding_handle *b = p->binding_handle;
3527         enum dcerpc_transport_t transport = dcerpc_binding_get_transport(p->binding);
3528
3529         if (transport != NCACN_NP && transport != NCALRPC) {
3530                 torture_comment(tctx, "testcase_TrustedDomains is only available "
3531                                 "over NCACN_NP or NCALRPC");
3532                 return true;
3533         }
3534
3535         torture_comment(tctx, "Testing %d domains\n", state->num_trusts);
3536
3537         if (!test_OpenPolicy(b, tctx)) {
3538                 ret = false;
3539         }
3540
3541         if (!test_lsa_OpenPolicy2(b, tctx, &handle)) {
3542                 ret = false;
3543         }
3544
3545         if (!handle) {
3546                 ret = false;
3547         }
3548
3549         if (!test_CreateTrustedDomain(b, tctx, handle, state->num_trusts)) {
3550                 ret = false;
3551         }
3552
3553         if (!test_CreateTrustedDomainEx(p, tctx, handle, state->num_trusts)) {
3554                 ret = false;
3555         }
3556
3557         if (!test_CreateTrustedDomainEx2(p, tctx, handle, state->num_trusts)) {
3558                 ret = false;
3559         }
3560
3561         if (!test_lsa_Close(b, tctx, handle)) {
3562                 ret = false;
3563         }
3564
3565         return ret;
3566 }
3567
3568 struct torture_suite *torture_rpc_lsa_trusted_domains(TALLOC_CTX *mem_ctx)
3569 {
3570         struct torture_suite *suite;
3571         struct torture_rpc_tcase *tcase;
3572         struct lsa_trustdom_state *state;
3573
3574         state = talloc(mem_ctx, struct lsa_trustdom_state);
3575
3576         state->num_trusts = 12;
3577
3578         suite = torture_suite_create(mem_ctx, "lsa.trusted.domains");
3579
3580         tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa",
3581                                                   &ndr_table_lsarpc);
3582         torture_rpc_tcase_add_test_ex(tcase, "TrustedDomains",
3583                                       testcase_TrustedDomains,
3584                                       state);
3585
3586         return suite;
3587 }
3588
3589 static bool testcase_Privileges(struct torture_context *tctx,
3590                                 struct dcerpc_pipe *p)
3591 {
3592         struct policy_handle *handle;
3593         struct dcerpc_binding_handle *b = p->binding_handle;
3594         enum dcerpc_transport_t transport = dcerpc_binding_get_transport(p->binding);
3595
3596         if (transport != NCACN_NP && transport != NCALRPC) {
3597                 torture_skip(tctx, "testcase_Privileges is only available "
3598                                 "over NCACN_NP or NCALRPC");
3599         }
3600
3601         if (!test_OpenPolicy(b, tctx)) {
3602                 return false;
3603         }
3604
3605         if (!test_lsa_OpenPolicy2(b, tctx, &handle)) {
3606                 return false;
3607         }
3608
3609         if (!handle) {
3610                 return false;
3611         }
3612
3613         if (!test_CreateAccount(b, tctx, handle)) {
3614                 return false;
3615         }
3616
3617         if (!test_EnumAccounts(b, tctx, handle)) {
3618                 return false;
3619         }
3620
3621         if (!test_EnumPrivs(b, tctx, handle)) {
3622                 return false;
3623         }
3624
3625         if (!test_lsa_Close(b, tctx, handle)) {
3626                 return false;
3627         }
3628
3629         return true;
3630 }
3631
3632
3633 struct torture_suite *torture_rpc_lsa_privileges(TALLOC_CTX *mem_ctx)
3634 {
3635         struct torture_suite *suite;
3636         struct torture_rpc_tcase *tcase;
3637
3638         suite = torture_suite_create(mem_ctx, "lsa.privileges");
3639
3640         tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa",
3641                                                   &ndr_table_lsarpc);
3642         torture_rpc_tcase_add_test(tcase, "Privileges",
3643                                    testcase_Privileges);
3644
3645         return suite;
3646 }