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