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