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