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