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