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