s4-torture: use krb5_error in lsa forest trust tests.
[samba.git] / source4 / torture / rpc / lsa.c
1 /*
2    Unix SMB/CIFS implementation.
3    test suite for lsa rpc operations
4
5    Copyright (C) Andrew Tridgell 2003
6    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2005
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "torture/torture.h"
24 #include "libcli/cldap/cldap.h"
25 #include "../lib/tsocket/tsocket.h"
26 #include "librpc/gen_ndr/ndr_lsa_c.h"
27 #include "librpc/gen_ndr/netlogon.h"
28 #include "librpc/gen_ndr/ndr_drsblobs.h"
29 #include "librpc/gen_ndr/ndr_netlogon_c.h"
30 #include "lib/events/events.h"
31 #include "libcli/security/security.h"
32 #include "libcli/auth/libcli_auth.h"
33 #include "torture/rpc/torture_rpc.h"
34 #include "param/param.h"
35 #include "source4/auth/kerberos/kerberos.h"
36 #include "source4/auth/kerberos/kerberos_util.h"
37 #include "lib/util/util_net.h"
38 #include "../lib/crypto/crypto.h"
39 #define TEST_MACHINENAME "lsatestmach"
40 #define TRUSTPW "12345678"
41
42 static void init_lsa_String(struct lsa_String *name, const char *s)
43 {
44         name->string = s;
45 }
46
47 static bool test_OpenPolicy(struct dcerpc_binding_handle *b,
48                             struct torture_context *tctx)
49 {
50         struct lsa_ObjectAttribute attr;
51         struct policy_handle handle;
52         struct lsa_QosInfo qos;
53         struct lsa_OpenPolicy r;
54         uint16_t system_name = '\\';
55
56         torture_comment(tctx, "\nTesting OpenPolicy\n");
57
58         qos.len = 0;
59         qos.impersonation_level = 2;
60         qos.context_mode = 1;
61         qos.effective_only = 0;
62
63         attr.len = 0;
64         attr.root_dir = NULL;
65         attr.object_name = NULL;
66         attr.attributes = 0;
67         attr.sec_desc = NULL;
68         attr.sec_qos = &qos;
69
70         r.in.system_name = &system_name;
71         r.in.attr = &attr;
72         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
73         r.out.handle = &handle;
74
75         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenPolicy_r(b, tctx, &r),
76                                    "OpenPolicy failed");
77
78         torture_assert_ntstatus_ok(tctx,
79                                    r.out.result,
80                                    "OpenPolicy failed");
81
82         return true;
83 }
84
85 static bool test_OpenPolicy_fail(struct dcerpc_binding_handle *b,
86                                  struct torture_context *tctx)
87 {
88         struct lsa_ObjectAttribute attr;
89         struct policy_handle handle;
90         struct lsa_QosInfo qos;
91         struct lsa_OpenPolicy r;
92         uint16_t system_name = '\\';
93         NTSTATUS status;
94
95         torture_comment(tctx, "\nTesting OpenPolicy_fail\n");
96
97         qos.len = 0;
98         qos.impersonation_level = 2;
99         qos.context_mode = 1;
100         qos.effective_only = 0;
101
102         attr.len = 0;
103         attr.root_dir = NULL;
104         attr.object_name = NULL;
105         attr.attributes = 0;
106         attr.sec_desc = NULL;
107         attr.sec_qos = &qos;
108
109         r.in.system_name = &system_name;
110         r.in.attr = &attr;
111         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
112         r.out.handle = &handle;
113
114         status = dcerpc_lsa_OpenPolicy_r(b, tctx, &r);
115         if (!NT_STATUS_IS_OK(status)) {
116                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
117                         torture_comment(tctx,
118                                         "OpenPolicy correctly returned with "
119                                         "status: %s\n",
120                                         nt_errstr(status));
121                         return true;
122                 }
123
124                 torture_assert_ntstatus_equal(tctx,
125                                               status,
126                                               NT_STATUS_ACCESS_DENIED,
127                                               "OpenPolicy return value should "
128                                               "be ACCESS_DENIED");
129                 return true;
130         }
131
132         if (!NT_STATUS_IS_OK(r.out.result)) {
133                 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) ||
134                     NT_STATUS_EQUAL(r.out.result, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
135                         torture_comment(tctx,
136                                         "OpenPolicy correctly returned with "
137                                         "result: %s\n",
138                                         nt_errstr(r.out.result));
139                         return true;
140                 }
141         }
142
143         torture_assert_ntstatus_equal(tctx,
144                                       r.out.result,
145                                       NT_STATUS_OK,
146                                       "OpenPolicy return value should be "
147                                       "ACCESS_DENIED");
148
149         return false;
150 }
151
152
153 bool test_lsa_OpenPolicy2_ex(struct dcerpc_binding_handle *b,
154                              struct torture_context *tctx,
155                              struct policy_handle **handle,
156                              NTSTATUS expected_status)
157 {
158         struct lsa_ObjectAttribute attr;
159         struct lsa_QosInfo qos;
160         struct lsa_OpenPolicy2 r;
161         NTSTATUS status;
162
163         torture_comment(tctx, "\nTesting OpenPolicy2\n");
164
165         *handle = talloc(tctx, struct policy_handle);
166         torture_assert(tctx, *handle != NULL, "talloc(tctx, struct policy_handle)");
167
168         qos.len = 0;
169         qos.impersonation_level = 2;
170         qos.context_mode = 1;
171         qos.effective_only = 0;
172
173         attr.len = 0;
174         attr.root_dir = NULL;
175         attr.object_name = NULL;
176         attr.attributes = 0;
177         attr.sec_desc = NULL;
178         attr.sec_qos = &qos;
179
180         r.in.system_name = "\\";
181         r.in.attr = &attr;
182         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
183         r.out.handle = *handle;
184
185         status = dcerpc_lsa_OpenPolicy2_r(b, tctx, &r);
186         torture_assert_ntstatus_equal(tctx, status, expected_status,
187                                    "OpenPolicy2 failed");
188         if (!NT_STATUS_IS_OK(expected_status)) {
189                 return true;
190         }
191
192         torture_assert_ntstatus_ok(tctx,
193                                    r.out.result,
194                                    "OpenPolicy2 failed");
195
196         return true;
197 }
198
199
200 bool test_lsa_OpenPolicy2(struct dcerpc_binding_handle *b,
201                           struct torture_context *tctx,
202                           struct policy_handle **handle)
203 {
204         return test_lsa_OpenPolicy2_ex(b, tctx, handle, NT_STATUS_OK);
205 }
206
207 static bool test_OpenPolicy2_fail(struct dcerpc_binding_handle *b,
208                                   struct torture_context *tctx)
209 {
210         struct lsa_ObjectAttribute attr;
211         struct policy_handle handle;
212         struct lsa_QosInfo qos;
213         struct lsa_OpenPolicy2 r;
214         NTSTATUS status;
215
216         torture_comment(tctx, "\nTesting OpenPolicy2_fail\n");
217
218         qos.len = 0;
219         qos.impersonation_level = 2;
220         qos.context_mode = 1;
221         qos.effective_only = 0;
222
223         attr.len = 0;
224         attr.root_dir = NULL;
225         attr.object_name = NULL;
226         attr.attributes = 0;
227         attr.sec_desc = NULL;
228         attr.sec_qos = &qos;
229
230         r.in.system_name = "\\";
231         r.in.attr = &attr;
232         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
233         r.out.handle = &handle;
234
235         status = dcerpc_lsa_OpenPolicy2_r(b, tctx, &r);
236         if (!NT_STATUS_IS_OK(status)) {
237                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
238                         torture_comment(tctx,
239                                         "OpenPolicy2 correctly returned with "
240                                         "status: %s\n",
241                                         nt_errstr(status));
242                         return true;
243                 }
244
245                 torture_assert_ntstatus_equal(tctx,
246                                               status,
247                                               NT_STATUS_ACCESS_DENIED,
248                                               "OpenPolicy2 return value should "
249                                               "be ACCESS_DENIED");
250                 return true;
251         }
252
253         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) ||
254             NT_STATUS_EQUAL(r.out.result, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
255                 torture_comment(tctx,
256                                 "OpenPolicy2 correctly returned with "
257                                 "result: %s\n",
258                                 nt_errstr(r.out.result));
259                 return true;
260         }
261
262         torture_fail(tctx,
263                      "OpenPolicy2 return value should be "
264                      "ACCESS_DENIED or RPC_PROTSEQ_NOT_SUPPORTED");
265
266         return false;
267 }
268
269 static bool test_LookupNames(struct dcerpc_binding_handle *b,
270                              struct torture_context *tctx,
271                              struct policy_handle *handle,
272                              struct lsa_TransNameArray *tnames)
273 {
274         struct lsa_LookupNames r;
275         struct lsa_TransSidArray sids;
276         struct lsa_RefDomainList *domains = NULL;
277         struct lsa_String *names;
278         uint32_t count = 0;
279         int i;
280         uint32_t *input_idx;
281
282         torture_comment(tctx, "\nTesting LookupNames with %d names\n", tnames->count);
283
284         sids.count = 0;
285         sids.sids = NULL;
286
287
288         r.in.num_names = 0;
289
290         input_idx = talloc_array(tctx, uint32_t, tnames->count);
291         names = talloc_array(tctx, struct lsa_String, tnames->count);
292
293         for (i=0;i<tnames->count;i++) {
294                 if (tnames->names[i].sid_type != SID_NAME_UNKNOWN) {
295                         init_lsa_String(&names[r.in.num_names], tnames->names[i].name.string);
296                         input_idx[r.in.num_names] = i;
297                         r.in.num_names++;
298                 }
299         }
300
301         r.in.handle = handle;
302         r.in.names = names;
303         r.in.sids = &sids;
304         r.in.level = 1;
305         r.in.count = &count;
306         r.out.count = &count;
307         r.out.sids = &sids;
308         r.out.domains = &domains;
309
310         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupNames_r(b, tctx, &r),
311                                    "LookupNames failed");
312         if (NT_STATUS_EQUAL(r.out.result, STATUS_SOME_UNMAPPED) ||
313             NT_STATUS_EQUAL(r.out.result, NT_STATUS_NONE_MAPPED)) {
314                 for (i=0;i< r.in.num_names;i++) {
315                         if (i < count && sids.sids[i].sid_type == SID_NAME_UNKNOWN) {
316                                 torture_comment(tctx, "LookupName of %s was unmapped\n",
317                                        tnames->names[i].name.string);
318                         } else if (i >=count) {
319                                 torture_comment(tctx, "LookupName of %s failed to return a result\n",
320                                        tnames->names[i].name.string);
321                         }
322                 }
323                 torture_assert_ntstatus_ok(tctx, r.out.result,
324                                            "LookupNames failed");
325         } else if (!NT_STATUS_IS_OK(r.out.result)) {
326                 torture_assert_ntstatus_ok(tctx, r.out.result,
327                                            "LookupNames failed");
328         }
329
330         for (i=0;i< r.in.num_names;i++) {
331                 torture_assert(tctx, (i < count),
332                                talloc_asprintf(tctx,
333                                "LookupName of %s failed to return a result\n",
334                                tnames->names[input_idx[i]].name.string));
335
336                 torture_assert_int_equal(tctx,
337                                          sids.sids[i].sid_type,
338                                          tnames->names[input_idx[i]].sid_type,
339                                          talloc_asprintf(tctx,
340                                          "LookupName of %s got unexpected name type: %s\n",
341                                          tnames->names[input_idx[i]].name.string,
342                                          sid_type_lookup(sids.sids[i].sid_type)));
343                 if (sids.sids[i].sid_type != SID_NAME_DOMAIN) {
344                         continue;
345                 }
346                 torture_assert_int_equal(tctx,
347                                          sids.sids[i].rid,
348                                          UINT32_MAX,
349                                          talloc_asprintf(tctx,
350                                          "LookupName of %s got unexpected rid: %d\n",
351                                          tnames->names[input_idx[i]].name.string,
352                                          sids.sids[i].rid));
353         }
354
355         return true;
356 }
357
358 static bool test_LookupNames_bogus(struct dcerpc_binding_handle *b,
359                                    struct torture_context *tctx,
360                                    struct policy_handle *handle)
361 {
362         struct lsa_LookupNames r;
363         struct lsa_TransSidArray sids;
364         struct lsa_RefDomainList *domains = NULL;
365         struct lsa_String names[1];
366         uint32_t count = 0;
367
368         torture_comment(tctx, "\nTesting LookupNames with bogus name\n");
369
370         sids.count = 0;
371         sids.sids = NULL;
372
373         init_lsa_String(&names[0], "NT AUTHORITY\\BOGUS");
374
375         r.in.handle = handle;
376         r.in.num_names = 1;
377         r.in.names = names;
378         r.in.sids = &sids;
379         r.in.level = 1;
380         r.in.count = &count;
381         r.out.count = &count;
382         r.out.sids = &sids;
383         r.out.domains = &domains;
384
385         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupNames_r(b, tctx, &r),
386                                    "LookupNames bogus failed");
387         if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_NONE_MAPPED)) {
388                 torture_comment(tctx, "LookupNames failed - %s\n",
389                                 nt_errstr(r.out.result));
390                 return false;
391         }
392
393         torture_comment(tctx, "\n");
394
395         return true;
396 }
397
398 static bool test_LookupNames_NULL(struct dcerpc_binding_handle *b,
399                                   struct torture_context *tctx,
400                                   struct policy_handle *handle)
401 {
402         struct lsa_LookupNames r;
403         struct lsa_TransSidArray sids;
404         struct lsa_RefDomainList *domains = NULL;
405         struct lsa_String names[1];
406         uint32_t count = 0;
407
408         torture_comment(tctx, "\nTesting LookupNames with NULL name\n");
409
410         sids.count = 0;
411         sids.sids = NULL;
412
413         names[0].string = NULL;
414
415         r.in.handle = handle;
416         r.in.num_names = 1;
417         r.in.names = names;
418         r.in.sids = &sids;
419         r.in.level = 1;
420         r.in.count = &count;
421         r.out.count = &count;
422         r.out.sids = &sids;
423         r.out.domains = &domains;
424
425         /* nt4 returns NT_STATUS_NONE_MAPPED with sid_type
426          * SID_NAME_UNKNOWN, rid 0, and sid_index -1;
427          *
428          * w2k3/w2k8 return NT_STATUS_OK with sid_type
429          * SID_NAME_DOMAIN, rid -1 and sid_index 0 and BUILTIN domain
430          */
431
432         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupNames_r(b, tctx, &r),
433                 "LookupNames with NULL name failed");
434         torture_assert_ntstatus_ok(tctx, r.out.result,
435                 "LookupNames with NULL name failed");
436
437         torture_comment(tctx, "\n");
438
439         return true;
440 }
441
442 static bool test_LookupNames_wellknown(struct dcerpc_binding_handle *b,
443                                        struct torture_context *tctx,
444                                        struct policy_handle *handle)
445 {
446         struct lsa_TranslatedName name;
447         struct lsa_TransNameArray tnames;
448         bool ret = true;
449
450         torture_comment(tctx, "Testing LookupNames with well known names\n");
451
452         tnames.names = &name;
453         tnames.count = 1;
454         name.name.string = "NT AUTHORITY\\SYSTEM";
455         name.sid_type = SID_NAME_WKN_GRP;
456         ret &= test_LookupNames(b, tctx, handle, &tnames);
457
458         name.name.string = "NT AUTHORITY\\ANONYMOUS LOGON";
459         name.sid_type = SID_NAME_WKN_GRP;
460         ret &= test_LookupNames(b, tctx, handle, &tnames);
461
462         name.name.string = "NT AUTHORITY\\Authenticated Users";
463         name.sid_type = SID_NAME_WKN_GRP;
464         ret &= test_LookupNames(b, tctx, handle, &tnames);
465
466 #if 0
467         name.name.string = "NT AUTHORITY";
468         ret &= test_LookupNames(b, tctx, handle, &tnames);
469
470         name.name.string = "NT AUTHORITY\\";
471         ret &= test_LookupNames(b, tctx, handle, &tnames);
472 #endif
473
474         name.name.string = "BUILTIN\\";
475         name.sid_type = SID_NAME_DOMAIN;
476         ret &= test_LookupNames(b, tctx, handle, &tnames);
477
478         name.name.string = "BUILTIN\\Administrators";
479         name.sid_type = SID_NAME_ALIAS;
480         ret &= test_LookupNames(b, tctx, handle, &tnames);
481
482         name.name.string = "SYSTEM";
483         name.sid_type = SID_NAME_WKN_GRP;
484         ret &= test_LookupNames(b, tctx, handle, &tnames);
485
486         name.name.string = "Everyone";
487         name.sid_type = SID_NAME_WKN_GRP;
488         ret &= test_LookupNames(b, tctx, handle, &tnames);
489         return ret;
490 }
491
492 static bool test_LookupNames2(struct dcerpc_binding_handle *b,
493                               struct torture_context *tctx,
494                               struct policy_handle *handle,
495                               struct lsa_TransNameArray2 *tnames,
496                               bool check_result)
497 {
498         struct lsa_LookupNames2 r;
499         struct lsa_TransSidArray2 sids;
500         struct lsa_RefDomainList *domains = NULL;
501         struct lsa_String *names;
502         uint32_t *input_idx;
503         uint32_t count = 0;
504         int i;
505
506         torture_comment(tctx, "\nTesting LookupNames2 with %d names\n", tnames->count);
507
508         sids.count = 0;
509         sids.sids = NULL;
510
511         r.in.num_names = 0;
512
513         input_idx = talloc_array(tctx, uint32_t, tnames->count);
514         names = talloc_array(tctx, struct lsa_String, tnames->count);
515
516         for (i=0;i<tnames->count;i++) {
517                 if (tnames->names[i].sid_type != SID_NAME_UNKNOWN) {
518                         init_lsa_String(&names[r.in.num_names], tnames->names[i].name.string);
519                         input_idx[r.in.num_names] = i;
520                         r.in.num_names++;
521                 }
522         }
523
524         r.in.handle = handle;
525         r.in.names = names;
526         r.in.sids = &sids;
527         r.in.level = 1;
528         r.in.count = &count;
529         r.in.lookup_options = 0;
530         r.in.client_revision = 0;
531         r.out.count = &count;
532         r.out.sids = &sids;
533         r.out.domains = &domains;
534
535         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupNames2_r(b, tctx, &r),
536                 "LookupNames2 failed");
537         torture_assert_ntstatus_ok(tctx, r.out.result, "LookupNames2 failed");
538
539         if (check_result) {
540                 torture_assert_int_equal(tctx, count, sids.count,
541                         "unexpected number of results returned");
542                 if (sids.count > 0) {
543                         torture_assert(tctx, sids.sids, "invalid sid buffer");
544                 }
545         }
546
547         torture_comment(tctx, "\n");
548
549         return true;
550 }
551
552
553 static bool test_LookupNames3(struct dcerpc_binding_handle *b,
554                               struct torture_context *tctx,
555                               struct policy_handle *handle,
556                               struct lsa_TransNameArray2 *tnames,
557                               bool check_result)
558 {
559         struct lsa_LookupNames3 r;
560         struct lsa_TransSidArray3 sids;
561         struct lsa_RefDomainList *domains = NULL;
562         struct lsa_String *names;
563         uint32_t count = 0;
564         int i;
565         uint32_t *input_idx;
566
567         torture_comment(tctx, "\nTesting LookupNames3 with %d names\n", tnames->count);
568
569         sids.count = 0;
570         sids.sids = NULL;
571
572         r.in.num_names = 0;
573
574         input_idx = talloc_array(tctx, uint32_t, tnames->count);
575         names = talloc_array(tctx, struct lsa_String, tnames->count);
576         for (i=0;i<tnames->count;i++) {
577                 if (tnames->names[i].sid_type != SID_NAME_UNKNOWN) {
578                         init_lsa_String(&names[r.in.num_names], tnames->names[i].name.string);
579                         input_idx[r.in.num_names] = i;
580                         r.in.num_names++;
581                 }
582         }
583
584         r.in.handle = handle;
585         r.in.names = names;
586         r.in.sids = &sids;
587         r.in.level = 1;
588         r.in.count = &count;
589         r.in.lookup_options = 0;
590         r.in.client_revision = 0;
591         r.out.count = &count;
592         r.out.sids = &sids;
593         r.out.domains = &domains;
594
595         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupNames3_r(b, tctx, &r),
596                 "LookupNames3 failed");
597         torture_assert_ntstatus_ok(tctx, r.out.result,
598                 "LookupNames3 failed");
599
600         if (check_result) {
601                 torture_assert_int_equal(tctx, count, sids.count,
602                         "unexpected number of results returned");
603                 if (sids.count > 0) {
604                         torture_assert(tctx, sids.sids, "invalid sid buffer");
605                 }
606         }
607
608         torture_comment(tctx, "\n");
609
610         return true;
611 }
612
613 static bool test_LookupNames4(struct dcerpc_binding_handle *b,
614                               struct torture_context *tctx,
615                               struct lsa_TransNameArray2 *tnames,
616                               bool check_result)
617 {
618         struct lsa_LookupNames4 r;
619         struct lsa_TransSidArray3 sids;
620         struct lsa_RefDomainList *domains = NULL;
621         struct lsa_String *names;
622         uint32_t count = 0;
623         int i;
624         uint32_t *input_idx;
625
626         torture_comment(tctx, "\nTesting LookupNames4 with %d names\n", tnames->count);
627
628         sids.count = 0;
629         sids.sids = NULL;
630
631         r.in.num_names = 0;
632
633         input_idx = talloc_array(tctx, uint32_t, tnames->count);
634         names = talloc_array(tctx, struct lsa_String, tnames->count);
635         for (i=0;i<tnames->count;i++) {
636                 if (tnames->names[i].sid_type != SID_NAME_UNKNOWN) {
637                         init_lsa_String(&names[r.in.num_names], tnames->names[i].name.string);
638                         input_idx[r.in.num_names] = i;
639                         r.in.num_names++;
640                 }
641         }
642
643         r.in.num_names = tnames->count;
644         r.in.names = names;
645         r.in.sids = &sids;
646         r.in.level = 1;
647         r.in.count = &count;
648         r.in.lookup_options = 0;
649         r.in.client_revision = 0;
650         r.out.count = &count;
651         r.out.sids = &sids;
652         r.out.domains = &domains;
653
654         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupNames4_r(b, tctx, &r),
655                 "LookupNames4 failed");
656
657         if (!NT_STATUS_IS_OK(r.out.result)) {
658                 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NONE_MAPPED)) {
659                         torture_comment(tctx,
660                                         "LookupNames4 failed: %s - not considered as an error",
661                                         nt_errstr(r.out.result));
662
663                         return true;
664                 }
665         }
666         torture_assert_ntstatus_ok(tctx,
667                                    r.out.result,
668                                    "LookupNames4 failed");
669
670         if (check_result) {
671                 torture_assert_int_equal(tctx, count, sids.count,
672                         "unexpected number of results returned");
673                 if (sids.count > 0) {
674                         torture_assert(tctx, sids.sids, "invalid sid buffer");
675                 }
676         }
677
678         torture_comment(tctx, "\n");
679
680         return true;
681 }
682
683 static bool test_LookupNames4_fail(struct dcerpc_binding_handle *b,
684                                    struct torture_context *tctx)
685 {
686         struct lsa_LookupNames4 r;
687         struct lsa_TransSidArray3 sids;
688         struct lsa_RefDomainList *domains = NULL;
689         struct lsa_String *names = NULL;
690         uint32_t count = 0;
691         NTSTATUS status;
692
693         torture_comment(tctx, "\nTesting LookupNames4_fail");
694
695         sids.count = 0;
696         sids.sids = NULL;
697
698         r.in.num_names = 0;
699
700         r.in.num_names = count;
701         r.in.names = names;
702         r.in.sids = &sids;
703         r.in.level = 1;
704         r.in.count = &count;
705         r.in.lookup_options = 0;
706         r.in.client_revision = 0;
707         r.out.count = &count;
708         r.out.sids = &sids;
709         r.out.domains = &domains;
710
711         status = dcerpc_lsa_LookupNames4_r(b, tctx, &r);
712         if (!NT_STATUS_IS_OK(status)) {
713                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
714                         torture_comment(tctx,
715                                         "LookupNames4 correctly returned with "
716                                         "status: %s\n",
717                                         nt_errstr(status));
718                         return true;
719                 }
720
721                 torture_assert_ntstatus_equal(tctx,
722                                               status,
723                                               NT_STATUS_ACCESS_DENIED,
724                                               "LookupNames4 return value should "
725                                               "be ACCESS_DENIED");
726                 return true;
727         }
728
729         if (!NT_STATUS_IS_OK(r.out.result)) {
730                 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) ||
731                     NT_STATUS_EQUAL(r.out.result, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
732                         torture_comment(tctx,
733                                         "LookupSids3 correctly returned with "
734                                         "result: %s\n",
735                                         nt_errstr(r.out.result));
736                         return true;
737                 }
738         }
739
740         torture_fail(tctx,
741                      "LookupNames4 return value should be "
742                      "ACCESS_DENIED or RPC_PROTSEQ_NOT_SUPPORTED");
743
744         return false;
745 }
746
747
748 static bool test_LookupSids(struct dcerpc_binding_handle *b,
749                             struct torture_context *tctx,
750                             struct policy_handle *handle,
751                             struct lsa_SidArray *sids)
752 {
753         struct lsa_LookupSids r;
754         struct lsa_TransNameArray names;
755         struct lsa_RefDomainList *domains = NULL;
756         uint32_t count = sids->num_sids;
757
758         torture_comment(tctx, "\nTesting LookupSids\n");
759
760         names.count = 0;
761         names.names = NULL;
762
763         r.in.handle = handle;
764         r.in.sids = sids;
765         r.in.names = &names;
766         r.in.level = 1;
767         r.in.count = &count;
768         r.out.count = &count;
769         r.out.names = &names;
770         r.out.domains = &domains;
771
772         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupSids_r(b, tctx, &r),
773                 "LookupSids failed");
774         if (!NT_STATUS_EQUAL(r.out.result, STATUS_SOME_UNMAPPED)) {
775                 torture_assert_ntstatus_ok(tctx, r.out.result,
776                         "LookupSids failed");
777         }
778
779         torture_comment(tctx, "\n");
780
781         if (!test_LookupNames(b, tctx, handle, &names)) {
782                 return false;
783         }
784
785         return true;
786 }
787
788
789 static bool test_LookupSids2(struct dcerpc_binding_handle *b,
790                             struct torture_context *tctx,
791                             struct policy_handle *handle,
792                             struct lsa_SidArray *sids)
793 {
794         struct lsa_LookupSids2 r;
795         struct lsa_TransNameArray2 names;
796         struct lsa_RefDomainList *domains = NULL;
797         uint32_t count = sids->num_sids;
798
799         torture_comment(tctx, "\nTesting LookupSids2\n");
800
801         names.count = 0;
802         names.names = NULL;
803
804         r.in.handle = handle;
805         r.in.sids = sids;
806         r.in.names = &names;
807         r.in.level = 1;
808         r.in.count = &count;
809         r.in.lookup_options = 0;
810         r.in.client_revision = 0;
811         r.out.count = &count;
812         r.out.names = &names;
813         r.out.domains = &domains;
814
815         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupSids2_r(b, tctx, &r),
816                 "LookupSids2 failed");
817         if (!NT_STATUS_IS_OK(r.out.result) &&
818             !NT_STATUS_EQUAL(r.out.result, STATUS_SOME_UNMAPPED)) {
819                 torture_comment(tctx, "LookupSids2 failed - %s\n",
820                                 nt_errstr(r.out.result));
821                 return false;
822         }
823
824         torture_comment(tctx, "\n");
825
826         if (!test_LookupNames2(b, tctx, handle, &names, false)) {
827                 return false;
828         }
829
830         if (!test_LookupNames3(b, tctx, handle, &names, false)) {
831                 return false;
832         }
833
834         return true;
835 }
836
837 static bool test_LookupSids3(struct dcerpc_binding_handle *b,
838                             struct torture_context *tctx,
839                             struct lsa_SidArray *sids)
840 {
841         struct lsa_LookupSids3 r;
842         struct lsa_TransNameArray2 names;
843         struct lsa_RefDomainList *domains = NULL;
844         uint32_t count = sids->num_sids;
845
846         torture_comment(tctx, "\nTesting LookupSids3\n");
847
848         names.count = 0;
849         names.names = NULL;
850
851         r.in.sids = sids;
852         r.in.names = &names;
853         r.in.level = 1;
854         r.in.count = &count;
855         r.in.lookup_options = 0;
856         r.in.client_revision = 0;
857         r.out.domains = &domains;
858         r.out.count = &count;
859         r.out.names = &names;
860
861         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupSids3_r(b, tctx, &r),
862                 "LookupSids3 failed");
863
864         if (!NT_STATUS_IS_OK(r.out.result)) {
865                 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NONE_MAPPED)) {
866                         torture_comment(tctx,
867                                         "LookupSids3 failed: %s - not considered as an error",
868                                         nt_errstr(r.out.result));
869
870                         return true;
871                 }
872
873                 torture_assert_ntstatus_ok(tctx,
874                                            r.out.result,
875                                            "LookupSids3 failed");
876
877                 return false;
878         }
879
880         torture_comment(tctx, "\n");
881
882         if (!test_LookupNames4(b, tctx, &names, true)) {
883                 return false;
884         }
885
886         return true;
887 }
888
889 static bool test_LookupSids3_fail(struct dcerpc_binding_handle *b,
890                                   struct torture_context *tctx,
891                                   struct lsa_SidArray *sids)
892 {
893         struct lsa_LookupSids3 r;
894         struct lsa_TransNameArray2 names;
895         struct lsa_RefDomainList *domains = NULL;
896         uint32_t count = sids->num_sids;
897         NTSTATUS status;
898
899         torture_comment(tctx, "\nTesting LookupSids3\n");
900
901         names.count = 0;
902         names.names = NULL;
903
904         r.in.sids = sids;
905         r.in.names = &names;
906         r.in.level = 1;
907         r.in.count = &count;
908         r.in.lookup_options = 0;
909         r.in.client_revision = 0;
910         r.out.domains = &domains;
911         r.out.count = &count;
912         r.out.names = &names;
913
914         status = dcerpc_lsa_LookupSids3_r(b, tctx, &r);
915         if (!NT_STATUS_IS_OK(status)) {
916                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
917                         torture_comment(tctx,
918                                         "LookupSids3 correctly returned with "
919                                         "status: %s\n",
920                                         nt_errstr(status));
921                         return true;
922                 }
923
924                 torture_assert_ntstatus_equal(tctx,
925                                               status,
926                                               NT_STATUS_ACCESS_DENIED,
927                                               "LookupSids3 return value should "
928                                               "be ACCESS_DENIED");
929                 return true;
930         }
931
932         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) ||
933             NT_STATUS_EQUAL(r.out.result, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
934                 torture_comment(tctx,
935                                 "LookupNames4 correctly returned with "
936                                 "result: %s\n",
937                                 nt_errstr(r.out.result));
938                 return true;
939         }
940
941         torture_fail(tctx,
942                      "LookupSids3 return value should be "
943                      "ACCESS_DENIED or RPC_PROTSEQ_NOT_SUPPORTED");
944
945         return false;
946 }
947
948 bool test_many_LookupSids(struct dcerpc_pipe *p,
949                           struct torture_context *tctx,
950                           struct policy_handle *handle)
951 {
952         uint32_t count;
953         struct lsa_SidArray sids;
954         int i;
955         struct dcerpc_binding_handle *b = p->binding_handle;
956         enum dcerpc_transport_t transport = dcerpc_binding_get_transport(p->binding);
957
958         torture_comment(tctx, "\nTesting LookupSids with lots of SIDs\n");
959
960         sids.num_sids = 100;
961
962         sids.sids = talloc_array(tctx, struct lsa_SidPtr, sids.num_sids);
963
964         for (i=0; i<sids.num_sids; i++) {
965                 const char *sidstr = "S-1-5-32-545";
966                 sids.sids[i].sid = dom_sid_parse_talloc(tctx, sidstr);
967         }
968
969         count = sids.num_sids;
970
971         if (handle) {
972                 struct lsa_LookupSids r;
973                 struct lsa_TransNameArray names;
974                 struct lsa_RefDomainList *domains = NULL;
975                 names.count = 0;
976                 names.names = NULL;
977
978                 r.in.handle = handle;
979                 r.in.sids = &sids;
980                 r.in.names = &names;
981                 r.in.level = 1;
982                 r.in.count = &names.count;
983                 r.out.count = &count;
984                 r.out.names = &names;
985                 r.out.domains = &domains;
986
987                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupSids_r(b, tctx, &r),
988                         "LookupSids failed");
989                 if (!NT_STATUS_IS_OK(r.out.result)) {
990                         torture_comment(tctx, "LookupSids failed - %s\n",
991                                         nt_errstr(r.out.result));
992                         return false;
993                 }
994
995                 torture_comment(tctx, "\n");
996
997                 if (!test_LookupNames(b, tctx, handle, &names)) {
998                         return false;
999                 }
1000         }
1001
1002         if (transport == NCACN_NP) {
1003                 if (!test_LookupSids3_fail(b, tctx, &sids)) {
1004                         return false;
1005                 }
1006                 if (!test_LookupNames4_fail(b, tctx)) {
1007                         return false;
1008                 }
1009         } else if (transport == NCACN_IP_TCP) {
1010                 struct lsa_TransNameArray2 names;
1011                 enum dcerpc_AuthType auth_type;
1012                 enum dcerpc_AuthLevel auth_level;
1013
1014                 names.count = 0;
1015                 names.names = NULL;
1016
1017                 dcerpc_binding_handle_auth_info(p->binding_handle,
1018                                                 &auth_type, &auth_level);
1019
1020                 if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL &&
1021                     auth_level >= DCERPC_AUTH_LEVEL_INTEGRITY) {
1022                         if (!test_LookupSids3(b, tctx, &sids)) {
1023                                 return false;
1024                         }
1025                         if (!test_LookupNames4(b, tctx, &names, true)) {
1026                                 return false;
1027                         }
1028                 } else {
1029                         /*
1030                          * If we don't have a secure channel these tests must
1031                          * fail with ACCESS_DENIED.
1032                          */
1033                         if (!test_LookupSids3_fail(b, tctx, &sids)) {
1034                                 return false;
1035                         }
1036                         if (!test_LookupNames4_fail(b, tctx)) {
1037                                 return false;
1038                         }
1039                 }
1040         }
1041
1042         torture_comment(tctx, "\n");
1043
1044
1045
1046         return true;
1047 }
1048
1049 static void lookupsids_cb(struct tevent_req *subreq)
1050 {
1051         int *replies = (int *)tevent_req_callback_data_void(subreq);
1052         NTSTATUS status;
1053
1054         status = dcerpc_lsa_LookupSids_r_recv(subreq, subreq);
1055         TALLOC_FREE(subreq);
1056         if (!NT_STATUS_IS_OK(status)) {
1057                 printf("lookupsids returned %s\n", nt_errstr(status));
1058                 *replies = -1;
1059         }
1060
1061         if (*replies >= 0) {
1062                 *replies += 1;
1063         }
1064 }
1065
1066 static bool test_LookupSids_async(struct dcerpc_binding_handle *b,
1067                                   struct torture_context *tctx,
1068                                   struct policy_handle *handle)
1069 {
1070         struct lsa_SidArray sids;
1071         struct lsa_SidPtr sidptr;
1072         uint32_t *count;
1073         struct lsa_TransNameArray *names;
1074         struct lsa_LookupSids *r;
1075         struct lsa_RefDomainList *domains = NULL;
1076         struct tevent_req **req;
1077         int i, replies;
1078         bool ret = true;
1079         const int num_async_requests = 50;
1080
1081         count = talloc_array(tctx, uint32_t, num_async_requests);
1082         names = talloc_array(tctx, struct lsa_TransNameArray, num_async_requests);
1083         r = talloc_array(tctx, struct lsa_LookupSids, num_async_requests);
1084
1085         torture_comment(tctx, "\nTesting %d async lookupsids request\n", num_async_requests);
1086
1087         req = talloc_array(tctx, struct tevent_req *, num_async_requests);
1088
1089         sids.num_sids = 1;
1090         sids.sids = &sidptr;
1091         sidptr.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-545");
1092
1093         replies = 0;
1094
1095         for (i=0; i<num_async_requests; i++) {
1096                 count[i] = 0;
1097                 names[i].count = 0;
1098                 names[i].names = NULL;
1099
1100                 r[i].in.handle = handle;
1101                 r[i].in.sids = &sids;
1102                 r[i].in.names = &names[i];
1103                 r[i].in.level = 1;
1104                 r[i].in.count = &names[i].count;
1105                 r[i].out.count = &count[i];
1106                 r[i].out.names = &names[i];
1107                 r[i].out.domains = &domains;
1108
1109                 req[i] = dcerpc_lsa_LookupSids_r_send(tctx, tctx->ev, b, &r[i]);
1110                 if (req[i] == NULL) {
1111                         ret = false;
1112                         break;
1113                 }
1114
1115                 tevent_req_set_callback(req[i], lookupsids_cb, &replies);
1116         }
1117
1118         while (replies >= 0 && replies < num_async_requests) {
1119                 tevent_loop_once(tctx->ev);
1120         }
1121
1122         talloc_free(req);
1123
1124         if (replies < 0) {
1125                 ret = false;
1126         }
1127
1128         return ret;
1129 }
1130
1131 static bool test_LookupPrivValue(struct dcerpc_binding_handle *b,
1132                                  struct torture_context *tctx,
1133                                  struct policy_handle *handle,
1134                                  struct lsa_String *name)
1135 {
1136         struct lsa_LookupPrivValue r;
1137         struct lsa_LUID luid;
1138
1139         r.in.handle = handle;
1140         r.in.name = name;
1141         r.out.luid = &luid;
1142
1143         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupPrivValue_r(b, tctx, &r),
1144                 "LookupPrivValue failed");
1145         torture_assert_ntstatus_ok(tctx, r.out.result,
1146                 "LookupPrivValue failed");
1147
1148         return true;
1149 }
1150
1151 static bool test_LookupPrivName(struct dcerpc_binding_handle *b,
1152                                 struct torture_context *tctx,
1153                                 struct policy_handle *handle,
1154                                 struct lsa_LUID *luid)
1155 {
1156         struct lsa_LookupPrivName r;
1157         struct lsa_StringLarge *name = NULL;
1158
1159         r.in.handle = handle;
1160         r.in.luid = luid;
1161         r.out.name = &name;
1162
1163         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupPrivName_r(b, tctx, &r),
1164                 "LookupPrivName failed");
1165         torture_assert_ntstatus_ok(tctx, r.out.result, "LookupPrivName failed");
1166
1167         return true;
1168 }
1169
1170 static bool test_RemovePrivilegesFromAccount(struct dcerpc_binding_handle *b,
1171                                              struct torture_context *tctx,
1172                                              struct policy_handle *handle,
1173                                              struct policy_handle *acct_handle,
1174                                              struct lsa_LUID *luid)
1175 {
1176         struct lsa_RemovePrivilegesFromAccount r;
1177         struct lsa_PrivilegeSet privs;
1178         bool ret = true;
1179
1180         torture_comment(tctx, "\nTesting RemovePrivilegesFromAccount\n");
1181
1182         r.in.handle = acct_handle;
1183         r.in.remove_all = 0;
1184         r.in.privs = &privs;
1185
1186         privs.count = 1;
1187         privs.unknown = 0;
1188         privs.set = talloc_array(tctx, struct lsa_LUIDAttribute, 1);
1189         privs.set[0].luid = *luid;
1190         privs.set[0].attribute = 0;
1191
1192         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_RemovePrivilegesFromAccount_r(b, tctx, &r),
1193                 "RemovePrivilegesFromAccount failed");
1194         if (!NT_STATUS_IS_OK(r.out.result)) {
1195
1196                 struct lsa_LookupPrivName r_name;
1197                 struct lsa_StringLarge *name = NULL;
1198
1199                 r_name.in.handle = handle;
1200                 r_name.in.luid = luid;
1201                 r_name.out.name = &name;
1202
1203                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupPrivName_r(b, tctx, &r_name),
1204                         "LookupPrivName failed");
1205                 if (!NT_STATUS_IS_OK(r_name.out.result)) {
1206                         torture_comment(tctx, "\nLookupPrivName failed - %s\n",
1207                                         nt_errstr(r_name.out.result));
1208                         return false;
1209                 }
1210                 /* Windows 2008 does not allow this to be removed */
1211                 if (strcmp("SeAuditPrivilege", name->string) == 0) {
1212                         return ret;
1213                 }
1214
1215                 torture_comment(tctx, "RemovePrivilegesFromAccount failed to remove %s - %s\n",
1216                        name->string,
1217                        nt_errstr(r.out.result));
1218                 return false;
1219         }
1220
1221         return ret;
1222 }
1223
1224 static bool test_AddPrivilegesToAccount(struct dcerpc_binding_handle *b,
1225                                         struct torture_context *tctx,
1226                                         struct policy_handle *acct_handle,
1227                                         struct lsa_LUID *luid)
1228 {
1229         struct lsa_AddPrivilegesToAccount r;
1230         struct lsa_PrivilegeSet privs;
1231         bool ret = true;
1232
1233         torture_comment(tctx, "\nTesting AddPrivilegesToAccount\n");
1234
1235         r.in.handle = acct_handle;
1236         r.in.privs = &privs;
1237
1238         privs.count = 1;
1239         privs.unknown = 0;
1240         privs.set = talloc_array(tctx, struct lsa_LUIDAttribute, 1);
1241         privs.set[0].luid = *luid;
1242         privs.set[0].attribute = 0;
1243
1244         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_AddPrivilegesToAccount_r(b, tctx, &r),
1245                 "AddPrivilegesToAccount failed");
1246         torture_assert_ntstatus_ok(tctx, r.out.result,
1247                 "AddPrivilegesToAccount failed");
1248         return ret;
1249 }
1250
1251 static bool test_EnumPrivsAccount(struct dcerpc_binding_handle *b,
1252                                   struct torture_context *tctx,
1253                                   struct policy_handle *handle,
1254                                   struct policy_handle *acct_handle)
1255 {
1256         struct lsa_EnumPrivsAccount r;
1257         struct lsa_PrivilegeSet *privs = NULL;
1258         bool ret = true;
1259
1260         torture_comment(tctx, "\nTesting EnumPrivsAccount\n");
1261
1262         r.in.handle = acct_handle;
1263         r.out.privs = &privs;
1264
1265         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumPrivsAccount_r(b, tctx, &r),
1266                 "EnumPrivsAccount failed");
1267         torture_assert_ntstatus_ok(tctx, r.out.result,
1268                 "EnumPrivsAccount failed");
1269
1270         if (privs && privs->count > 0) {
1271                 int i;
1272                 for (i=0;i<privs->count;i++) {
1273                         test_LookupPrivName(b, tctx, handle,
1274                                             &privs->set[i].luid);
1275                 }
1276
1277                 ret &= test_RemovePrivilegesFromAccount(b, tctx, handle, acct_handle,
1278                                                         &privs->set[0].luid);
1279                 ret &= test_AddPrivilegesToAccount(b, tctx, acct_handle,
1280                                                    &privs->set[0].luid);
1281         }
1282
1283         return ret;
1284 }
1285
1286 static bool test_GetSystemAccessAccount(struct dcerpc_binding_handle *b,
1287                                         struct torture_context *tctx,
1288                                         struct policy_handle *handle,
1289                                         struct policy_handle *acct_handle)
1290 {
1291         uint32_t access_mask;
1292         struct lsa_GetSystemAccessAccount r;
1293
1294         torture_comment(tctx, "\nTesting GetSystemAccessAccount\n");
1295
1296         r.in.handle = acct_handle;
1297         r.out.access_mask = &access_mask;
1298
1299         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetSystemAccessAccount_r(b, tctx, &r),
1300                 "GetSystemAccessAccount failed");
1301         torture_assert_ntstatus_ok(tctx, r.out.result,
1302                 "GetSystemAccessAccount failed");
1303
1304         if (r.out.access_mask != NULL) {
1305                 torture_comment(tctx, "Rights:");
1306                 if (*(r.out.access_mask) & LSA_POLICY_MODE_INTERACTIVE)
1307                         torture_comment(tctx, " LSA_POLICY_MODE_INTERACTIVE");
1308                 if (*(r.out.access_mask) & LSA_POLICY_MODE_NETWORK)
1309                         torture_comment(tctx, " LSA_POLICY_MODE_NETWORK");
1310                 if (*(r.out.access_mask) & LSA_POLICY_MODE_BATCH)
1311                         torture_comment(tctx, " LSA_POLICY_MODE_BATCH");
1312                 if (*(r.out.access_mask) & LSA_POLICY_MODE_SERVICE)
1313                         torture_comment(tctx, " LSA_POLICY_MODE_SERVICE");
1314                 if (*(r.out.access_mask) & LSA_POLICY_MODE_PROXY)
1315                         torture_comment(tctx, " LSA_POLICY_MODE_PROXY");
1316                 if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_INTERACTIVE)
1317                         torture_comment(tctx, " LSA_POLICY_MODE_DENY_INTERACTIVE");
1318                 if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_NETWORK)
1319                         torture_comment(tctx, " LSA_POLICY_MODE_DENY_NETWORK");
1320                 if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_BATCH)
1321                         torture_comment(tctx, " LSA_POLICY_MODE_DENY_BATCH");
1322                 if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_SERVICE)
1323                         torture_comment(tctx, " LSA_POLICY_MODE_DENY_SERVICE");
1324                 if (*(r.out.access_mask) & LSA_POLICY_MODE_REMOTE_INTERACTIVE)
1325                         torture_comment(tctx, " LSA_POLICY_MODE_REMOTE_INTERACTIVE");
1326                 if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_REMOTE_INTERACTIVE)
1327                         torture_comment(tctx, " LSA_POLICY_MODE_DENY_REMOTE_INTERACTIVE");
1328                 if (*(r.out.access_mask) & LSA_POLICY_MODE_ALL)
1329                         torture_comment(tctx, " LSA_POLICY_MODE_ALL");
1330                 if (*(r.out.access_mask) & LSA_POLICY_MODE_ALL_NT4)
1331                         torture_comment(tctx, " LSA_POLICY_MODE_ALL_NT4");
1332                 torture_comment(tctx, "\n");
1333         }
1334
1335         return true;
1336 }
1337
1338 static bool test_Delete(struct dcerpc_binding_handle *b,
1339                         struct torture_context *tctx,
1340                         struct policy_handle *handle)
1341 {
1342         struct lsa_Delete r;
1343
1344         torture_comment(tctx, "\nTesting Delete\n");
1345
1346         r.in.handle = handle;
1347         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Delete_r(b, tctx, &r),
1348                 "Delete failed");
1349         torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_SUPPORTED,
1350                 "Delete should have failed NT_STATUS_NOT_SUPPORTED");
1351
1352         return true;
1353 }
1354
1355 static bool test_DeleteObject(struct dcerpc_binding_handle *b,
1356                               struct torture_context *tctx,
1357                               struct policy_handle *handle)
1358 {
1359         struct lsa_DeleteObject r;
1360
1361         torture_comment(tctx, "\nTesting DeleteObject\n");
1362
1363         r.in.handle = handle;
1364         r.out.handle = handle;
1365         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_DeleteObject_r(b, tctx, &r),
1366                 "DeleteObject failed");
1367         torture_assert_ntstatus_ok(tctx, r.out.result,
1368                 "DeleteObject failed");
1369
1370         return true;
1371 }
1372
1373
1374 static bool test_CreateAccount(struct dcerpc_binding_handle *b,
1375                                struct torture_context *tctx,
1376                                struct policy_handle *handle)
1377 {
1378         struct lsa_CreateAccount r;
1379         struct dom_sid2 *newsid;
1380         struct policy_handle acct_handle;
1381
1382         newsid = dom_sid_parse_talloc(tctx, "S-1-5-12349876-4321-2854");
1383
1384         torture_comment(tctx, "\nTesting CreateAccount\n");
1385
1386         r.in.handle = handle;
1387         r.in.sid = newsid;
1388         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1389         r.out.acct_handle = &acct_handle;
1390
1391         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CreateAccount_r(b, tctx, &r),
1392                 "CreateAccount failed");
1393         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_OBJECT_NAME_COLLISION)) {
1394                 struct lsa_OpenAccount r_o;
1395                 r_o.in.handle = handle;
1396                 r_o.in.sid = newsid;
1397                 r_o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1398                 r_o.out.acct_handle = &acct_handle;
1399
1400                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(b, tctx, &r_o),
1401                         "OpenAccount failed");
1402                 torture_assert_ntstatus_ok(tctx, r_o.out.result,
1403                         "OpenAccount failed");
1404         } else {
1405                 torture_assert_ntstatus_ok(tctx, r.out.result,
1406                                            "CreateAccount failed");
1407         }
1408
1409         if (!test_Delete(b, tctx, &acct_handle)) {
1410                 return false;
1411         }
1412
1413         if (!test_DeleteObject(b, tctx, &acct_handle)) {
1414                 return false;
1415         }
1416
1417         return true;
1418 }
1419
1420 static bool test_DeleteTrustedDomain(struct dcerpc_binding_handle *b,
1421                                      struct torture_context *tctx,
1422                                      struct policy_handle *handle,
1423                                      struct lsa_StringLarge name)
1424 {
1425         struct lsa_OpenTrustedDomainByName r;
1426         struct policy_handle trustdom_handle;
1427
1428         r.in.handle = handle;
1429         r.in.name.string = name.string;
1430         r.in.access_mask = SEC_STD_DELETE;
1431         r.out.trustdom_handle = &trustdom_handle;
1432
1433         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenTrustedDomainByName_r(b, tctx, &r),
1434                 "OpenTrustedDomainByName failed");
1435         torture_assert_ntstatus_ok(tctx, r.out.result,
1436                 "OpenTrustedDomainByName failed");
1437
1438         if (!test_Delete(b, tctx, &trustdom_handle)) {
1439                 return false;
1440         }
1441
1442         if (!test_DeleteObject(b, tctx, &trustdom_handle)) {
1443                 return false;
1444         }
1445
1446         return true;
1447 }
1448
1449 static bool test_DeleteTrustedDomainBySid(struct dcerpc_binding_handle *b,
1450                                           struct torture_context *tctx,
1451                                           struct policy_handle *handle,
1452                                           struct dom_sid *sid)
1453 {
1454         struct lsa_DeleteTrustedDomain r;
1455
1456         r.in.handle = handle;
1457         r.in.dom_sid = sid;
1458
1459         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_DeleteTrustedDomain_r(b, tctx, &r),
1460                 "DeleteTrustedDomain failed");
1461         torture_assert_ntstatus_ok(tctx, r.out.result,
1462                 "DeleteTrustedDomain failed");
1463
1464         return true;
1465 }
1466
1467
1468 static bool test_CreateSecret(struct dcerpc_pipe *p,
1469                               struct torture_context *tctx,
1470                               struct policy_handle *handle)
1471 {
1472         struct lsa_CreateSecret r;
1473         struct lsa_OpenSecret r2;
1474         struct lsa_SetSecret r3;
1475         struct lsa_QuerySecret r4;
1476         struct lsa_SetSecret r5;
1477         struct lsa_QuerySecret r6;
1478         struct lsa_SetSecret r7;
1479         struct lsa_QuerySecret r8;
1480         struct policy_handle sec_handle, sec_handle2, sec_handle3;
1481         struct lsa_DeleteObject d_o;
1482         struct lsa_DATA_BUF buf1;
1483         struct lsa_DATA_BUF_PTR bufp1;
1484         struct lsa_DATA_BUF_PTR bufp2;
1485         DATA_BLOB enc_key;
1486         bool ret = true;
1487         DATA_BLOB session_key;
1488         NTTIME old_mtime, new_mtime;
1489         DATA_BLOB blob1;
1490         const char *secret1 = "abcdef12345699qwerty";
1491         char *secret2;
1492         const char *secret3 = "ABCDEF12345699QWERTY";
1493         char *secret4;
1494         const char *secret5 = "NEW-SAMBA4-SECRET";
1495         char *secret6;
1496         char *secname[2];
1497         int i;
1498         const int LOCAL = 0;
1499         const int GLOBAL = 1;
1500         struct dcerpc_binding_handle *b = p->binding_handle;
1501
1502         secname[LOCAL] = talloc_asprintf(tctx, "torturesecret-%u", (unsigned int)random());
1503         secname[GLOBAL] = talloc_asprintf(tctx, "G$torturesecret-%u", (unsigned int)random());
1504
1505         for (i=0; i< 2; i++) {
1506                 torture_comment(tctx, "\nTesting CreateSecret of %s\n", secname[i]);
1507
1508                 init_lsa_String(&r.in.name, secname[i]);
1509
1510                 r.in.handle = handle;
1511                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1512                 r.out.sec_handle = &sec_handle;
1513
1514                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CreateSecret_r(b, tctx, &r),
1515                         "CreateSecret failed");
1516                 torture_assert_ntstatus_ok(tctx, r.out.result,
1517                         "CreateSecret failed");
1518
1519                 r.in.handle = handle;
1520                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1521                 r.out.sec_handle = &sec_handle3;
1522
1523                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CreateSecret_r(b, tctx, &r),
1524                         "CreateSecret failed");
1525                 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_COLLISION,
1526                                               "CreateSecret should have failed OBJECT_NAME_COLLISION");
1527
1528                 r2.in.handle = handle;
1529                 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1530                 r2.in.name = r.in.name;
1531                 r2.out.sec_handle = &sec_handle2;
1532
1533                 torture_comment(tctx, "Testing OpenSecret\n");
1534
1535                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenSecret_r(b, tctx, &r2),
1536                         "OpenSecret failed");
1537                 torture_assert_ntstatus_ok(tctx, r2.out.result,
1538                                            "OpenSecret failed");
1539
1540                 torture_assert_ntstatus_ok(tctx, dcerpc_fetch_session_key(p, &session_key),
1541                                            "dcerpc_fetch_session_key failed");
1542
1543                 enc_key = sess_encrypt_string(secret1, &session_key);
1544
1545                 r3.in.sec_handle = &sec_handle;
1546                 r3.in.new_val = &buf1;
1547                 r3.in.old_val = NULL;
1548                 r3.in.new_val->data = enc_key.data;
1549                 r3.in.new_val->length = enc_key.length;
1550                 r3.in.new_val->size = enc_key.length;
1551
1552                 torture_comment(tctx, "Testing SetSecret\n");
1553
1554                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_SetSecret_r(b, tctx, &r3),
1555                         "SetSecret failed");
1556                 torture_assert_ntstatus_ok(tctx, r3.out.result,
1557                         "SetSecret failed");
1558
1559                 r3.in.sec_handle = &sec_handle;
1560                 r3.in.new_val = &buf1;
1561                 r3.in.old_val = NULL;
1562                 r3.in.new_val->data = enc_key.data;
1563                 r3.in.new_val->length = enc_key.length;
1564                 r3.in.new_val->size = enc_key.length;
1565
1566                 /* break the encrypted data */
1567                 enc_key.data[0]++;
1568
1569                 torture_comment(tctx, "Testing SetSecret with broken key\n");
1570
1571                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_SetSecret_r(b, tctx, &r3),
1572                                            "SetSecret failed");
1573                 torture_assert_ntstatus_equal(tctx, r3.out.result, NT_STATUS_UNKNOWN_REVISION,
1574                                               "SetSecret should have failed UNKNOWN_REVISION");
1575
1576                 data_blob_free(&enc_key);
1577
1578                 ZERO_STRUCT(new_mtime);
1579                 ZERO_STRUCT(old_mtime);
1580
1581                 /* fetch the secret back again */
1582                 r4.in.sec_handle = &sec_handle;
1583                 r4.in.new_val = &bufp1;
1584                 r4.in.new_mtime = &new_mtime;
1585                 r4.in.old_val = NULL;
1586                 r4.in.old_mtime = NULL;
1587
1588                 bufp1.buf = NULL;
1589
1590                 torture_comment(tctx, "Testing QuerySecret\n");
1591                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QuerySecret_r(b, tctx, &r4),
1592                         "QuerySecret failed");
1593                 if (!NT_STATUS_IS_OK(r4.out.result)) {
1594                         torture_comment(tctx, "QuerySecret failed - %s\n", nt_errstr(r4.out.result));
1595                         ret = false;
1596                 } else {
1597                         if (r4.out.new_val == NULL || r4.out.new_val->buf == NULL) {
1598                                 torture_comment(tctx, "No secret buffer returned\n");
1599                                 ret = false;
1600                         } else {
1601                                 blob1.data = r4.out.new_val->buf->data;
1602                                 blob1.length = r4.out.new_val->buf->size;
1603
1604                                 secret2 = sess_decrypt_string(tctx,
1605                                                               &blob1, &session_key);
1606
1607                                 if (strcmp(secret1, secret2) != 0) {
1608                                         torture_comment(tctx, "Returned secret (r4) '%s' doesn't match '%s'\n",
1609                                                secret2, secret1);
1610                                         ret = false;
1611                                 }
1612                         }
1613                 }
1614
1615                 enc_key = sess_encrypt_string(secret3, &session_key);
1616
1617                 r5.in.sec_handle = &sec_handle;
1618                 r5.in.new_val = &buf1;
1619                 r5.in.old_val = NULL;
1620                 r5.in.new_val->data = enc_key.data;
1621                 r5.in.new_val->length = enc_key.length;
1622                 r5.in.new_val->size = enc_key.length;
1623
1624
1625                 smb_msleep(200);
1626                 torture_comment(tctx, "Testing SetSecret (existing value should move to old)\n");
1627
1628                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_SetSecret_r(b, tctx, &r5),
1629                         "SetSecret failed");
1630                 if (!NT_STATUS_IS_OK(r5.out.result)) {
1631                         torture_comment(tctx, "SetSecret failed - %s\n", nt_errstr(r5.out.result));
1632                         ret = false;
1633                 }
1634
1635                 data_blob_free(&enc_key);
1636
1637                 ZERO_STRUCT(new_mtime);
1638                 ZERO_STRUCT(old_mtime);
1639
1640                 /* fetch the secret back again */
1641                 r6.in.sec_handle = &sec_handle;
1642                 r6.in.new_val = &bufp1;
1643                 r6.in.new_mtime = &new_mtime;
1644                 r6.in.old_val = &bufp2;
1645                 r6.in.old_mtime = &old_mtime;
1646
1647                 bufp1.buf = NULL;
1648                 bufp2.buf = NULL;
1649
1650                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QuerySecret_r(b, tctx, &r6),
1651                         "QuerySecret failed");
1652                 if (!NT_STATUS_IS_OK(r6.out.result)) {
1653                         torture_comment(tctx, "QuerySecret failed - %s\n", nt_errstr(r6.out.result));
1654                         ret = false;
1655                         secret4 = NULL;
1656                 } else {
1657
1658                         if (r6.out.new_val->buf == NULL || r6.out.old_val->buf == NULL
1659                                 || r6.out.new_mtime == NULL || r6.out.old_mtime == NULL) {
1660                                 torture_comment(tctx, "Both secret buffers and both times not returned\n");
1661                                 ret = false;
1662                                 secret4 = NULL;
1663                         } else {
1664                                 blob1.data = r6.out.new_val->buf->data;
1665                                 blob1.length = r6.out.new_val->buf->size;
1666
1667                                 secret4 = sess_decrypt_string(tctx,
1668                                                               &blob1, &session_key);
1669
1670                                 if (strcmp(secret3, secret4) != 0) {
1671                                         torture_comment(tctx, "Returned NEW secret %s doesn't match %s\n", secret4, secret3);
1672                                         ret = false;
1673                                 }
1674
1675                                 blob1.data = r6.out.old_val->buf->data;
1676                                 blob1.length = r6.out.old_val->buf->length;
1677
1678                                 secret2 = sess_decrypt_string(tctx,
1679                                                               &blob1, &session_key);
1680
1681                                 if (strcmp(secret1, secret2) != 0) {
1682                                         torture_comment(tctx, "Returned OLD secret %s doesn't match %s\n", secret2, secret1);
1683                                         ret = false;
1684                                 }
1685
1686                                 if (*r6.out.new_mtime == *r6.out.old_mtime) {
1687                                         torture_comment(tctx, "Returned secret (r6-%d) %s must not have same mtime for both secrets: %s != %s\n",
1688                                                i,
1689                                                secname[i],
1690                                                nt_time_string(tctx, *r6.out.old_mtime),
1691                                                nt_time_string(tctx, *r6.out.new_mtime));
1692                                         ret = false;
1693                                 }
1694                         }
1695                 }
1696
1697                 enc_key = sess_encrypt_string(secret5, &session_key);
1698
1699                 r7.in.sec_handle = &sec_handle;
1700                 r7.in.old_val = &buf1;
1701                 r7.in.old_val->data = enc_key.data;
1702                 r7.in.old_val->length = enc_key.length;
1703                 r7.in.old_val->size = enc_key.length;
1704                 r7.in.new_val = NULL;
1705
1706                 torture_comment(tctx, "Testing SetSecret of old Secret only\n");
1707
1708                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_SetSecret_r(b, tctx, &r7),
1709                         "SetSecret failed");
1710                 if (!NT_STATUS_IS_OK(r7.out.result)) {
1711                         torture_comment(tctx, "SetSecret failed - %s\n", nt_errstr(r7.out.result));
1712                         ret = false;
1713                 }
1714
1715                 data_blob_free(&enc_key);
1716
1717                 /* fetch the secret back again */
1718                 r8.in.sec_handle = &sec_handle;
1719                 r8.in.new_val = &bufp1;
1720                 r8.in.new_mtime = &new_mtime;
1721                 r8.in.old_val = &bufp2;
1722                 r8.in.old_mtime = &old_mtime;
1723
1724                 bufp1.buf = NULL;
1725                 bufp2.buf = NULL;
1726
1727                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QuerySecret_r(b, tctx, &r8),
1728                         "QuerySecret failed");
1729                 if (!NT_STATUS_IS_OK(r8.out.result)) {
1730                         torture_comment(tctx, "QuerySecret failed - %s\n", nt_errstr(r8.out.result));
1731                         ret = false;
1732                 } else {
1733                         if (!r8.out.new_val || !r8.out.old_val) {
1734                                 torture_comment(tctx, "in/out pointers not returned, despite being set on in for QuerySecret\n");
1735                                 ret = false;
1736                         } else if (r8.out.new_val->buf != NULL) {
1737                                 torture_comment(tctx, "NEW secret buffer must not be returned after OLD set\n");
1738                                 ret = false;
1739                         } else if (r8.out.old_val->buf == NULL) {
1740                                 torture_comment(tctx, "OLD secret buffer was not returned after OLD set\n");
1741                                 ret = false;
1742                         } else if (r8.out.new_mtime == NULL || r8.out.old_mtime == NULL) {
1743                                 torture_comment(tctx, "Both times not returned after OLD set\n");
1744                                 ret = false;
1745                         } else {
1746                                 blob1.data = r8.out.old_val->buf->data;
1747                                 blob1.length = r8.out.old_val->buf->size;
1748
1749                                 secret6 = sess_decrypt_string(tctx,
1750                                                               &blob1, &session_key);
1751
1752                                 if (strcmp(secret5, secret6) != 0) {
1753                                         torture_comment(tctx, "Returned OLD secret %s doesn't match %s\n", secret5, secret6);
1754                                         ret = false;
1755                                 }
1756
1757                                 if (*r8.out.new_mtime != *r8.out.old_mtime) {
1758                                         torture_comment(tctx, "Returned secret (r8) %s did not had same mtime for both secrets: %s != %s\n",
1759                                                secname[i],
1760                                                nt_time_string(tctx, *r8.out.old_mtime),
1761                                                nt_time_string(tctx, *r8.out.new_mtime));
1762                                         ret = false;
1763                                 }
1764                         }
1765                 }
1766
1767                 if (!test_Delete(b, tctx, &sec_handle)) {
1768                         ret = false;
1769                 }
1770
1771                 if (!test_DeleteObject(b, tctx, &sec_handle)) {
1772                         return false;
1773                 }
1774
1775                 d_o.in.handle = &sec_handle2;
1776                 d_o.out.handle = &sec_handle2;
1777                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_DeleteObject_r(b, tctx, &d_o),
1778                         "DeleteObject failed");
1779                 torture_assert_ntstatus_equal(tctx, d_o.out.result, NT_STATUS_INVALID_HANDLE,
1780                                               "OpenSecret expected INVALID_HANDLE");
1781
1782                 torture_comment(tctx, "Testing OpenSecret of just-deleted secret\n");
1783
1784                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenSecret_r(b, tctx, &r2),
1785                                            "OpenSecret failed");
1786                 torture_assert_ntstatus_equal(tctx, r2.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND,
1787                                               "OpenSecret expected OBJECT_NAME_NOT_FOUND");
1788         }
1789         return ret;
1790 }
1791
1792
1793 static bool test_EnumAccountRights(struct dcerpc_binding_handle *b,
1794                                    struct torture_context *tctx,
1795                                    struct policy_handle *acct_handle,
1796                                    struct dom_sid *sid)
1797 {
1798         struct lsa_EnumAccountRights r;
1799         struct lsa_RightSet rights;
1800
1801         torture_comment(tctx, "\nTesting EnumAccountRights\n");
1802
1803         r.in.handle = acct_handle;
1804         r.in.sid = sid;
1805         r.out.rights = &rights;
1806
1807         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(b, tctx, &r),
1808                 "EnumAccountRights failed");
1809         if (!NT_STATUS_IS_OK(r.out.result)) {
1810                 torture_comment(tctx, "EnumAccountRights of %s failed - %s\n",
1811                        dom_sid_string(tctx, sid), nt_errstr(r.out.result));
1812         }
1813         torture_assert_ntstatus_ok(tctx, r.out.result,
1814                 "EnumAccountRights failed");
1815
1816         return true;
1817 }
1818
1819
1820 static bool test_QuerySecurity(struct dcerpc_binding_handle *b,
1821                              struct torture_context *tctx,
1822                              struct policy_handle *handle,
1823                              struct policy_handle *acct_handle)
1824 {
1825         struct lsa_QuerySecurity r;
1826         struct sec_desc_buf *sdbuf = NULL;
1827
1828         if (torture_setting_bool(tctx, "samba4", false)) {
1829                 torture_comment(tctx, "\nskipping QuerySecurity test against Samba4\n");
1830                 return true;
1831         }
1832
1833         torture_comment(tctx, "\nTesting QuerySecurity\n");
1834
1835         r.in.handle = acct_handle;
1836         r.in.sec_info = SECINFO_OWNER |
1837                         SECINFO_GROUP |
1838                         SECINFO_DACL;
1839         r.out.sdbuf = &sdbuf;
1840
1841         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QuerySecurity_r(b, tctx, &r),
1842                 "QuerySecurity failed");
1843         if (!NT_STATUS_IS_OK(r.out.result)) {
1844                 torture_comment(tctx, "QuerySecurity failed - %s\n", nt_errstr(r.out.result));
1845                 return false;
1846         }
1847
1848         return true;
1849 }
1850
1851 static bool test_OpenAccount(struct dcerpc_binding_handle *b,
1852                              struct torture_context *tctx,
1853                              struct policy_handle *handle,
1854                              struct dom_sid *sid)
1855 {
1856         struct lsa_OpenAccount r;
1857         struct policy_handle acct_handle;
1858
1859         torture_comment(tctx, "\nTesting OpenAccount\n");
1860
1861         r.in.handle = handle;
1862         r.in.sid = sid;
1863         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1864         r.out.acct_handle = &acct_handle;
1865
1866         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(b, tctx, &r),
1867                 "OpenAccount failed");
1868         torture_assert_ntstatus_ok(tctx, r.out.result,
1869                 "OpenAccount failed");
1870
1871         if (!test_EnumPrivsAccount(b, tctx, handle, &acct_handle)) {
1872                 return false;
1873         }
1874
1875         if (!test_GetSystemAccessAccount(b, tctx, handle, &acct_handle)) {
1876                 return false;
1877         }
1878
1879         if (!test_QuerySecurity(b, tctx, handle, &acct_handle)) {
1880                 return false;
1881         }
1882
1883         return true;
1884 }
1885
1886 static bool test_EnumAccounts(struct dcerpc_binding_handle *b,
1887                               struct torture_context *tctx,
1888                               struct policy_handle *handle)
1889 {
1890         struct lsa_EnumAccounts r;
1891         struct lsa_SidArray sids1, sids2;
1892         uint32_t resume_handle = 0;
1893         int i;
1894         bool ret = true;
1895
1896         torture_comment(tctx, "\nTesting EnumAccounts\n");
1897
1898         r.in.handle = handle;
1899         r.in.resume_handle = &resume_handle;
1900         r.in.num_entries = 100;
1901         r.out.resume_handle = &resume_handle;
1902         r.out.sids = &sids1;
1903
1904         resume_handle = 0;
1905         while (true) {
1906                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(b, tctx, &r),
1907                         "EnumAccounts failed");
1908                 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES)) {
1909                         break;
1910                 }
1911                 torture_assert_ntstatus_ok(tctx, r.out.result,
1912                         "EnumAccounts failed");
1913
1914                 if (!test_LookupSids(b, tctx, handle, &sids1)) {
1915                         return false;
1916                 }
1917
1918                 if (!test_LookupSids2(b, tctx, handle, &sids1)) {
1919                         return false;
1920                 }
1921
1922                 /* Can't test lookupSids3 here, as clearly we must not
1923                  * be on schannel, or we would not be able to do the
1924                  * rest */
1925
1926                 torture_comment(tctx, "Testing all accounts\n");
1927                 for (i=0;i<sids1.num_sids;i++) {
1928                         ret &= test_OpenAccount(b, tctx, handle, sids1.sids[i].sid);
1929                         ret &= test_EnumAccountRights(b, tctx, handle, sids1.sids[i].sid);
1930                 }
1931                 torture_comment(tctx, "\n");
1932         }
1933
1934         if (sids1.num_sids < 3) {
1935                 return ret;
1936         }
1937
1938         torture_comment(tctx, "Trying EnumAccounts partial listing (asking for 1 at 2)\n");
1939         resume_handle = 2;
1940         r.in.num_entries = 1;
1941         r.out.sids = &sids2;
1942
1943         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(b, tctx, &r),
1944                 "EnumAccounts failed");
1945         torture_assert_ntstatus_ok(tctx, r.out.result,
1946                 "EnumAccounts failed");
1947
1948         if (sids2.num_sids != 1) {
1949                 torture_comment(tctx, "Returned wrong number of entries (%d)\n", sids2.num_sids);
1950                 return false;
1951         }
1952
1953         return true;
1954 }
1955
1956 static bool test_LookupPrivDisplayName(struct dcerpc_binding_handle *b,
1957                                        struct torture_context *tctx,
1958                                        struct policy_handle *handle,
1959                                        struct lsa_String *priv_name)
1960 {
1961         struct lsa_LookupPrivDisplayName r;
1962         /* produce a reasonable range of language output without screwing up
1963            terminals */
1964         uint16_t language_id = (random() % 4) + 0x409;
1965         uint16_t returned_language_id = 0;
1966         struct lsa_StringLarge *disp_name = NULL;
1967
1968         torture_comment(tctx, "\nTesting LookupPrivDisplayName(%s)\n", priv_name->string);
1969
1970         r.in.handle = handle;
1971         r.in.name = priv_name;
1972         r.in.language_id = language_id;
1973         r.in.language_id_sys = 0;
1974         r.out.returned_language_id = &returned_language_id;
1975         r.out.disp_name = &disp_name;
1976
1977         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupPrivDisplayName_r(b, tctx, &r),
1978                 "LookupPrivDisplayName failed");
1979         if (!NT_STATUS_IS_OK(r.out.result)) {
1980                 torture_comment(tctx, "LookupPrivDisplayName failed - %s\n", nt_errstr(r.out.result));
1981                 return false;
1982         }
1983         torture_comment(tctx, "%s -> \"%s\"  (language 0x%x/0x%x)\n",
1984                priv_name->string, disp_name->string,
1985                r.in.language_id, *r.out.returned_language_id);
1986
1987         return true;
1988 }
1989
1990 static bool test_EnumAccountsWithUserRight(struct dcerpc_binding_handle *b,
1991                                            struct torture_context *tctx,
1992                                            struct policy_handle *handle,
1993                                            struct lsa_String *priv_name)
1994 {
1995         struct lsa_EnumAccountsWithUserRight r;
1996         struct lsa_SidArray sids;
1997
1998         ZERO_STRUCT(sids);
1999
2000         torture_comment(tctx, "\nTesting EnumAccountsWithUserRight(%s)\n", priv_name->string);
2001
2002         r.in.handle = handle;
2003         r.in.name = priv_name;
2004         r.out.sids = &sids;
2005
2006         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountsWithUserRight_r(b, tctx, &r),
2007                 "EnumAccountsWithUserRight failed");
2008
2009         /* NT_STATUS_NO_MORE_ENTRIES means noone has this privilege */
2010         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES)) {
2011                 return true;
2012         }
2013
2014         if (!NT_STATUS_IS_OK(r.out.result)) {
2015                 torture_comment(tctx, "EnumAccountsWithUserRight failed - %s\n", nt_errstr(r.out.result));
2016                 return false;
2017         }
2018
2019         return true;
2020 }
2021
2022
2023 static bool test_EnumPrivs(struct dcerpc_binding_handle *b,
2024                            struct torture_context *tctx,
2025                            struct policy_handle *handle)
2026 {
2027         struct lsa_EnumPrivs r;
2028         struct lsa_PrivArray privs1;
2029         uint32_t resume_handle = 0;
2030         int i;
2031         bool ret = true;
2032
2033         torture_comment(tctx, "\nTesting EnumPrivs\n");
2034
2035         r.in.handle = handle;
2036         r.in.resume_handle = &resume_handle;
2037         r.in.max_count = 100;
2038         r.out.resume_handle = &resume_handle;
2039         r.out.privs = &privs1;
2040
2041         resume_handle = 0;
2042         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumPrivs_r(b, tctx, &r),
2043                 "EnumPrivs failed");
2044         torture_assert_ntstatus_ok(tctx, r.out.result,
2045                 "EnumPrivs failed");
2046
2047         for (i = 0; i< privs1.count; i++) {
2048                 test_LookupPrivDisplayName(b, tctx, handle, (struct lsa_String *)&privs1.privs[i].name);
2049                 test_LookupPrivValue(b, tctx, handle, (struct lsa_String *)&privs1.privs[i].name);
2050                 if (!test_EnumAccountsWithUserRight(b, tctx, handle, (struct lsa_String *)&privs1.privs[i].name)) {
2051                         ret = false;
2052                 }
2053         }
2054
2055         return ret;
2056 }
2057
2058 static bool test_QueryForestTrustInformation(struct dcerpc_binding_handle *b,
2059                                              struct torture_context *tctx,
2060                                              struct policy_handle *handle,
2061                                              const char *trusted_domain_name)
2062 {
2063         bool ret = true;
2064         struct lsa_lsaRQueryForestTrustInformation r;
2065         struct lsa_String string;
2066         struct lsa_ForestTrustInformation info, *info_ptr;
2067
2068         torture_comment(tctx, "\nTesting lsaRQueryForestTrustInformation\n");
2069
2070         if (torture_setting_bool(tctx, "samba4", false)) {
2071                 torture_comment(tctx, "skipping QueryForestTrustInformation against Samba4\n");
2072                 return true;
2073         }
2074
2075         ZERO_STRUCT(string);
2076
2077         if (trusted_domain_name) {
2078                 init_lsa_String(&string, trusted_domain_name);
2079         }
2080
2081         info_ptr = &info;
2082
2083         r.in.handle = handle;
2084         r.in.trusted_domain_name = &string;
2085         r.in.highest_record_type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
2086         r.out.forest_trust_info = &info_ptr;
2087
2088         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_lsaRQueryForestTrustInformation_r(b, tctx, &r),
2089                 "lsaRQueryForestTrustInformation failed");
2090
2091         if (!NT_STATUS_IS_OK(r.out.result)) {
2092                 torture_comment(tctx, "lsaRQueryForestTrustInformation of %s failed - %s\n", trusted_domain_name, nt_errstr(r.out.result));
2093                 ret = false;
2094         }
2095
2096         return ret;
2097 }
2098
2099 static bool test_query_each_TrustDomEx(struct dcerpc_binding_handle *b,
2100                                        struct torture_context *tctx,
2101                                        struct policy_handle *handle,
2102                                        struct lsa_DomainListEx *domains)
2103 {
2104         int i;
2105         bool ret = true;
2106
2107         for (i=0; i< domains->count; i++) {
2108
2109                 if (domains->domains[i].trust_attributes & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
2110                         ret &= test_QueryForestTrustInformation(b, tctx, handle,
2111                                                                 domains->domains[i].domain_name.string);
2112                 }
2113         }
2114
2115         return ret;
2116 }
2117
2118 static bool test_query_each_TrustDom(struct dcerpc_binding_handle *b,
2119                                      struct torture_context *tctx,
2120                                      struct policy_handle *handle,
2121                                      struct lsa_DomainList *domains)
2122 {
2123         int i,j;
2124         bool ret = true;
2125
2126         torture_comment(tctx, "\nTesting OpenTrustedDomain, OpenTrustedDomainByName and QueryInfoTrustedDomain\n");
2127         for (i=0; i< domains->count; i++) {
2128                 struct lsa_OpenTrustedDomain trust;
2129                 struct lsa_OpenTrustedDomainByName trust_by_name;
2130                 struct policy_handle trustdom_handle;
2131                 struct policy_handle handle2;
2132                 struct lsa_Close c;
2133                 struct lsa_CloseTrustedDomainEx c_trust;
2134                 int levels [] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
2135                 int ok[]      = {1, 0, 1, 0, 0, 1, 0, 1, 0,  0,  0,  1, 1};
2136
2137                 if (domains->domains[i].sid) {
2138                         trust.in.handle = handle;
2139                         trust.in.sid = domains->domains[i].sid;
2140                         trust.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2141                         trust.out.trustdom_handle = &trustdom_handle;
2142
2143                         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenTrustedDomain_r(b, tctx, &trust),
2144                                 "OpenTrustedDomain failed");
2145
2146                         if (NT_STATUS_EQUAL(trust.out.result, NT_STATUS_NO_SUCH_DOMAIN)) {
2147                                 torture_comment(tctx, "DOMAIN(%s, %s) not a direct trust?\n",
2148                                                 domains->domains[i].name.string,
2149                                                 dom_sid_string(tctx, domains->domains[i].sid));
2150                                 continue;
2151                         }
2152                         if (!NT_STATUS_IS_OK(trust.out.result)) {
2153                                 torture_comment(tctx, "OpenTrustedDomain failed - %s\n", nt_errstr(trust.out.result));
2154                                 return false;
2155                         }
2156
2157                         c.in.handle = &trustdom_handle;
2158                         c.out.handle = &handle2;
2159
2160                         c_trust.in.handle = &trustdom_handle;
2161                         c_trust.out.handle = &handle2;
2162
2163                         for (j=0; j < ARRAY_SIZE(levels); j++) {
2164                                 struct lsa_QueryTrustedDomainInfo q;
2165                                 union lsa_TrustedDomainInfo *info = NULL;
2166                                 q.in.trustdom_handle = &trustdom_handle;
2167                                 q.in.level = levels[j];
2168                                 q.out.info = &info;
2169                                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfo_r(b, tctx, &q),
2170                                         "QueryTrustedDomainInfo failed");
2171                                 if (!NT_STATUS_IS_OK(q.out.result) && ok[j]) {
2172                                         torture_comment(tctx, "QueryTrustedDomainInfo level %d failed - %s\n",
2173                                                levels[j], nt_errstr(q.out.result));
2174                                         ret = false;
2175                                 } else if (NT_STATUS_IS_OK(q.out.result) && !ok[j]) {
2176                                         torture_comment(tctx, "QueryTrustedDomainInfo level %d unexpectedly succeeded - %s\n",
2177                                                levels[j], nt_errstr(q.out.result));
2178                                         ret = false;
2179                                 }
2180                         }
2181
2182                         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CloseTrustedDomainEx_r(b, tctx, &c_trust),
2183                                 "CloseTrustedDomainEx failed");
2184                         if (!NT_STATUS_EQUAL(c_trust.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
2185                                 torture_comment(tctx, "Expected CloseTrustedDomainEx to return NT_STATUS_NOT_IMPLEMENTED, instead - %s\n", nt_errstr(c_trust.out.result));
2186                                 return false;
2187                         }
2188
2189                         c.in.handle = &trustdom_handle;
2190                         c.out.handle = &handle2;
2191
2192                         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Close_r(b, tctx, &c),
2193                                 "Close failed");
2194                         if (!NT_STATUS_IS_OK(c.out.result)) {
2195                                 torture_comment(tctx, "Close of trusted domain failed - %s\n", nt_errstr(c.out.result));
2196                                 return false;
2197                         }
2198
2199                         for (j=0; j < ARRAY_SIZE(levels); j++) {
2200                                 struct lsa_QueryTrustedDomainInfoBySid q;
2201                                 union lsa_TrustedDomainInfo *info = NULL;
2202
2203                                 if (!domains->domains[i].sid) {
2204                                         continue;
2205                                 }
2206
2207                                 q.in.handle  = handle;
2208                                 q.in.dom_sid = domains->domains[i].sid;
2209                                 q.in.level   = levels[j];
2210                                 q.out.info   = &info;
2211
2212                                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfoBySid_r(b, tctx, &q),
2213                                         "lsa_QueryTrustedDomainInfoBySid failed");
2214                                 if (!NT_STATUS_IS_OK(q.out.result) && ok[j]) {
2215                                         torture_comment(tctx, "QueryTrustedDomainInfoBySid level %d failed - %s\n",
2216                                                levels[j], nt_errstr(q.out.result));
2217                                         ret = false;
2218                                 } else if (NT_STATUS_IS_OK(q.out.result) && !ok[j]) {
2219                                         torture_comment(tctx, "QueryTrustedDomainInfoBySid level %d unexpectedly succeeded - %s\n",
2220                                                levels[j], nt_errstr(q.out.result));
2221                                         ret = false;
2222                                 }
2223                         }
2224                 }
2225
2226                 trust_by_name.in.handle = handle;
2227                 trust_by_name.in.name.string = domains->domains[i].name.string;
2228                 trust_by_name.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2229                 trust_by_name.out.trustdom_handle = &trustdom_handle;
2230
2231                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenTrustedDomainByName_r(b, tctx, &trust_by_name),
2232                         "OpenTrustedDomainByName failed");
2233
2234                 if (NT_STATUS_EQUAL(trust_by_name.out.result, NT_STATUS_NO_SUCH_DOMAIN)) {
2235                         torture_comment(tctx, "DOMAIN(%s, %s) not a direct trust?\n",
2236                                         domains->domains[i].name.string,
2237                                         dom_sid_string(tctx, domains->domains[i].sid));
2238                         continue;
2239                 }
2240                 if (!NT_STATUS_IS_OK(trust_by_name.out.result)) {
2241                         torture_comment(tctx, "OpenTrustedDomainByName failed - %s\n", nt_errstr(trust_by_name.out.result));
2242                         return false;
2243                 }
2244
2245                 for (j=0; j < ARRAY_SIZE(levels); j++) {
2246                         struct lsa_QueryTrustedDomainInfo q;
2247                         union lsa_TrustedDomainInfo *info = NULL;
2248                         q.in.trustdom_handle = &trustdom_handle;
2249                         q.in.level = levels[j];
2250                         q.out.info = &info;
2251                         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfo_r(b, tctx, &q),
2252                                 "QueryTrustedDomainInfo failed");
2253                         if (!NT_STATUS_IS_OK(q.out.result) && ok[j]) {
2254                                 torture_comment(tctx, "QueryTrustedDomainInfo level %d failed - %s\n",
2255                                        levels[j], nt_errstr(q.out.result));
2256                                 ret = false;
2257                         } else if (NT_STATUS_IS_OK(q.out.result) && !ok[j]) {
2258                                 torture_comment(tctx, "QueryTrustedDomainInfo level %d unexpectedly succeeded - %s\n",
2259                                        levels[j], nt_errstr(q.out.result));
2260                                 ret = false;
2261                         }
2262                 }
2263
2264                 c.in.handle = &trustdom_handle;
2265                 c.out.handle = &handle2;
2266
2267                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Close_r(b, tctx, &c),
2268                         "Close failed");
2269                 if (!NT_STATUS_IS_OK(c.out.result)) {
2270                         torture_comment(tctx, "Close of trusted domain failed - %s\n", nt_errstr(c.out.result));
2271                         return false;
2272                 }
2273
2274                 for (j=0; j < ARRAY_SIZE(levels); j++) {
2275                         struct lsa_QueryTrustedDomainInfoByName q;
2276                         union lsa_TrustedDomainInfo *info = NULL;
2277                         struct lsa_String name;
2278
2279                         name.string = domains->domains[i].name.string;
2280
2281                         q.in.handle         = handle;
2282                         q.in.trusted_domain = &name;
2283                         q.in.level          = levels[j];
2284                         q.out.info          = &info;
2285                         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfoByName_r(b, tctx, &q),
2286                                 "QueryTrustedDomainInfoByName failed");
2287                         if (!NT_STATUS_IS_OK(q.out.result) && ok[j]) {
2288                                 torture_comment(tctx, "QueryTrustedDomainInfoByName level %d failed - %s\n",
2289                                        levels[j], nt_errstr(q.out.result));
2290                                 ret = false;
2291                         } else if (NT_STATUS_IS_OK(q.out.result) && !ok[j]) {
2292                                 torture_comment(tctx, "QueryTrustedDomainInfoByName level %d unexpectedly succeeded - %s\n",
2293                                        levels[j], nt_errstr(q.out.result));
2294                                 ret = false;
2295                         }
2296                 }
2297         }
2298         return ret;
2299 }
2300
2301 static bool test_EnumTrustDom(struct dcerpc_binding_handle *b,
2302                               struct torture_context *tctx,
2303                               struct policy_handle *handle)
2304 {
2305         struct lsa_EnumTrustDom r;
2306         uint32_t in_resume_handle = 0;
2307         uint32_t out_resume_handle;
2308         struct lsa_DomainList domains;
2309         bool ret = true;
2310
2311         torture_comment(tctx, "\nTesting EnumTrustDom\n");
2312
2313         r.in.handle = handle;
2314         r.in.resume_handle = &in_resume_handle;
2315         r.in.max_size = 0;
2316         r.out.domains = &domains;
2317         r.out.resume_handle = &out_resume_handle;
2318
2319         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustDom_r(b, tctx, &r),
2320                 "lsa_EnumTrustDom failed");
2321
2322         /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
2323          * always be larger than the previous input resume handle, in
2324          * particular when hitting the last query it is vital to set the
2325          * resume handle correctly to avoid infinite client loops, as
2326          * seen e.g.  with Windows XP SP3 when resume handle is 0 and
2327          * status is NT_STATUS_OK - gd */
2328
2329         if (NT_STATUS_IS_OK(r.out.result) ||
2330             NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES) ||
2331             NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
2332         {
2333                 if (out_resume_handle <= in_resume_handle) {
2334                         torture_comment(tctx, "EnumTrustDom failed - should have returned output resume_handle (0x%08x) larger than input resume handle (0x%08x)\n",
2335                                 out_resume_handle, in_resume_handle);
2336                         return false;
2337                 }
2338         }
2339
2340         if (NT_STATUS_IS_OK(r.out.result)) {
2341                 if (domains.count == 0) {
2342                         torture_comment(tctx, "EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
2343                         return false;
2344                 }
2345         } else if (!(NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) || NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES))) {
2346                 torture_comment(tctx, "EnumTrustDom of zero size failed - %s\n", nt_errstr(r.out.result));
2347                 return false;
2348         }
2349
2350         /* Start from the bottom again */
2351         in_resume_handle = 0;
2352
2353         do {
2354                 r.in.handle = handle;
2355                 r.in.resume_handle = &in_resume_handle;
2356                 r.in.max_size = LSA_ENUM_TRUST_DOMAIN_MULTIPLIER * 3;
2357                 r.out.domains = &domains;
2358                 r.out.resume_handle = &out_resume_handle;
2359
2360                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustDom_r(b, tctx, &r),
2361                         "EnumTrustDom failed");
2362
2363                 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
2364                  * always be larger than the previous input resume handle, in
2365                  * particular when hitting the last query it is vital to set the
2366                  * resume handle correctly to avoid infinite client loops, as
2367                  * seen e.g.  with Windows XP SP3 when resume handle is 0 and
2368                  * status is NT_STATUS_OK - gd */
2369
2370                 if (NT_STATUS_IS_OK(r.out.result) ||
2371                     NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES) ||
2372                     NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
2373                 {
2374                         if (out_resume_handle <= in_resume_handle) {
2375                                 torture_comment(tctx, "EnumTrustDom failed - should have returned output resume_handle (0x%08x) larger than input resume handle (0x%08x)\n",
2376                                         out_resume_handle, in_resume_handle);
2377                                 return false;
2378                         }
2379                 }
2380
2381                 /* NO_MORE_ENTRIES is allowed */
2382                 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES)) {
2383                         if (domains.count == 0) {
2384                                 return true;
2385                         }
2386                         torture_comment(tctx, "EnumTrustDom failed - should have returned 0 trusted domains with 'NT_STATUS_NO_MORE_ENTRIES'\n");
2387                         return false;
2388                 } else if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES)) {
2389                         /* Windows 2003 gets this off by one on the first run */
2390                         if (r.out.domains->count < 3 || r.out.domains->count > 4) {
2391                                 torture_comment(tctx, "EnumTrustDom didn't fill the buffer we "
2392                                        "asked it to (got %d, expected %d / %d == %d entries)\n",
2393                                        r.out.domains->count, LSA_ENUM_TRUST_DOMAIN_MULTIPLIER * 3,
2394                                        LSA_ENUM_TRUST_DOMAIN_MULTIPLIER, r.in.max_size);
2395                                 ret = false;
2396                         }
2397                 } else if (!NT_STATUS_IS_OK(r.out.result)) {
2398                         torture_comment(tctx, "EnumTrustDom failed - %s\n", nt_errstr(r.out.result));
2399                         return false;
2400                 }
2401
2402                 if (domains.count == 0) {
2403                         torture_comment(tctx, "EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
2404                         return false;
2405                 }
2406
2407                 ret &= test_query_each_TrustDom(b, tctx, handle, &domains);
2408
2409                 in_resume_handle = out_resume_handle;
2410
2411         } while ((NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES)));
2412
2413         return ret;
2414 }
2415
2416 static bool test_EnumTrustDomEx(struct dcerpc_binding_handle *b,
2417                                 struct torture_context *tctx,
2418                                 struct policy_handle *handle)
2419 {
2420         struct lsa_EnumTrustedDomainsEx r_ex;
2421         uint32_t in_resume_handle = 0;
2422         uint32_t out_resume_handle;
2423         struct lsa_DomainListEx domains_ex;
2424         bool ret = true;
2425
2426         torture_comment(tctx, "\nTesting EnumTrustedDomainsEx\n");
2427
2428         r_ex.in.handle = handle;
2429         r_ex.in.resume_handle = &in_resume_handle;
2430         r_ex.in.max_size = 0;
2431         r_ex.out.domains = &domains_ex;
2432         r_ex.out.resume_handle = &out_resume_handle;
2433
2434         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustedDomainsEx_r(b, tctx, &r_ex),
2435                 "EnumTrustedDomainsEx failed");
2436
2437         /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
2438          * always be larger than the previous input resume handle, in
2439          * particular when hitting the last query it is vital to set the
2440          * resume handle correctly to avoid infinite client loops, as
2441          * seen e.g.  with Windows XP SP3 when resume handle is 0 and
2442          * status is NT_STATUS_OK - gd */
2443
2444         if (NT_STATUS_IS_OK(r_ex.out.result) ||
2445             NT_STATUS_EQUAL(r_ex.out.result, NT_STATUS_NO_MORE_ENTRIES) ||
2446             NT_STATUS_EQUAL(r_ex.out.result, STATUS_MORE_ENTRIES))
2447         {
2448                 if (out_resume_handle <= in_resume_handle) {
2449                         torture_comment(tctx, "EnumTrustDomEx failed - should have returned output resume_handle (0x%08x) larger than input resume handle (0x%08x)\n",
2450                                 out_resume_handle, in_resume_handle);
2451                         return false;
2452                 }
2453         }
2454
2455         if (NT_STATUS_IS_OK(r_ex.out.result)) {
2456                 if (domains_ex.count == 0) {
2457                         torture_comment(tctx, "EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
2458                         return false;
2459                 }
2460         } else if (!(NT_STATUS_EQUAL(r_ex.out.result, STATUS_MORE_ENTRIES) ||
2461                     NT_STATUS_EQUAL(r_ex.out.result, NT_STATUS_NO_MORE_ENTRIES))) {
2462                 torture_comment(tctx, "EnumTrustDom of zero size failed - %s\n",
2463                                 nt_errstr(r_ex.out.result));
2464                 return false;
2465         }
2466
2467         in_resume_handle = 0;
2468         do {
2469                 r_ex.in.handle = handle;
2470                 r_ex.in.resume_handle = &in_resume_handle;
2471                 r_ex.in.max_size = LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER * 3;
2472                 r_ex.out.domains = &domains_ex;
2473                 r_ex.out.resume_handle = &out_resume_handle;
2474
2475                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustedDomainsEx_r(b, tctx, &r_ex),
2476                         "EnumTrustedDomainsEx failed");
2477
2478                 in_resume_handle = out_resume_handle;
2479
2480                 /* NO_MORE_ENTRIES is allowed */
2481                 if (NT_STATUS_EQUAL(r_ex.out.result, NT_STATUS_NO_MORE_ENTRIES)) {
2482                         if (domains_ex.count == 0) {
2483                                 return true;
2484                         }
2485                         torture_comment(tctx, "EnumTrustDomainsEx failed - should have returned 0 trusted domains with 'NT_STATUS_NO_MORE_ENTRIES'\n");
2486                         return false;
2487                 } else if (NT_STATUS_EQUAL(r_ex.out.result, STATUS_MORE_ENTRIES)) {
2488                         /* Windows 2003 gets this off by one on the first run */
2489                         if (r_ex.out.domains->count < 3 || r_ex.out.domains->count > 4) {
2490                                 torture_comment(tctx, "EnumTrustDom didn't fill the buffer we "
2491                                        "asked it to (got %d, expected %d / %d == %d entries)\n",
2492                                        r_ex.out.domains->count,
2493                                        r_ex.in.max_size,
2494                                        LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER,
2495                                        r_ex.in.max_size / LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER);
2496                         }
2497                 } else if (!NT_STATUS_IS_OK(r_ex.out.result)) {
2498                         torture_comment(tctx, "EnumTrustedDomainEx failed - %s\n", nt_errstr(r_ex.out.result));
2499                         return false;
2500                 }
2501
2502                 if (domains_ex.count == 0) {
2503                         torture_comment(tctx, "EnumTrustDomainEx failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
2504                         return false;
2505                 }
2506
2507                 ret &= test_query_each_TrustDomEx(b, tctx, handle, &domains_ex);
2508
2509         } while ((NT_STATUS_EQUAL(r_ex.out.result, STATUS_MORE_ENTRIES)));
2510
2511         return ret;
2512 }
2513
2514
2515 static bool test_CreateTrustedDomain(struct dcerpc_binding_handle *b,
2516                                      struct torture_context *tctx,
2517                                      struct policy_handle *handle,
2518                                      uint32_t num_trusts)
2519 {
2520         bool ret = true;
2521         struct lsa_CreateTrustedDomain r;
2522         struct lsa_DomainInfo trustinfo;
2523         struct dom_sid **domsid;
2524         struct policy_handle *trustdom_handle;
2525         struct lsa_QueryTrustedDomainInfo q;
2526         union lsa_TrustedDomainInfo *info = NULL;
2527         int i;
2528
2529         torture_comment(tctx, "\nTesting CreateTrustedDomain for %d domains\n", num_trusts);
2530
2531         if (!test_EnumTrustDom(b, tctx, handle)) {
2532                 ret = false;
2533         }
2534
2535         if (!test_EnumTrustDomEx(b, tctx, handle)) {
2536                 ret = false;
2537         }
2538
2539         domsid = talloc_array(tctx, struct dom_sid *, num_trusts);
2540         trustdom_handle = talloc_array(tctx, struct policy_handle, num_trusts);
2541
2542         for (i=0; i< num_trusts; i++) {
2543                 char *trust_name = talloc_asprintf(tctx, "TORTURE1%02d", i);
2544                 char *trust_sid = talloc_asprintf(tctx, "S-1-5-21-97398-379795-1%02d", i);
2545
2546                 domsid[i] = dom_sid_parse_talloc(tctx, trust_sid);
2547
2548                 trustinfo.sid = domsid[i];
2549                 init_lsa_String((struct lsa_String *)&trustinfo.name, trust_name);
2550
2551                 r.in.policy_handle = handle;
2552                 r.in.info = &trustinfo;
2553                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2554                 r.out.trustdom_handle = &trustdom_handle[i];
2555
2556                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CreateTrustedDomain_r(b, tctx, &r),
2557                         "CreateTrustedDomain failed");
2558                 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_OBJECT_NAME_COLLISION)) {
2559                         test_DeleteTrustedDomain(b, tctx, handle, trustinfo.name);
2560                         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CreateTrustedDomain_r(b, tctx, &r),
2561                                 "CreateTrustedDomain failed");
2562                 }
2563                 if (!NT_STATUS_IS_OK(r.out.result)) {
2564                         torture_comment(tctx, "CreateTrustedDomain failed - %s\n", nt_errstr(r.out.result));
2565                         ret = false;
2566                 } else {
2567
2568                         q.in.trustdom_handle = &trustdom_handle[i];
2569                         q.in.level = LSA_TRUSTED_DOMAIN_INFO_INFO_EX;
2570                         q.out.info = &info;
2571                         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfo_r(b, tctx, &q),
2572                                 "QueryTrustedDomainInfo failed");
2573                         if (!NT_STATUS_IS_OK(q.out.result)) {
2574                                 torture_comment(tctx, "QueryTrustedDomainInfo level %d failed - %s\n", q.in.level, nt_errstr(q.out.result));
2575                                 ret = false;
2576                         } else if (!q.out.info) {
2577                                 ret = false;
2578                         } else {
2579                                 if (strcmp(info->info_ex.domain_name.string, trustinfo.name.string) != 0) {
2580                                         torture_comment(tctx, "QueryTrustedDomainInfo returned inconsistent long name: %s != %s\n",
2581                                                info->info_ex.domain_name.string, trustinfo.name.string);
2582                                         ret = false;
2583                                 }
2584                                 if (strcmp(info->info_ex.netbios_name.string, trustinfo.name.string) != 0) {
2585                                         torture_comment(tctx, "QueryTrustedDomainInfo returned inconsistent short name: %s != %s\n",
2586                                                info->info_ex.netbios_name.string, trustinfo.name.string);
2587                                         ret = false;
2588                                 }
2589                                 if (info->info_ex.trust_type != LSA_TRUST_TYPE_DOWNLEVEL) {
2590                                         torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n",
2591                                                trust_name, info->info_ex.trust_type, LSA_TRUST_TYPE_DOWNLEVEL);
2592                                         ret = false;
2593                                 }
2594                                 if (info->info_ex.trust_attributes != 0) {
2595                                         torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n",
2596                                                trust_name, info->info_ex.trust_attributes, 0);
2597                                         ret = false;
2598                                 }
2599                                 if (info->info_ex.trust_direction != LSA_TRUST_DIRECTION_OUTBOUND) {
2600                                         torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n",
2601                                                trust_name, info->info_ex.trust_direction, LSA_TRUST_DIRECTION_OUTBOUND);
2602                                         ret = false;
2603                                 }
2604                         }
2605                 }
2606         }
2607
2608         /* now that we have some domains to look over, we can test the enum calls */
2609         if (!test_EnumTrustDom(b, tctx, handle)) {
2610                 ret = false;
2611         }
2612
2613         if (!test_EnumTrustDomEx(b, tctx, handle)) {
2614                 ret = false;
2615         }
2616
2617         for (i=0; i<num_trusts; i++) {
2618                 if (!test_DeleteTrustedDomainBySid(b, tctx, handle, domsid[i])) {
2619                         ret = false;
2620                 }
2621         }
2622
2623         return ret;
2624 }
2625
2626 static bool gen_authinfo_internal(TALLOC_CTX *mem_ctx,
2627                                   const char *incoming_old, const char *incoming_new,
2628                                   const char *outgoing_old, const char *outgoing_new,
2629                                   DATA_BLOB session_key,
2630                                   struct lsa_TrustDomainInfoAuthInfoInternal **_authinfo_internal)
2631 {
2632         struct lsa_TrustDomainInfoAuthInfoInternal *authinfo_internal;
2633         struct trustDomainPasswords auth_struct;
2634         struct AuthenticationInformation in_info;
2635         struct AuthenticationInformation io_info;
2636         struct AuthenticationInformation on_info;
2637         struct AuthenticationInformation oo_info;
2638         size_t converted_size;
2639         DATA_BLOB auth_blob;
2640         enum ndr_err_code ndr_err;
2641         bool ok;
2642
2643         authinfo_internal = talloc_zero(mem_ctx, struct lsa_TrustDomainInfoAuthInfoInternal);
2644         if (authinfo_internal == NULL) {
2645                 return false;
2646         }
2647
2648         in_info.AuthType = TRUST_AUTH_TYPE_CLEAR;
2649         ok = convert_string_talloc(mem_ctx, CH_UNIX, CH_UTF16,
2650                                    incoming_new,
2651                                    strlen(incoming_new),
2652                                    &in_info.AuthInfo.clear.password,
2653                                    &converted_size);
2654         if (!ok) {
2655                 return false;
2656         }
2657         in_info.AuthInfo.clear.size = converted_size;
2658
2659         io_info.AuthType = TRUST_AUTH_TYPE_CLEAR;
2660         ok = convert_string_talloc(mem_ctx, CH_UNIX, CH_UTF16,
2661                                    incoming_old,
2662                                    strlen(incoming_old),
2663                                    &io_info.AuthInfo.clear.password,
2664                                    &converted_size);
2665         if (!ok) {
2666                 return false;
2667         }
2668         io_info.AuthInfo.clear.size = converted_size;
2669
2670         on_info.AuthType = TRUST_AUTH_TYPE_CLEAR;
2671         ok = convert_string_talloc(mem_ctx, CH_UNIX, CH_UTF16,
2672                                    outgoing_new,
2673                                    strlen(outgoing_new),
2674                                    &on_info.AuthInfo.clear.password,
2675                                    &converted_size);
2676         if (!ok) {
2677                 return false;
2678         }
2679         on_info.AuthInfo.clear.size = converted_size;
2680
2681         oo_info.AuthType = TRUST_AUTH_TYPE_CLEAR;
2682         ok = convert_string_talloc(mem_ctx, CH_UNIX, CH_UTF16,
2683                                    outgoing_old,
2684                                    strlen(outgoing_old),
2685                                    &oo_info.AuthInfo.clear.password,
2686                                    &converted_size);
2687         if (!ok) {
2688                 return false;
2689         }
2690         oo_info.AuthInfo.clear.size = converted_size;
2691
2692         generate_random_buffer(auth_struct.confounder, sizeof(auth_struct.confounder));
2693         auth_struct.outgoing.count = 1;
2694         auth_struct.outgoing.current.count = 1;
2695         auth_struct.outgoing.current.array = &on_info;
2696         auth_struct.outgoing.previous.count = 1;
2697         auth_struct.outgoing.previous.array = &oo_info;
2698
2699         auth_struct.incoming.count = 1;
2700         auth_struct.incoming.current.count = 1;
2701         auth_struct.incoming.current.array = &in_info;
2702         auth_struct.incoming.previous.count = 1;
2703         auth_struct.incoming.previous.array = &io_info;
2704
2705         ndr_err = ndr_push_struct_blob(&auth_blob, mem_ctx, &auth_struct,
2706                                        (ndr_push_flags_fn_t)ndr_push_trustDomainPasswords);
2707         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2708                 return false;
2709         }
2710
2711         arcfour_crypt_blob(auth_blob.data, auth_blob.length, &session_key);
2712
2713         authinfo_internal->auth_blob.size = auth_blob.length;
2714         authinfo_internal->auth_blob.data = auth_blob.data;
2715
2716         *_authinfo_internal = authinfo_internal;
2717
2718         return true;
2719 }
2720
2721 static bool gen_authinfo(TALLOC_CTX *mem_ctx,
2722                          const char *incoming_old, const char *incoming_new,
2723                          const char *outgoing_old, const char *outgoing_new,
2724                          struct lsa_TrustDomainInfoAuthInfo **_authinfo)
2725 {
2726         struct lsa_TrustDomainInfoAuthInfo *authinfo;
2727         struct lsa_TrustDomainInfoBuffer *in_buffer;
2728         struct lsa_TrustDomainInfoBuffer *io_buffer;
2729         struct lsa_TrustDomainInfoBuffer *on_buffer;
2730         struct lsa_TrustDomainInfoBuffer *oo_buffer;
2731         size_t converted_size;
2732         bool ok;
2733
2734         authinfo = talloc_zero(mem_ctx, struct lsa_TrustDomainInfoAuthInfo);
2735         if (authinfo == NULL) {
2736                 return false;
2737         }
2738
2739         in_buffer = talloc_zero(authinfo, struct lsa_TrustDomainInfoBuffer);
2740         if (in_buffer == NULL) {
2741                 return false;
2742         }
2743         in_buffer->AuthType = TRUST_AUTH_TYPE_CLEAR;
2744         ok = convert_string_talloc(in_buffer, CH_UNIX, CH_UTF16,
2745                                    incoming_new,
2746                                    strlen(incoming_new),
2747                                    &in_buffer->data.data,
2748                                    &converted_size);
2749         if (!ok) {
2750                 return false;
2751         }
2752         in_buffer->data.size = converted_size;
2753
2754         io_buffer = talloc_zero(authinfo, struct lsa_TrustDomainInfoBuffer);
2755         if (io_buffer == NULL) {
2756                 return false;
2757         }
2758         io_buffer->AuthType = TRUST_AUTH_TYPE_CLEAR;
2759         ok = convert_string_talloc(io_buffer, CH_UNIX, CH_UTF16,
2760                                    incoming_old,
2761                                    strlen(incoming_old),
2762                                    &io_buffer->data.data,
2763                                    &converted_size);
2764         if (!ok) {
2765                 return false;
2766         }
2767         io_buffer->data.size = converted_size;
2768
2769         on_buffer = talloc_zero(authinfo, struct lsa_TrustDomainInfoBuffer);
2770         if (on_buffer == NULL) {
2771                 return false;
2772         }
2773         on_buffer->AuthType = TRUST_AUTH_TYPE_CLEAR;
2774         ok = convert_string_talloc(on_buffer, CH_UNIX, CH_UTF16,
2775                                    outgoing_new,
2776                                    strlen(outgoing_new),
2777                                    &on_buffer->data.data,
2778                                    &converted_size);
2779         if (!ok) {
2780                 return false;
2781         }
2782         on_buffer->data.size = converted_size;
2783
2784         oo_buffer = talloc_zero(authinfo, struct lsa_TrustDomainInfoBuffer);
2785         if (oo_buffer == NULL) {
2786                 return false;
2787         }
2788         oo_buffer->AuthType = TRUST_AUTH_TYPE_CLEAR;
2789         ok = convert_string_talloc(oo_buffer, CH_UNIX, CH_UTF16,
2790                                    outgoing_old,
2791                                    strlen(outgoing_old),
2792                                    &oo_buffer->data.data,
2793                                    &converted_size);
2794         if (!ok) {
2795                 return false;
2796         }
2797         oo_buffer->data.size = converted_size;
2798
2799         authinfo->incoming_count = 1;
2800         authinfo->incoming_current_auth_info = in_buffer;
2801         authinfo->incoming_previous_auth_info = io_buffer;
2802         authinfo->outgoing_count = 1;
2803         authinfo->outgoing_current_auth_info = on_buffer;
2804         authinfo->outgoing_previous_auth_info = oo_buffer;
2805
2806         *_authinfo = authinfo;
2807
2808         return true;
2809 }
2810
2811 static bool check_pw_with_ServerAuthenticate3(struct dcerpc_pipe *p,
2812                                              struct torture_context *tctx,
2813                                              uint32_t negotiate_flags,
2814                                              const char *server_name,
2815                                              struct cli_credentials *machine_credentials,
2816                                              struct netlogon_creds_CredentialState **creds_out)
2817 {
2818         struct netr_ServerReqChallenge r;
2819         struct netr_ServerAuthenticate3 a;
2820         struct netr_Credential credentials1, credentials2, credentials3;
2821         struct netlogon_creds_CredentialState *creds;
2822         const struct samr_Password *new_password = NULL;
2823         const struct samr_Password *old_password = NULL;
2824         uint32_t rid;
2825         struct dcerpc_binding_handle *b = p->binding_handle;
2826
2827         new_password = cli_credentials_get_nt_hash(machine_credentials, tctx);
2828         old_password = cli_credentials_get_old_nt_hash(machine_credentials, tctx);
2829
2830         r.in.server_name = server_name;
2831         r.in.computer_name = cli_credentials_get_workstation(machine_credentials);
2832         r.in.credentials = &credentials1;
2833         r.out.return_credentials = &credentials2;
2834
2835         generate_random_buffer(credentials1.data, sizeof(credentials1.data));
2836
2837         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
2838                 "ServerReqChallenge failed");
2839         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
2840
2841         a.in.server_name = server_name;
2842         a.in.account_name = cli_credentials_get_username(machine_credentials);
2843         a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2844         a.in.computer_name = cli_credentials_get_workstation(machine_credentials);
2845         a.in.negotiate_flags = &negotiate_flags;
2846         a.in.credentials = &credentials3;
2847         a.out.return_credentials = &credentials3;
2848         a.out.negotiate_flags = &negotiate_flags;
2849         a.out.rid = &rid;
2850
2851         creds = netlogon_creds_client_init(tctx, a.in.account_name,
2852                                            a.in.computer_name,
2853                                            a.in.secure_channel_type,
2854                                            &credentials1, &credentials2,
2855                                            new_password, &credentials3,
2856                                            negotiate_flags);
2857
2858         torture_assert(tctx, creds != NULL, "memory allocation");
2859
2860         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
2861                 "ServerAuthenticate3 failed");
2862         if (!NT_STATUS_IS_OK(a.out.result)) {
2863                 if (!NT_STATUS_EQUAL(a.out.result, NT_STATUS_ACCESS_DENIED)) {
2864                         torture_assert_ntstatus_ok(tctx, a.out.result,
2865                                                    "ServerAuthenticate3 failed");
2866                 }
2867                 return false;
2868         }
2869         torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
2870
2871         if (old_password != NULL) {
2872                 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
2873                         "ServerReqChallenge failed");
2874                 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
2875
2876                 creds = netlogon_creds_client_init(tctx, a.in.account_name,
2877                                                    a.in.computer_name,
2878                                                    a.in.secure_channel_type,
2879                                                    &credentials1, &credentials2,
2880                                                    old_password, &credentials3,
2881                                                    negotiate_flags);
2882
2883                 torture_assert(tctx, creds != NULL, "memory allocation");
2884
2885                 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
2886                         "ServerAuthenticate3 failed");
2887                 if (!NT_STATUS_IS_OK(a.out.result)) {
2888                         if (!NT_STATUS_EQUAL(a.out.result, NT_STATUS_ACCESS_DENIED)) {
2889                                 torture_assert_ntstatus_ok(tctx, a.out.result,
2890                                                            "ServerAuthenticate3 (old) failed");
2891                         }
2892                         return false;
2893                 }
2894                 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential (old) chaining failed");
2895         }
2896
2897         /* Prove that requesting a challenge again won't break it */
2898         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
2899                 "ServerReqChallenge failed");
2900         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
2901
2902         *creds_out = creds;
2903         return true;
2904 }
2905
2906 /*
2907  * This function is set in torture_krb5_init_context as krb5
2908  * send_and_recv function.  This allows us to override what server the
2909  * test is aimed at, and to inspect the packets just before they are
2910  * sent to the network, and before they are processed on the recv
2911  * side.
2912  *
2913  * The torture_krb5_pre_send_test() and torture_krb5_post_recv_test()
2914  * functions are implement the actual tests.
2915  *
2916  * When this asserts, the caller will get a spurious 'cannot contact
2917  * any KDC' message.
2918  *
2919  */
2920 struct check_pw_with_krb5_ctx {
2921         struct addrinfo *server;
2922         struct {
2923                 unsigned io;
2924                 unsigned fail;
2925                 unsigned errors;
2926                 unsigned error_io;
2927                 unsigned ok;
2928         } counts;
2929         krb5_error error;
2930         struct smb_krb5_context *smb_krb5_context;
2931         krb5_get_init_creds_opt *krb_options;
2932         krb5_creds my_creds;
2933         krb5_get_creds_opt opt_canon;
2934         krb5_get_creds_opt opt_nocanon;
2935         krb5_principal upn_realm;
2936         krb5_principal upn_dns;
2937         krb5_principal upn_netbios;
2938         krb5_ccache krbtgt_ccache;
2939         krb5_principal krbtgt_trust_realm;
2940         krb5_creds *krbtgt_trust_realm_creds;
2941         krb5_principal krbtgt_trust_dns;
2942         krb5_creds *krbtgt_trust_dns_creds;
2943         krb5_principal krbtgt_trust_netbios;
2944         krb5_creds *krbtgt_trust_netbios_creds;
2945         krb5_principal cifs_trust_dns;
2946         krb5_creds *cifs_trust_dns_creds;
2947         krb5_principal cifs_trust_netbios;
2948         krb5_creds *cifs_trust_netbios_creds;
2949         krb5_principal drs_trust_dns;
2950         krb5_creds *drs_trust_dns_creds;
2951         krb5_principal drs_trust_netbios;
2952         krb5_creds *drs_trust_netbios_creds;
2953         krb5_principal four_trust_dns;
2954         krb5_creds *four_trust_dns_creds;
2955         krb5_creds krbtgt_referral_creds;
2956         Ticket krbtgt_referral_ticket;
2957         krb5_keyblock krbtgt_referral_keyblock;
2958         EncTicketPart krbtgt_referral_enc_part;
2959 };
2960
2961 static krb5_error_code check_pw_with_krb5_send_and_recv_func(krb5_context context,
2962                                         void *data, /* struct check_pw_with_krb5_ctx */
2963                                         krb5_krbhst_info *_hi,
2964                                         time_t timeout,
2965                                         const krb5_data *send_buf,
2966                                         krb5_data *recv_buf)
2967 {
2968         struct check_pw_with_krb5_ctx *ctx =
2969                 talloc_get_type_abort(data, struct check_pw_with_krb5_ctx);
2970         krb5_error_code k5ret;
2971         krb5_krbhst_info hi = *_hi;
2972         size_t used;
2973         int ret;
2974
2975         hi.proto = KRB5_KRBHST_TCP;
2976
2977         smb_krb5_free_error(ctx->smb_krb5_context->krb5_context,
2978                             &ctx->error);
2979         ctx->counts.io++;
2980
2981         k5ret = smb_krb5_send_and_recv_func_forced(context, ctx->server,
2982                                                    &hi, timeout, send_buf, recv_buf);
2983         if (k5ret != 0) {
2984                 ctx->counts.fail++;
2985                 return k5ret;
2986         }
2987
2988         ret = decode_KRB_ERROR(recv_buf->data, recv_buf->length,
2989                                &ctx->error, &used);
2990         if (ret == 0) {
2991                 ctx->counts.errors++;
2992                 ctx->counts.error_io = ctx->counts.io;
2993         } else {
2994                 ctx->counts.ok++;
2995         }
2996
2997         return k5ret;
2998 }
2999
3000 static int check_pw_with_krb5_ctx_destructor(struct check_pw_with_krb5_ctx *ctx)
3001 {
3002         if (ctx->server != NULL) {
3003                 freeaddrinfo(ctx->server);
3004                 ctx->server = NULL;
3005         }
3006
3007         if (ctx->krb_options != NULL) {
3008                 krb5_get_init_creds_opt_free(ctx->smb_krb5_context->krb5_context,
3009                                              ctx->krb_options);
3010                 ctx->krb_options = NULL;
3011         }
3012
3013         krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3014                                 &ctx->my_creds);
3015
3016         if (ctx->opt_canon != NULL) {
3017                 krb5_get_creds_opt_free(ctx->smb_krb5_context->krb5_context,
3018                                         ctx->opt_canon);
3019                 ctx->opt_canon = NULL;
3020         }
3021
3022         if (ctx->opt_nocanon != NULL) {
3023                 krb5_get_creds_opt_free(ctx->smb_krb5_context->krb5_context,
3024                                         ctx->opt_nocanon);
3025                 ctx->opt_nocanon = NULL;
3026         }
3027
3028         if (ctx->krbtgt_ccache != NULL) {
3029                 krb5_cc_close(ctx->smb_krb5_context->krb5_context,
3030                               ctx->krbtgt_ccache);
3031                 ctx->krbtgt_ccache = NULL;
3032         }
3033
3034         if (ctx->upn_realm != NULL) {
3035                 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3036                                     ctx->upn_realm);
3037                 ctx->upn_realm = NULL;
3038         }
3039
3040         if (ctx->upn_dns != NULL) {
3041                 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3042                                     ctx->upn_dns);
3043                 ctx->upn_dns = NULL;
3044         }
3045
3046         if (ctx->upn_netbios != NULL) {
3047                 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3048                                     ctx->upn_netbios);
3049                 ctx->upn_netbios = NULL;
3050         }
3051
3052         if (ctx->krbtgt_trust_realm != NULL) {
3053                 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3054                                     ctx->krbtgt_trust_realm);
3055                 ctx->krbtgt_trust_realm = NULL;
3056         }
3057
3058         if (ctx->krbtgt_trust_realm_creds != NULL) {
3059                 krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3060                                 ctx->krbtgt_trust_realm_creds);
3061                 ctx->krbtgt_trust_realm_creds = NULL;
3062         }
3063
3064         if (ctx->krbtgt_trust_dns != NULL) {
3065                 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3066                                     ctx->krbtgt_trust_dns);
3067                 ctx->krbtgt_trust_dns = NULL;
3068         }
3069
3070         if (ctx->krbtgt_trust_dns_creds != NULL) {
3071                 krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3072                                 ctx->krbtgt_trust_dns_creds);
3073                 ctx->krbtgt_trust_dns_creds = NULL;
3074         }
3075
3076         if (ctx->krbtgt_trust_netbios != NULL) {
3077                 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3078                                     ctx->krbtgt_trust_netbios);
3079                 ctx->krbtgt_trust_netbios = NULL;
3080         }
3081
3082         if (ctx->krbtgt_trust_netbios_creds != NULL) {
3083                 krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3084                                 ctx->krbtgt_trust_netbios_creds);
3085                 ctx->krbtgt_trust_netbios_creds = NULL;
3086         }
3087
3088         if (ctx->cifs_trust_dns != NULL) {
3089                 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3090                                     ctx->cifs_trust_dns);
3091                 ctx->cifs_trust_dns = NULL;
3092         }
3093
3094         if (ctx->cifs_trust_dns_creds != NULL) {
3095                 krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3096                                 ctx->cifs_trust_dns_creds);
3097                 ctx->cifs_trust_dns_creds = NULL;
3098         }
3099
3100         if (ctx->cifs_trust_netbios != NULL) {
3101                 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3102                                     ctx->cifs_trust_netbios);
3103                 ctx->cifs_trust_netbios = NULL;
3104         }
3105
3106         if (ctx->cifs_trust_netbios_creds != NULL) {
3107                 krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3108                                 ctx->cifs_trust_netbios_creds);
3109                 ctx->cifs_trust_netbios_creds = NULL;
3110         }
3111
3112         if (ctx->drs_trust_dns != NULL) {
3113                 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3114                                     ctx->drs_trust_dns);
3115                 ctx->drs_trust_dns = NULL;
3116         }
3117
3118         if (ctx->drs_trust_dns_creds != NULL) {
3119                 krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3120                                 ctx->drs_trust_dns_creds);
3121                 ctx->drs_trust_dns_creds = NULL;
3122         }
3123
3124         if (ctx->drs_trust_netbios != NULL) {
3125                 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3126                                     ctx->drs_trust_netbios);
3127                 ctx->drs_trust_netbios = NULL;
3128         }
3129
3130         if (ctx->drs_trust_netbios_creds != NULL) {
3131                 krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3132                                 ctx->drs_trust_netbios_creds);
3133                 ctx->drs_trust_netbios_creds = NULL;
3134         }
3135
3136         if (ctx->four_trust_dns != NULL) {
3137                 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3138                                     ctx->four_trust_dns);
3139                 ctx->four_trust_dns = NULL;
3140         }
3141
3142         if (ctx->four_trust_dns_creds != NULL) {
3143                 krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3144                                 ctx->four_trust_dns_creds);
3145                 ctx->four_trust_dns_creds = NULL;
3146         }
3147
3148         krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3149                                 &ctx->krbtgt_referral_creds);
3150
3151         free_Ticket(&ctx->krbtgt_referral_ticket);
3152
3153         krb5_free_keyblock_contents(ctx->smb_krb5_context->krb5_context,
3154                                     &ctx->krbtgt_referral_keyblock);
3155
3156         free_EncTicketPart(&ctx->krbtgt_referral_enc_part);
3157
3158         smb_krb5_free_error(ctx->smb_krb5_context->krb5_context,
3159                             &ctx->error);
3160
3161         talloc_unlink(ctx, ctx->smb_krb5_context);
3162         ctx->smb_krb5_context = NULL;
3163         return 0;
3164 }
3165
3166 static bool check_pw_with_krb5(struct torture_context *tctx,
3167                                struct cli_credentials *credentials,
3168                                const struct lsa_TrustDomainInfoInfoEx *trusted)
3169 {
3170         const char *trusted_dns_name = trusted->domain_name.string;
3171         const char *trusted_netbios_name = trusted->netbios_name.string;
3172         char *trusted_realm_name = NULL;
3173         krb5_principal principal = NULL;
3174         enum credentials_obtained obtained;
3175         const char *error_string = NULL;
3176         const char *workstation = cli_credentials_get_workstation(credentials);
3177         const char *password = cli_credentials_get_password(credentials);
3178         const struct samr_Password *nthash = NULL;
3179         const struct samr_Password *old_nthash = NULL;
3180         const char *old_password = cli_credentials_get_old_password(credentials);
3181         int kvno = cli_credentials_get_kvno(credentials);
3182         int expected_kvno = 0;
3183         krb5uint32 t_kvno = 0;
3184         const char *host = torture_setting_string(tctx, "host", NULL);
3185         krb5_error_code k5ret;
3186         krb5_boolean k5ok;
3187         int type;
3188         bool ok;
3189         struct check_pw_with_krb5_ctx *ctx = NULL;
3190         char *assertion_message = NULL;
3191         const char *realm = NULL;
3192         char *upn_realm_string = NULL;
3193         char *upn_dns_string = NULL;
3194         char *upn_netbios_string = NULL;
3195         char *krbtgt_cc_name = NULL;
3196         char *krbtgt_trust_realm_string = NULL;
3197         char *krbtgt_trust_dns_string = NULL;
3198         char *krbtgt_trust_netbios_string = NULL;
3199         char *cifs_trust_dns_string = NULL;
3200         char *cifs_trust_netbios_string = NULL;
3201         char *drs_trust_dns_string = NULL;
3202         char *drs_trust_netbios_string = NULL;
3203         char *four_trust_dns_string = NULL;
3204
3205         ctx = talloc_zero(tctx, struct check_pw_with_krb5_ctx);
3206         torture_assert(tctx, ctx != NULL, "Failed to allocate");
3207
3208         realm = cli_credentials_get_realm(credentials);
3209         trusted_realm_name = strupper_talloc(tctx, trusted_dns_name);
3210
3211         nthash = cli_credentials_get_nt_hash(credentials, ctx);
3212         old_nthash = cli_credentials_get_old_nt_hash(credentials, ctx);
3213
3214         k5ret = smb_krb5_init_context(ctx, tctx->lp_ctx, &ctx->smb_krb5_context);
3215         torture_assert_int_equal(tctx, k5ret, 0, "smb_krb5_init_context failed");
3216
3217         ok = interpret_string_addr_internal(&ctx->server, host, AI_NUMERICHOST);
3218         torture_assert(tctx, ok, "Failed to parse target server");
3219         talloc_set_destructor(ctx, check_pw_with_krb5_ctx_destructor);
3220
3221         set_sockaddr_port(ctx->server->ai_addr, 88);
3222
3223         k5ret = krb5_set_send_to_kdc_func(ctx->smb_krb5_context->krb5_context,
3224                                           check_pw_with_krb5_send_and_recv_func,
3225                                           ctx);
3226         torture_assert_int_equal(tctx, k5ret, 0, "krb5_set_send_to_kdc_func failed");
3227
3228         torture_assert_int_equal(tctx,
3229                         krb5_get_init_creds_opt_alloc(ctx->smb_krb5_context->krb5_context,
3230                                                       &ctx->krb_options),
3231                         0, "krb5_get_init_creds_opt_alloc failed");
3232         torture_assert_int_equal(tctx,
3233                         krb5_get_init_creds_opt_set_pac_request(
3234                                 ctx->smb_krb5_context->krb5_context,
3235                                 ctx->krb_options, true),
3236                         0, "krb5_get_init_creds_opt_set_pac_request failed");
3237
3238         upn_realm_string = talloc_asprintf(ctx, "user@%s",
3239                                            trusted_realm_name);
3240         torture_assert_int_equal(tctx,
3241                         smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3242                                                 &ctx->upn_realm,
3243                                                 realm, upn_realm_string, NULL),
3244                         0, "smb_krb5_make_principal failed");
3245         krb5_principal_set_type(ctx->smb_krb5_context->krb5_context,
3246                                 ctx->upn_realm, KRB5_NT_ENTERPRISE_PRINCIPAL);
3247
3248         upn_dns_string = talloc_asprintf(ctx, "user@%s",
3249                                          trusted_dns_name);
3250         torture_assert_int_equal(tctx,
3251                         smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3252                                                 &ctx->upn_dns,
3253                                                 realm, upn_dns_string, NULL),
3254                         0, "smb_krb5_make_principal failed");
3255         krb5_principal_set_type(ctx->smb_krb5_context->krb5_context,
3256                                 ctx->upn_dns, KRB5_NT_ENTERPRISE_PRINCIPAL);
3257
3258         upn_netbios_string = talloc_asprintf(ctx, "user@%s",
3259                                          trusted_netbios_name);
3260         torture_assert_int_equal(tctx,
3261                         smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3262                                                 &ctx->upn_netbios,
3263                                                 realm, upn_netbios_string, NULL),
3264                         0, "smb_krb5_make_principal failed");
3265         krb5_principal_set_type(ctx->smb_krb5_context->krb5_context,
3266                                 ctx->upn_netbios, KRB5_NT_ENTERPRISE_PRINCIPAL);
3267
3268         k5ret = principal_from_credentials(ctx, credentials, ctx->smb_krb5_context,
3269                                            &principal, &obtained,  &error_string);
3270         torture_assert_int_equal(tctx, k5ret, 0, error_string);
3271
3272         ZERO_STRUCT(ctx->counts);
3273         k5ret = krb5_get_init_creds_password(ctx->smb_krb5_context->krb5_context,
3274                                              &ctx->my_creds, ctx->upn_realm,
3275                                              "_none_", NULL, NULL, 0,
3276                                              NULL, ctx->krb_options);
3277         assertion_message = talloc_asprintf(ctx,
3278                                 "krb5_get_init_creds_password(%s, canon) for failed: "
3279                                 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u/%u,ok=%u]",
3280                                 upn_realm_string,
3281                                 k5ret,
3282                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3283                                                            k5ret, ctx),
3284                                 trusted->trust_direction,
3285                                 trusted->trust_type,
3286                                 trusted->trust_attributes,
3287                                 ctx->counts.io, ctx->counts.error_io, ctx->counts.errors, ctx->counts.ok);
3288         torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3289         torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3290         torture_assert_int_equal(tctx, ctx->counts.error_io, 1, assertion_message);
3291         torture_assert_int_equal(tctx, KRB5_ERROR_CODE(&ctx->error), 68, assertion_message);
3292         torture_assert(tctx, ctx->error.crealm != NULL, assertion_message);
3293         torture_assert_str_equal(tctx, *ctx->error.crealm, trusted_realm_name, assertion_message);
3294         torture_assert(tctx, ctx->error.cname == NULL, assertion_message);
3295         torture_assert_str_equal(tctx, ctx->error.realm, realm, assertion_message);
3296
3297         ZERO_STRUCT(ctx->counts);
3298         k5ret = krb5_get_init_creds_password(ctx->smb_krb5_context->krb5_context,
3299                                              &ctx->my_creds, ctx->upn_dns,
3300                                              "_none_", NULL, NULL, 0,
3301                                              NULL, ctx->krb_options);
3302         assertion_message = talloc_asprintf(ctx,
3303                                 "krb5_get_init_creds_password(%s, canon) for failed: "
3304                                 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u/%u,ok=%u]",
3305                                 upn_dns_string,
3306                                 k5ret,
3307                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3308                                                            k5ret, ctx),
3309                                 trusted->trust_direction,
3310                                 trusted->trust_type,
3311                                 trusted->trust_attributes,
3312                                 ctx->counts.io, ctx->counts.error_io, ctx->counts.errors, ctx->counts.ok);
3313         torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3314         torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3315         torture_assert_int_equal(tctx, ctx->counts.error_io, 1, assertion_message);
3316         torture_assert_int_equal(tctx, KRB5_ERROR_CODE(&ctx->error), 68, assertion_message);
3317         torture_assert(tctx, ctx->error.crealm != NULL, assertion_message);
3318         torture_assert_str_equal(tctx, *ctx->error.crealm, trusted_realm_name, assertion_message);
3319         torture_assert(tctx, ctx->error.cname == NULL, assertion_message);
3320         torture_assert_str_equal(tctx, ctx->error.realm, realm, assertion_message);
3321
3322         ZERO_STRUCT(ctx->counts);
3323         k5ret = krb5_get_init_creds_password(ctx->smb_krb5_context->krb5_context,
3324                                              &ctx->my_creds, ctx->upn_netbios,
3325                                              "_none_", NULL, NULL, 0,
3326                                              NULL, ctx->krb_options);
3327         assertion_message = talloc_asprintf(ctx,
3328                                 "krb5_get_init_creds_password(%s, canon) for failed: "
3329                                 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u/%u,ok=%u]",
3330                                 upn_netbios_string,
3331                                 k5ret,
3332                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3333                                                            k5ret, ctx),
3334                                 trusted->trust_direction,
3335                                 trusted->trust_type,
3336                                 trusted->trust_attributes,
3337                                 ctx->counts.io, ctx->counts.error_io, ctx->counts.errors, ctx->counts.ok);
3338         torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3339         torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3340         torture_assert_int_equal(tctx, ctx->counts.error_io, 1, assertion_message);
3341         torture_assert_int_equal(tctx, KRB5_ERROR_CODE(&ctx->error), 68, assertion_message);
3342         torture_assert(tctx, ctx->error.crealm != NULL, assertion_message);
3343         torture_assert_str_equal(tctx, *ctx->error.crealm, trusted_realm_name, assertion_message);
3344         torture_assert(tctx, ctx->error.cname == NULL, assertion_message);
3345         torture_assert_str_equal(tctx, ctx->error.realm, realm, assertion_message);
3346
3347         torture_comment(tctx, "password[%s] old_password[%s]\n",
3348                         password, old_password);
3349         if (old_password != NULL) {
3350                 k5ret = krb5_get_init_creds_password(ctx->smb_krb5_context->krb5_context,
3351                                                      &ctx->my_creds, principal,
3352                                                      old_password, NULL, NULL, 0,
3353                                                      NULL, ctx->krb_options);
3354                 torture_assert_int_equal(tctx, k5ret, KRB5KDC_ERR_PREAUTH_FAILED,
3355                                          "preauth should fail with old password");
3356         }
3357
3358         k5ret = krb5_get_init_creds_password(ctx->smb_krb5_context->krb5_context,
3359                                              &ctx->my_creds, principal,
3360                                              password, NULL, NULL, 0,
3361                                              NULL, ctx->krb_options);
3362         if (k5ret == KRB5KDC_ERR_PREAUTH_FAILED) {
3363                 TALLOC_FREE(ctx);
3364                 return false;
3365         }
3366
3367         assertion_message = talloc_asprintf(ctx,
3368                                 "krb5_get_init_creds_password for failed: %s",
3369                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3370                                                            k5ret, ctx));
3371         torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3372
3373         torture_assert_int_equal(tctx,
3374                         krb5_get_creds_opt_alloc(ctx->smb_krb5_context->krb5_context,
3375                                                  &ctx->opt_canon),
3376                         0, "krb5_get_creds_opt_alloc");
3377
3378         krb5_get_creds_opt_add_options(ctx->smb_krb5_context->krb5_context,
3379                                        ctx->opt_canon,
3380                                        KRB5_GC_CANONICALIZE);
3381
3382         krb5_get_creds_opt_add_options(ctx->smb_krb5_context->krb5_context,
3383                                        ctx->opt_canon,
3384                                        KRB5_GC_NO_STORE);
3385
3386         torture_assert_int_equal(tctx,
3387                         krb5_get_creds_opt_alloc(ctx->smb_krb5_context->krb5_context,
3388                                                  &ctx->opt_nocanon),
3389                         0, "krb5_get_creds_opt_alloc");
3390
3391         krb5_get_creds_opt_add_options(ctx->smb_krb5_context->krb5_context,
3392                                        ctx->opt_nocanon,
3393                                        KRB5_GC_NO_STORE);
3394
3395         krbtgt_cc_name = talloc_asprintf(ctx, "MEMORY:%p.krbtgt", ctx->smb_krb5_context);
3396         torture_assert_int_equal(tctx,
3397                         krb5_cc_resolve(ctx->smb_krb5_context->krb5_context,
3398                                         krbtgt_cc_name,
3399                                         &ctx->krbtgt_ccache),
3400                         0, "krb5_cc_resolve failed");
3401
3402         torture_assert_int_equal(tctx,
3403                         krb5_cc_initialize(ctx->smb_krb5_context->krb5_context,
3404                                            ctx->krbtgt_ccache,
3405                                            ctx->my_creds.client),
3406                         0, "krb5_cc_initialize failed");
3407
3408         torture_assert_int_equal(tctx,
3409                         krb5_cc_store_cred(ctx->smb_krb5_context->krb5_context,
3410                                            ctx->krbtgt_ccache,
3411                                            &ctx->my_creds),
3412                         0, "krb5_cc_store_cred failed");
3413
3414         krbtgt_trust_realm_string = talloc_asprintf(ctx, "krbtgt/%s@%s",
3415                                                     trusted_realm_name, realm);
3416         torture_assert_int_equal(tctx,
3417                         smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3418                                                 &ctx->krbtgt_trust_realm,
3419                                                 realm, "krbtgt",
3420                                                 trusted_realm_name, NULL),
3421                         0, "smb_krb5_make_principal failed");
3422
3423         krbtgt_trust_dns_string = talloc_asprintf(ctx, "krbtgt/%s@%s",
3424                                                   trusted_dns_name, realm);
3425         torture_assert_int_equal(tctx,
3426                         smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3427                                                 &ctx->krbtgt_trust_dns,
3428                                                 realm, "krbtgt",
3429                                                 trusted_dns_name, NULL),
3430                         0, "smb_krb5_make_principal failed");
3431
3432         krbtgt_trust_netbios_string = talloc_asprintf(ctx, "krbtgt/%s@%s",
3433                                                       trusted_netbios_name, realm);
3434         torture_assert_int_equal(tctx,
3435                         smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3436                                                 &ctx->krbtgt_trust_netbios,
3437                                                 realm, "krbtgt",
3438                                                 trusted_netbios_name, NULL),
3439                         0, "smb_krb5_make_principal failed");
3440
3441         /* Confirm if we can do a TGS for krbtgt/trusted_realm */
3442         ZERO_STRUCT(ctx->counts);
3443         k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3444                                ctx->opt_nocanon,
3445                                ctx->krbtgt_ccache,
3446                                ctx->krbtgt_trust_realm,
3447                                &ctx->krbtgt_trust_realm_creds);
3448         assertion_message = talloc_asprintf(ctx,
3449                                 "krb5_get_creds(%s, canon) for failed: "
3450                                 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3451                                 krbtgt_trust_realm_string,
3452                                 k5ret,
3453                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3454                                                            k5ret, ctx),
3455                                 trusted->trust_direction,
3456                                 trusted->trust_type,
3457                                 trusted->trust_attributes,
3458                                 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3459         torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3460         torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3461         torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
3462
3463         k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3464                                       ctx->krbtgt_trust_realm_creds->server,
3465                                       ctx->krbtgt_trust_realm);
3466         torture_assert(tctx, k5ok, assertion_message);
3467         type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3468                                            ctx->krbtgt_trust_realm_creds->server);
3469         torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3470
3471         /* Confirm if we have no referral ticket in the cache */
3472         krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3473                                 &ctx->krbtgt_referral_creds);
3474         k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3475                                       ctx->krbtgt_ccache,
3476                                       0,
3477                                       ctx->krbtgt_trust_realm_creds,
3478                                       &ctx->krbtgt_referral_creds);
3479         assertion_message = talloc_asprintf(ctx,
3480                                 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3481                                 krbtgt_trust_realm_string,
3482                                 k5ret,
3483                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3484                                                            k5ret, ctx));
3485         torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
3486
3487         /* Confirm if we can do a TGS for krbtgt/trusted_dns with CANON */
3488         ZERO_STRUCT(ctx->counts);
3489         k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3490                                ctx->opt_canon,
3491                                ctx->krbtgt_ccache,
3492                                ctx->krbtgt_trust_dns,
3493                                &ctx->krbtgt_trust_dns_creds);
3494         assertion_message = talloc_asprintf(ctx,
3495                                 "krb5_get_creds(%s, canon) for failed: "
3496                                 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3497                                 krbtgt_trust_dns_string,
3498                                 k5ret,
3499                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3500                                                            k5ret, ctx),
3501                                 trusted->trust_direction,
3502                                 trusted->trust_type,
3503                                 trusted->trust_attributes,
3504                                 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3505         torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3506         torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3507         torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
3508
3509         /* Confirm if we have the referral ticket in the cache */
3510         krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3511                                 &ctx->krbtgt_referral_creds);
3512         k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3513                                       ctx->krbtgt_ccache,
3514                                       0,
3515                                       ctx->krbtgt_trust_realm_creds,
3516                                       &ctx->krbtgt_referral_creds);
3517         assertion_message = talloc_asprintf(ctx,
3518                                 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3519                                 krbtgt_trust_realm_string,
3520                                 k5ret,
3521                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3522                                                            k5ret, ctx));
3523         torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3524
3525         k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3526                                       ctx->krbtgt_referral_creds.server,
3527                                       ctx->krbtgt_trust_realm);
3528         torture_assert(tctx, k5ok, assertion_message);
3529         type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3530                                            ctx->krbtgt_referral_creds.server);
3531         torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3532         k5ret = decode_Ticket(ctx->krbtgt_referral_creds.ticket.data,
3533                               ctx->krbtgt_referral_creds.ticket.length,
3534                               &ctx->krbtgt_referral_ticket, NULL);
3535         torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3536         if (kvno > 0) {
3537                 expected_kvno = kvno - 1;
3538         }
3539         if (ctx->krbtgt_referral_ticket.enc_part.kvno != NULL) {
3540                 t_kvno = *ctx->krbtgt_referral_ticket.enc_part.kvno;
3541                 assertion_message = talloc_asprintf(ctx,
3542                                 "krbtgt_referral_ticket(%s) kvno(%u) expected(%u) current(%u)",
3543                                 krbtgt_trust_realm_string,
3544                                 (unsigned)t_kvno, (unsigned)expected_kvno,(unsigned)kvno);
3545                 torture_comment(tctx, "%s\n", assertion_message);
3546                 torture_assert_int_not_equal(tctx, t_kvno, 0, assertion_message);
3547         } else {
3548                 assertion_message = talloc_asprintf(ctx,
3549                                 "krbtgt_referral_ticket(%s) kvno(NULL) exptected(%u) current(%u)",
3550                                 krbtgt_trust_realm_string,
3551                                 (unsigned)expected_kvno,(unsigned)kvno);
3552                 torture_comment(tctx, "%s\n", assertion_message);
3553         }
3554         torture_assert_int_equal(tctx, t_kvno, expected_kvno, assertion_message);
3555
3556         if (old_nthash != NULL && expected_kvno != kvno) {
3557                 torture_comment(tctx, "old_nthash: %s\n", assertion_message);
3558                 k5ret = smb_krb5_keyblock_init_contents(ctx->smb_krb5_context->krb5_context,
3559                                                         ENCTYPE_ARCFOUR_HMAC,
3560                                                         old_nthash->hash,
3561                                                         sizeof(old_nthash->hash),
3562                                                         &ctx->krbtgt_referral_keyblock);
3563                 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3564         } else {
3565                 torture_comment(tctx, "nthash: %s\n", assertion_message);
3566                 k5ret = smb_krb5_keyblock_init_contents(ctx->smb_krb5_context->krb5_context,
3567                                                         ENCTYPE_ARCFOUR_HMAC,
3568                                                         nthash->hash,
3569                                                         sizeof(nthash->hash),
3570                                                         &ctx->krbtgt_referral_keyblock);
3571                 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3572         }
3573         k5ret = krb5_decrypt_ticket(ctx->smb_krb5_context->krb5_context,
3574                                     &ctx->krbtgt_referral_ticket,
3575                                     &ctx->krbtgt_referral_keyblock,
3576                                     &ctx->krbtgt_referral_enc_part,
3577                                     0);
3578         torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3579
3580         /* Delete the referral ticket from the cache */
3581         k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
3582                                     ctx->krbtgt_ccache,
3583                                     0,
3584                                     &ctx->krbtgt_referral_creds);
3585         assertion_message = talloc_asprintf(ctx,
3586                                 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
3587                                 krbtgt_trust_realm_string,
3588                                 k5ret,
3589                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3590                                                            k5ret, ctx));
3591         torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3592
3593         /* Confirm if we can do a TGS for krbtgt/trusted_dns no CANON */
3594         ZERO_STRUCT(ctx->counts);
3595         k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3596                                ctx->opt_nocanon,
3597                                ctx->krbtgt_ccache,
3598                                ctx->krbtgt_trust_dns,
3599                                &ctx->krbtgt_trust_dns_creds);
3600         assertion_message = talloc_asprintf(ctx,
3601                                 "krb5_get_creds(%s, nocanon) for failed: "
3602                                 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3603                                 krbtgt_trust_dns_string,
3604                                 k5ret,
3605                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3606                                                            k5ret, ctx),
3607                                 trusted->trust_direction,
3608                                 trusted->trust_type,
3609                                 trusted->trust_attributes,
3610                                 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3611         torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3612         torture_assert_int_equal(tctx, ctx->counts.io, 2, assertion_message);
3613         torture_assert_int_equal(tctx, ctx->counts.ok, 2, assertion_message);
3614
3615         k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3616                                       ctx->krbtgt_trust_dns_creds->server,
3617                                       ctx->krbtgt_trust_realm);
3618         torture_assert(tctx, k5ok, assertion_message);
3619         type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3620                                            ctx->krbtgt_trust_dns_creds->server);
3621         torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3622
3623         /* Confirm if we have the referral ticket in the cache */
3624         krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3625                                 &ctx->krbtgt_referral_creds);
3626         k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3627                                       ctx->krbtgt_ccache,
3628                                       0,
3629                                       ctx->krbtgt_trust_realm_creds,
3630                                       &ctx->krbtgt_referral_creds);
3631         assertion_message = talloc_asprintf(ctx,
3632                                 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3633                                 krbtgt_trust_realm_string,
3634                                 k5ret,
3635                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3636                                                            k5ret, ctx));
3637         torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3638
3639         k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3640                                       ctx->krbtgt_referral_creds.server,
3641                                       ctx->krbtgt_trust_realm);
3642         torture_assert(tctx, k5ok, assertion_message);
3643         type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3644                                            ctx->krbtgt_referral_creds.server);
3645         torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3646
3647         /* Delete the referral ticket from the cache */
3648         k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
3649                                     ctx->krbtgt_ccache,
3650                                     0,
3651                                     &ctx->krbtgt_referral_creds);
3652         assertion_message = talloc_asprintf(ctx,
3653                                 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
3654                                 krbtgt_trust_realm_string,
3655                                 k5ret,
3656                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3657                                                            k5ret, ctx));
3658         torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3659
3660         /* Confirm if we can do a TGS for krbtgt/NETBIOS with CANON */
3661         ZERO_STRUCT(ctx->counts);
3662         k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3663                                ctx->opt_canon,
3664                                ctx->krbtgt_ccache,
3665                                ctx->krbtgt_trust_netbios,
3666                                &ctx->krbtgt_trust_netbios_creds);
3667         assertion_message = talloc_asprintf(ctx,
3668                                 "krb5_get_creds(%s, canon) for failed: "
3669                                 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3670                                 krbtgt_trust_netbios_string,
3671                                 k5ret,
3672                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3673                                                            k5ret, ctx),
3674                                 trusted->trust_direction,
3675                                 trusted->trust_type,
3676                                 trusted->trust_attributes,
3677                                 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3678         torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3679         torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3680         torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
3681
3682         /* Confirm if we have the referral ticket in the cache */
3683         krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3684                                 &ctx->krbtgt_referral_creds);
3685         k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3686                                       ctx->krbtgt_ccache,
3687                                       0,
3688                                       ctx->krbtgt_trust_realm_creds,
3689                                       &ctx->krbtgt_referral_creds);
3690         assertion_message = talloc_asprintf(ctx,
3691                                 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3692                                 krbtgt_trust_netbios_string,
3693                                 k5ret,
3694                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3695                                                            k5ret, ctx));
3696         torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3697
3698         k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3699                                       ctx->krbtgt_referral_creds.server,
3700                                       ctx->krbtgt_trust_realm);
3701         torture_assert(tctx, k5ok, assertion_message);
3702         type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3703                                            ctx->krbtgt_referral_creds.server);
3704         torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3705
3706         /* Delete the referral ticket from the cache */
3707         k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
3708                                     ctx->krbtgt_ccache,
3709                                     0,
3710                                     &ctx->krbtgt_referral_creds);
3711         assertion_message = talloc_asprintf(ctx,
3712                                 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
3713                                 krbtgt_trust_realm_string,
3714                                 k5ret,
3715                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3716                                                            k5ret, ctx));
3717         torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3718
3719         /* Confirm if we can do a TGS for krbtgt/NETBIOS no CANON */
3720         ZERO_STRUCT(ctx->counts);
3721         k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3722                                ctx->opt_nocanon,
3723                                ctx->krbtgt_ccache,
3724                                ctx->krbtgt_trust_netbios,
3725                                &ctx->krbtgt_trust_netbios_creds);
3726         assertion_message = talloc_asprintf(ctx,
3727                                 "krb5_get_creds(%s, nocanon) for failed: "
3728                                 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3729                                 krbtgt_trust_netbios_string,
3730                                 k5ret,
3731                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3732                                                            k5ret, ctx),
3733                                 trusted->trust_direction,
3734                                 trusted->trust_type,
3735                                 trusted->trust_attributes,
3736                                 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3737         torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3738         torture_assert_int_equal(tctx, ctx->counts.io, 2, assertion_message);
3739         torture_assert_int_equal(tctx, ctx->counts.ok, 2, assertion_message);
3740
3741         k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3742                                       ctx->krbtgt_trust_netbios_creds->server,
3743                                       ctx->krbtgt_trust_realm);
3744         torture_assert(tctx, k5ok, assertion_message);
3745         type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3746                                            ctx->krbtgt_trust_netbios_creds->server);
3747         torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3748
3749         /* Confirm if we have the referral ticket in the cache */
3750         krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3751                                 &ctx->krbtgt_referral_creds);
3752         k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3753                                       ctx->krbtgt_ccache,
3754                                       0,
3755                                       ctx->krbtgt_trust_realm_creds,
3756                                       &ctx->krbtgt_referral_creds);
3757         assertion_message = talloc_asprintf(ctx,
3758                                 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3759                                 krbtgt_trust_realm_string,
3760                                 k5ret,
3761                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3762                                                            k5ret, ctx));
3763         torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3764
3765         k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3766                                       ctx->krbtgt_referral_creds.server,
3767                                       ctx->krbtgt_trust_realm);
3768         torture_assert(tctx, k5ok, assertion_message);
3769         type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3770                                            ctx->krbtgt_referral_creds.server);
3771         torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3772
3773         /* Delete the referral ticket from the cache */
3774         k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
3775                                     ctx->krbtgt_ccache,
3776                                     0,
3777                                     &ctx->krbtgt_referral_creds);
3778         assertion_message = talloc_asprintf(ctx,
3779                                 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
3780                                 krbtgt_trust_realm_string,
3781                                 k5ret,
3782                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3783                                                            k5ret, ctx));
3784         torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3785
3786         cifs_trust_dns_string = talloc_asprintf(ctx, "cifs/%s@%s",
3787                                                 trusted_dns_name, realm);
3788         torture_assert_int_equal(tctx,
3789                         smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3790                                                 &ctx->cifs_trust_dns,
3791                                                 realm, "cifs",
3792                                                 trusted_dns_name, NULL),
3793                         0, "smb_krb5_make_principal failed");
3794
3795         /* Confirm if we get krbtgt/trusted_realm back when asking for cifs/trusted_realm */
3796         ZERO_STRUCT(ctx->counts);
3797         k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3798                                ctx->opt_canon,
3799                                ctx->krbtgt_ccache,
3800                                ctx->cifs_trust_dns,
3801                                &ctx->cifs_trust_dns_creds);
3802         assertion_message = talloc_asprintf(ctx,
3803                                 "krb5_get_creds(%s) for failed: (%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3804                                 cifs_trust_dns_string,
3805                                 k5ret,
3806                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3807                                                            k5ret, ctx),
3808                                 trusted->trust_direction,
3809                                 trusted->trust_type,
3810                                 trusted->trust_attributes,
3811                                 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3812         torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3813         torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3814         torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
3815
3816         /* Confirm if we have the referral ticket in the cache */
3817         krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3818                                 &ctx->krbtgt_referral_creds);
3819         k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3820                                       ctx->krbtgt_ccache,
3821                                       0,
3822                                       ctx->krbtgt_trust_realm_creds,
3823                                       &ctx->krbtgt_referral_creds);
3824         assertion_message = talloc_asprintf(ctx,
3825                                 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3826                                 krbtgt_trust_realm_string,
3827                                 k5ret,
3828                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3829                                                            k5ret, ctx));
3830         torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3831
3832         k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3833                                       ctx->krbtgt_referral_creds.server,
3834                                       ctx->krbtgt_trust_realm);
3835         torture_assert(tctx, k5ok, assertion_message);
3836         type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3837                                            ctx->krbtgt_referral_creds.server);
3838         torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3839
3840         /* Delete the referral ticket from the cache */
3841         k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
3842                                     ctx->krbtgt_ccache,
3843                                     0,
3844                                     &ctx->krbtgt_referral_creds);
3845         assertion_message = talloc_asprintf(ctx,
3846                                 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
3847                                 krbtgt_trust_realm_string,
3848                                 k5ret,
3849                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3850                                                            k5ret, ctx));
3851         torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3852
3853         cifs_trust_netbios_string = talloc_asprintf(ctx, "cifs/%s@%s",
3854                                                 trusted_netbios_name, realm);
3855         torture_assert_int_equal(tctx,
3856                         smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3857                                                 &ctx->cifs_trust_netbios,
3858                                                 realm, "cifs",
3859                                                 trusted_netbios_name, NULL),
3860                         0, "smb_krb5_make_principal failed");
3861
3862         /* Confirm if we get krbtgt/trusted_realm back when asking for cifs/trusted_realm */
3863         ZERO_STRUCT(ctx->counts);
3864         k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3865                                ctx->opt_canon,
3866                                ctx->krbtgt_ccache,
3867                                ctx->cifs_trust_netbios,
3868                                &ctx->cifs_trust_netbios_creds);
3869         assertion_message = talloc_asprintf(ctx,
3870                                 "krb5_get_creds(%s) for failed: (%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3871                                 cifs_trust_netbios_string,
3872                                 k5ret,
3873                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3874                                                            k5ret, ctx),
3875                                 trusted->trust_direction,
3876                                 trusted->trust_type,
3877                                 trusted->trust_attributes,
3878                                 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3879         torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3880         torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3881         torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
3882
3883         /* Confirm if we have the referral ticket in the cache */
3884         krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3885                                 &ctx->krbtgt_referral_creds);
3886         k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3887                                       ctx->krbtgt_ccache,
3888                                       0,
3889                                       ctx->krbtgt_trust_realm_creds,
3890                                       &ctx->krbtgt_referral_creds);
3891         assertion_message = talloc_asprintf(ctx,
3892                                 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3893                                 krbtgt_trust_realm_string,
3894                                 k5ret,
3895                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3896                                                            k5ret, ctx));
3897         torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3898
3899         k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3900                                       ctx->krbtgt_referral_creds.server,
3901                                       ctx->krbtgt_trust_realm);
3902         torture_assert(tctx, k5ok, assertion_message);
3903         type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3904                                            ctx->krbtgt_referral_creds.server);
3905         torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3906
3907         /* Delete the referral ticket from the cache */
3908         k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
3909                                     ctx->krbtgt_ccache,
3910                                     0,
3911                                     &ctx->krbtgt_referral_creds);
3912         assertion_message = talloc_asprintf(ctx,
3913                                 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
3914                                 krbtgt_trust_realm_string,
3915                                 k5ret,
3916                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3917                                                            k5ret, ctx));
3918         torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3919
3920         drs_trust_dns_string = talloc_asprintf(ctx,
3921                         "E3514235-4B06-11D1-AB04-00C04FC2DCD2/%s/%s@%s",
3922                         workstation, trusted_dns_name, realm);
3923         torture_assert_int_equal(tctx,
3924                         smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3925                                                 &ctx->drs_trust_dns,
3926                                                 realm, "E3514235-4B06-11D1-AB04-00C04FC2DCD2",
3927                                                 workstation, trusted_dns_name, NULL),
3928                         0, "smb_krb5_make_principal failed");
3929
3930         /* Confirm if we get krbtgt/trusted_realm back when asking for a 3 part principal */
3931         ZERO_STRUCT(ctx->counts);
3932         k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3933                                ctx->opt_canon,
3934                                ctx->krbtgt_ccache,
3935                                ctx->drs_trust_dns,
3936                                &ctx->drs_trust_dns_creds);
3937         assertion_message = talloc_asprintf(ctx,
3938                                 "krb5_get_creds(%s) for failed: (%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3939                                 drs_trust_dns_string,
3940                                 k5ret,
3941                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3942                                                            k5ret, ctx),
3943                                 trusted->trust_direction,
3944                                 trusted->trust_type,
3945                                 trusted->trust_attributes,
3946                                 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3947         torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3948         torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3949         torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
3950
3951         /* Confirm if we have the referral ticket in the cache */
3952         krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3953                                 &ctx->krbtgt_referral_creds);
3954         k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3955                                       ctx->krbtgt_ccache,
3956                                       0,
3957                                       ctx->krbtgt_trust_realm_creds,
3958                                       &ctx->krbtgt_referral_creds);
3959         assertion_message = talloc_asprintf(ctx,
3960                                 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3961                                 krbtgt_trust_realm_string,
3962                                 k5ret,
3963                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3964                                                            k5ret, ctx));
3965         torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3966
3967         k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3968                                       ctx->krbtgt_referral_creds.server,
3969                                       ctx->krbtgt_trust_realm);
3970         torture_assert(tctx, k5ok, assertion_message);
3971         type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3972                                            ctx->krbtgt_referral_creds.server);
3973         torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3974
3975         /* Delete the referral ticket from the cache */
3976         k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
3977                                     ctx->krbtgt_ccache,
3978                                     0,
3979                                     &ctx->krbtgt_referral_creds);
3980         assertion_message = talloc_asprintf(ctx,
3981                                 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
3982                                 krbtgt_trust_realm_string,
3983                                 k5ret,
3984                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3985                                                            k5ret, ctx));
3986         torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3987
3988         drs_trust_netbios_string = talloc_asprintf(ctx,
3989                         "E3514235-4B06-11D1-AB04-00C04FC2DCD2/%s/%s@%s",
3990                         workstation, trusted_netbios_name, realm);
3991         torture_assert_int_equal(tctx,
3992                         smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3993                                                 &ctx->drs_trust_netbios,
3994                                                 realm, "E3514235-4B06-11D1-AB04-00C04FC2DCD2",
3995                                                 workstation, trusted_netbios_name, NULL),
3996                         0, "smb_krb5_make_principal failed");
3997
3998         /* Confirm if we get krbtgt/trusted_realm back when asking for a 3 part principal */
3999         ZERO_STRUCT(ctx->counts);
4000         k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
4001                                ctx->opt_canon,
4002                                ctx->krbtgt_ccache,
4003                                ctx->drs_trust_netbios,
4004                                &ctx->drs_trust_netbios_creds);
4005         assertion_message = talloc_asprintf(ctx,
4006                                 "krb5_get_creds(%s) for failed: (%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
4007                                 drs_trust_netbios_string,
4008                                 k5ret,
4009                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4010                                                            k5ret, ctx),
4011                                 trusted->trust_direction,
4012                                 trusted->trust_type,
4013                                 trusted->trust_attributes,
4014                                 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
4015         torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
4016         torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
4017         torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
4018
4019         /* Confirm if we have the referral ticket in the cache */
4020         krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
4021                                 &ctx->krbtgt_referral_creds);
4022         k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
4023                                       ctx->krbtgt_ccache,
4024                                       0,
4025                                       ctx->krbtgt_trust_realm_creds,
4026                                       &ctx->krbtgt_referral_creds);
4027         assertion_message = talloc_asprintf(ctx,
4028                                 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
4029                                 krbtgt_trust_realm_string,
4030                                 k5ret,
4031                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4032                                                            k5ret, ctx));
4033         torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
4034
4035         k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
4036                                       ctx->krbtgt_referral_creds.server,
4037                                       ctx->krbtgt_trust_realm);
4038         torture_assert(tctx, k5ok, assertion_message);
4039         type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
4040                                            ctx->krbtgt_referral_creds.server);
4041         torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
4042
4043         /* Delete the referral ticket from the cache */
4044         k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
4045                                     ctx->krbtgt_ccache,
4046                                     0,
4047                                     &ctx->krbtgt_referral_creds);
4048         assertion_message = talloc_asprintf(ctx,
4049                                 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
4050                                 krbtgt_trust_realm_string,
4051                                 k5ret,
4052                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4053                                                            k5ret, ctx));
4054         torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
4055
4056         four_trust_dns_string = talloc_asprintf(ctx, "four/tree/two/%s@%s",
4057                                                 trusted_dns_name, realm);
4058         torture_assert_int_equal(tctx,
4059                         smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
4060                                                 &ctx->four_trust_dns,
4061                                                 realm, "four", "tree", "two",
4062                                                 trusted_dns_name, NULL),
4063                         0, "smb_krb5_make_principal failed");
4064
4065         /* Confirm if we get an error back for a 4 part principal */
4066         ZERO_STRUCT(ctx->counts);
4067         k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
4068                                ctx->opt_canon,
4069                                ctx->krbtgt_ccache,
4070                                ctx->four_trust_dns,
4071                                &ctx->four_trust_dns_creds);
4072         assertion_message = talloc_asprintf(ctx,
4073                                 "krb5_get_creds(%s) for failed: (%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
4074                                 four_trust_dns_string,
4075                                 k5ret,
4076                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4077                                                            k5ret, ctx),
4078                                 trusted->trust_direction,
4079                                 trusted->trust_type,
4080                                 trusted->trust_attributes,
4081                                 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
4082         torture_assert_int_equal(tctx, k5ret, KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN, assertion_message);
4083         torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
4084         torture_assert_int_equal(tctx, ctx->counts.error_io, 1, assertion_message);
4085         torture_assert_int_equal(tctx, KRB5_ERROR_CODE(&ctx->error), 7, assertion_message);
4086
4087         /* Confirm if we have no referral ticket in the cache */
4088         krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
4089                                 &ctx->krbtgt_referral_creds);
4090         k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
4091                                       ctx->krbtgt_ccache,
4092                                       0,
4093                                       ctx->krbtgt_trust_realm_creds,
4094                                       &ctx->krbtgt_referral_creds);
4095         assertion_message = talloc_asprintf(ctx,
4096                                 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
4097                                 krbtgt_trust_realm_string,
4098                                 k5ret,
4099                                 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4100                                                            k5ret, ctx));
4101         torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
4102
4103         TALLOC_FREE(ctx);
4104         return true;
4105 }
4106
4107 static bool check_dom_trust_pw(struct dcerpc_pipe *p,
4108                                struct torture_context *tctx,
4109                                const char *our_netbios_name,
4110                                const char *our_dns_name,
4111                                enum netr_SchannelType secure_channel_type,
4112                                const struct lsa_TrustDomainInfoInfoEx *trusted,
4113                                const char *previous_password,
4114                                const char *current_password,
4115                                uint32_t current_version,
4116                                const char *next_password,
4117                                uint32_t next_version,
4118                                bool expected_result)
4119 {
4120         struct cli_credentials *incoming_creds;
4121         char *server_name = NULL;
4122         char *account = NULL;
4123         char *principal = NULL;
4124         char *workstation = NULL;
4125         const char *binding = torture_setting_string(tctx, "binding", NULL);
4126         const char *host = torture_setting_string(tctx, "host", NULL);
4127         struct dcerpc_binding *b2;
4128         struct netlogon_creds_CredentialState *creds;
4129         struct samr_CryptPassword samr_crypt_password;
4130         struct netr_CryptPassword netr_crypt_password;
4131         struct netr_Authenticator req_auth;
4132         struct netr_Authenticator rep_auth;
4133         struct netr_ServerPasswordSet2 s;
4134         struct dcerpc_pipe *p2;
4135         NTSTATUS status;
4136         bool ok;
4137         int rc;
4138         const char *trusted_netbios_name = trusted->netbios_name.string;
4139         const char *trusted_dns_name = trusted->domain_name.string;
4140         struct tsocket_address *dest_addr;
4141         struct cldap_socket *cldap;
4142         struct cldap_netlogon cldap1;
4143
4144         incoming_creds = cli_credentials_init(tctx);
4145         torture_assert(tctx, incoming_creds, "cli_credentials_init");
4146
4147         cli_credentials_set_domain(incoming_creds, our_netbios_name, CRED_SPECIFIED);
4148         cli_credentials_set_realm(incoming_creds, our_dns_name, CRED_SPECIFIED);
4149
4150         if (secure_channel_type == SEC_CHAN_DNS_DOMAIN) {
4151                 account = talloc_asprintf(tctx, "%s.", trusted_dns_name);
4152                 torture_assert(tctx, account, __location__);
4153
4154                 principal = talloc_asprintf(tctx, "%s$@%s",
4155                                             trusted_netbios_name,
4156                                             cli_credentials_get_realm(incoming_creds));
4157                 torture_assert(tctx, principal, __location__);
4158
4159                 workstation = talloc_asprintf(tctx, "%sUP",
4160                                               trusted_netbios_name);
4161                 torture_assert(tctx, workstation, __location__);
4162         } else {
4163                 account = talloc_asprintf(tctx, "%s$", trusted_netbios_name);
4164                 torture_assert(tctx, account, __location__);
4165
4166                 workstation = talloc_asprintf(tctx, "%sDOWN",
4167                                               trusted_netbios_name);
4168                 torture_assert(tctx, workstation, __location__);
4169         }
4170
4171         cli_credentials_set_username(incoming_creds, account, CRED_SPECIFIED);
4172         if (principal != NULL) {
4173                 cli_credentials_set_principal(incoming_creds, principal,
4174                                               CRED_SPECIFIED);
4175         }
4176         cli_credentials_set_kvno(incoming_creds, current_version);
4177         cli_credentials_set_password(incoming_creds, current_password, CRED_SPECIFIED);
4178         cli_credentials_set_old_password(incoming_creds, previous_password, CRED_SPECIFIED);
4179         cli_credentials_set_workstation(incoming_creds, workstation, CRED_SPECIFIED);
4180         cli_credentials_set_secure_channel_type(incoming_creds, secure_channel_type);
4181
4182         rc = tsocket_address_inet_from_strings(tctx, "ip",
4183                                                host,
4184                                                lpcfg_cldap_port(tctx->lp_ctx),
4185                                                &dest_addr);
4186         torture_assert_int_equal(tctx, rc, 0, "tsocket_address_inet_from_strings");
4187
4188         /* cldap_socket_init should now know about the dest. address */
4189         status = cldap_socket_init(tctx, NULL, dest_addr, &cldap);
4190         torture_assert_ntstatus_ok(tctx, status, "cldap_socket_init");
4191
4192         ZERO_STRUCT(cldap1);
4193         cldap1.in.dest_address = NULL;
4194         cldap1.in.dest_port = 0;
4195         cldap1.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX;
4196         cldap1.in.user = account;
4197         if (secure_channel_type == SEC_CHAN_DNS_DOMAIN) {
4198                 cldap1.in.acct_control = ACB_AUTOLOCK;
4199         } else {
4200                 cldap1.in.acct_control = ACB_DOMTRUST;
4201         }
4202         status = cldap_netlogon(cldap, tctx, &cldap1);
4203         torture_assert_ntstatus_ok(tctx, status, "cldap_netlogon");
4204         torture_assert_int_equal(tctx, cldap1.out.netlogon.ntver,
4205                                  NETLOGON_NT_VERSION_5EX,
4206                                  "ntver");
4207         torture_assert_int_equal(tctx, cldap1.out.netlogon.data.nt5_ex.nt_version,
4208                                  NETLOGON_NT_VERSION_1 | NETLOGON_NT_VERSION_5EX,
4209                                  "nt_version");
4210         torture_assert_int_equal(tctx, cldap1.out.netlogon.data.nt5_ex.command,
4211                                  LOGON_SAM_LOGON_RESPONSE_EX,
4212                                  "command");
4213         torture_assert_str_equal(tctx, cldap1.out.netlogon.data.nt5_ex.user_name,
4214                                  cldap1.in.user,
4215                                  "user_name");
4216         server_name = talloc_asprintf(tctx, "\\\\%s",
4217                         cldap1.out.netlogon.data.nt5_ex.pdc_dns_name);
4218         torture_assert(tctx, server_name, __location__);
4219
4220         status = dcerpc_parse_binding(tctx, binding, &b2);
4221         torture_assert_ntstatus_ok(tctx, status, "Bad binding string");
4222
4223         status = dcerpc_pipe_connect_b(tctx, &p2, b2,
4224                                        &ndr_table_netlogon,
4225                                        cli_credentials_init_anon(tctx),
4226                                        tctx->ev, tctx->lp_ctx);
4227         torture_assert_ntstatus_ok(tctx, status, "dcerpc_pipe_connect_b");
4228
4229         ok = check_pw_with_ServerAuthenticate3(p2, tctx,
4230                                                NETLOGON_NEG_AUTH2_ADS_FLAGS,
4231                                                server_name,
4232                                                incoming_creds, &creds);
4233         torture_assert_int_equal(tctx, ok, expected_result,
4234                                  "check_pw_with_ServerAuthenticate3");
4235
4236         if (trusted->trust_type != LSA_TRUST_TYPE_DOWNLEVEL) {
4237                 ok = check_pw_with_krb5(tctx, incoming_creds, trusted);
4238                 torture_assert_int_equal(tctx, ok, expected_result,
4239                                          "check_pw_with_krb5");
4240         }
4241
4242         if (expected_result != true || next_password == NULL) {
4243                 TALLOC_FREE(p2);
4244                 return true;
4245         }
4246
4247         /*
4248          * netr_ServerPasswordSet2
4249          */
4250         ok = encode_pw_buffer(samr_crypt_password.data,
4251                               next_password, STR_UNICODE);
4252         torture_assert(tctx, ok, "encode_pw_buffer");
4253
4254         if (next_version != 0) {
4255                 struct NL_PASSWORD_VERSION version;
4256                 uint32_t len = IVAL(samr_crypt_password.data, 512);
4257                 uint32_t ofs = 512 - len;
4258                 uint8_t *ptr;
4259
4260                 ofs -= 12;
4261
4262                 version.ReservedField = 0;
4263                 version.PasswordVersionNumber = next_version;
4264                 version.PasswordVersionPresent =
4265                         NETLOGON_PASSWORD_VERSION_NUMBER_PRESENT;
4266
4267                 ptr = samr_crypt_password.data + ofs;
4268                 SIVAL(ptr, 0, version.ReservedField);
4269                 SIVAL(ptr, 4, version.PasswordVersionNumber);
4270                 SIVAL(ptr, 8, version.PasswordVersionPresent);
4271         }
4272
4273         netlogon_creds_client_authenticator(creds, &req_auth);
4274         ZERO_STRUCT(rep_auth);
4275
4276         if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
4277                 netlogon_creds_aes_encrypt(creds,
4278                                            samr_crypt_password.data,
4279                                            516);
4280         } else {
4281                 netlogon_creds_arcfour_crypt(creds,
4282                                              samr_crypt_password.data,
4283                                              516);
4284         }
4285
4286         memcpy(netr_crypt_password.data,
4287                samr_crypt_password.data, 512);
4288         netr_crypt_password.length = IVAL(samr_crypt_password.data, 512);
4289
4290
4291         s.in.server_name = server_name;
4292         s.in.account_name = cli_credentials_get_username(incoming_creds);
4293         s.in.secure_channel_type = cli_credentials_get_secure_channel_type(incoming_creds);
4294         s.in.computer_name = cli_credentials_get_workstation(incoming_creds);
4295         s.in.credential = &req_auth;
4296         s.in.new_password = &netr_crypt_password;
4297         s.out.return_authenticator = &rep_auth;
4298         status = dcerpc_netr_ServerPasswordSet2_r(p2->binding_handle, tctx, &s);
4299         torture_assert_ntstatus_ok(tctx, status, "failed to set password");
4300
4301         ok = netlogon_creds_client_check(creds, &rep_auth.cred);
4302         torture_assert(tctx, ok, "netlogon_creds_client_check");
4303
4304         cli_credentials_set_kvno(incoming_creds, next_version);
4305         cli_credentials_set_password(incoming_creds, next_password, CRED_SPECIFIED);
4306         cli_credentials_set_old_password(incoming_creds, current_password, CRED_SPECIFIED);
4307
4308         TALLOC_FREE(p2);
4309         status = dcerpc_pipe_connect_b(tctx, &p2, b2,
4310                                        &ndr_table_netlogon,
4311                                        cli_credentials_init_anon(tctx),
4312                                        tctx->ev, tctx->lp_ctx);
4313         torture_assert_ntstatus_ok(tctx, status, "dcerpc_pipe_connect_b");
4314
4315         ok = check_pw_with_ServerAuthenticate3(p2, tctx,
4316                                                NETLOGON_NEG_AUTH2_ADS_FLAGS,
4317                                                server_name,
4318                                                incoming_creds, &creds);
4319         torture_assert(tctx, ok, "check_pw_with_ServerAuthenticate3 with changed password");
4320
4321         if (trusted->trust_type != LSA_TRUST_TYPE_DOWNLEVEL) {
4322                 ok = check_pw_with_krb5(tctx, incoming_creds, trusted);
4323                 torture_assert(tctx, ok, "check_pw_with_krb5 with changed password");
4324         }
4325
4326         TALLOC_FREE(p2);
4327         return true;
4328 }
4329
4330 static bool test_CreateTrustedDomainEx_common(struct dcerpc_pipe *p,
4331                                               struct torture_context *tctx,
4332                                               struct policy_handle *handle,
4333                                               uint32_t num_trusts,
4334                                               bool ex2_call)
4335 {
4336         NTSTATUS status;
4337         bool ret = true;
4338         struct lsa_QueryInfoPolicy2 p2;
4339         union lsa_PolicyInformation *our_info = NULL;
4340         struct lsa_CreateTrustedDomainEx r;
4341         struct lsa_CreateTrustedDomainEx2 r2;
4342         struct lsa_TrustDomainInfoInfoEx trustinfo;
4343         struct lsa_TrustDomainInfoAuthInfoInternal *authinfo_internal = NULL;
4344         struct lsa_TrustDomainInfoAuthInfo *authinfo = NULL;
4345         struct dom_sid **domsid;
4346         struct policy_handle *trustdom_handle;
4347         struct lsa_QueryTrustedDomainInfo q;
4348         union lsa_TrustedDomainInfo *info = NULL;
4349         DATA_BLOB session_key;
4350         int i;
4351         struct dcerpc_binding_handle *b = p->binding_handle;
4352         const char *id;
4353         const char *incoming_v00 = TRUSTPW "InV00";
4354         const char *incoming_v0 = TRUSTPW "InV0";
4355         const char *incoming_v1 = TRUSTPW "InV1";
4356         const char *incoming_v2 = TRUSTPW "InV2";
4357         const char *incoming_v40 = TRUSTPW "InV40";
4358         const char *outgoing_v00 = TRUSTPW "OutV00";
4359         const char *outgoing_v0 = TRUSTPW "OutV0";
4360
4361         if (ex2_call) {
4362                 torture_comment(tctx, "\nTesting CreateTrustedDomainEx2 for %d domains\n", num_trusts);
4363                 id = "3";
4364         } else {
4365                 torture_comment(tctx, "\nTesting CreateTrustedDomainEx for %d domains\n", num_trusts);
4366                 id = "2";
4367         }
4368
4369         domsid = talloc_array(tctx, struct dom_sid *, num_trusts);
4370         trustdom_handle = talloc_array(tctx, struct policy_handle, num_trusts);
4371
4372         status = dcerpc_fetch_session_key(p, &session_key);
4373         if (!NT_STATUS_IS_OK(status)) {
4374                 torture_comment(tctx, "dcerpc_fetch_session_key failed - %s\n", nt_errstr(status));
4375                 return false;
4376         }
4377
4378         ZERO_STRUCT(p2);
4379         p2.in.handle = handle;
4380         p2.in.level = LSA_POLICY_INFO_DNS;
4381         p2.out.info = &our_info;
4382
4383         torture_assert_ntstatus_ok(tctx,
4384                                 dcerpc_lsa_QueryInfoPolicy2_r(b, tctx, &p2),
4385                                 "lsa_QueryInfoPolicy2 failed");
4386         torture_assert_ntstatus_ok(tctx, p2.out.result,
4387                                 "lsa_QueryInfoPolicy2 failed");
4388         torture_assert(tctx, our_info != NULL, "lsa_QueryInfoPolicy2 our_info");
4389
4390         for (i=0; i< num_trusts; i++) {
4391                 char *trust_name = talloc_asprintf(tctx, "TORTURE%s%02d", id, i);
4392                 char *trust_name_dns = talloc_asprintf(tctx, "torturedom%s%02d.samba._none_.example.com", id, i);
4393                 char *trust_sid = talloc_asprintf(tctx, "S-1-5-21-97398-379795-%s%02d", id, i);
4394                 bool ok;
4395
4396                 domsid[i] = dom_sid_parse_talloc(tctx, trust_sid);
4397
4398                 trustinfo.sid = domsid[i];
4399                 trustinfo.netbios_name.string = trust_name;
4400                 trustinfo.domain_name.string = trust_name_dns;
4401
4402                 /* Create inbound, some outbound, and some
4403                  * bi-directional trusts in a repeating pattern based
4404                  * on i */
4405
4406                 /* 1 == inbound, 2 == outbound, 3 == both */
4407                 trustinfo.trust_direction = (i % 3) + 1;
4408
4409                 /* Try different trust types too */
4410
4411                 /* 1 == downlevel (NT4), 2 == uplevel (ADS), 3 == MIT (kerberos but not AD) */
4412                 trustinfo.trust_type = (((i / 3) + 1) % 3) + 1;
4413
4414                 trustinfo.trust_attributes = LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION;
4415
4416                 ok = gen_authinfo_internal(tctx, incoming_v00, incoming_v0,
4417                                   outgoing_v00, outgoing_v0,
4418                                   session_key, &authinfo_internal);
4419                 if (!ok) {
4420                         torture_comment(tctx, "gen_authinfo_internal failed");
4421                         ret = false;
4422                 }
4423
4424                 ok = gen_authinfo(tctx, incoming_v00, incoming_v0,
4425                                   outgoing_v00, outgoing_v0,
4426                                   &authinfo);
4427                 if (!ok) {
4428                         torture_comment(tctx, "gen_authinfonfo failed");
4429                         ret = false;
4430                 }
4431
4432                 if (ex2_call) {
4433
4434                         r2.in.policy_handle = handle;
4435                         r2.in.info = &trustinfo;
4436                         r2.in.auth_info_internal = authinfo_internal;
4437                         r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4438                         r2.out.trustdom_handle = &trustdom_handle[i];
4439
4440                         torture_assert_ntstatus_ok(tctx,
4441                                 dcerpc_lsa_CreateTrustedDomainEx2_r(b, tctx, &r2),
4442                                 "CreateTrustedDomainEx2 failed");
4443
4444                         status = r2.out.result;
4445                 } else {
4446
4447                         r.in.policy_handle = handle;
4448                         r.in.info = &trustinfo;
4449                         r.in.auth_info = authinfo;
4450                         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4451                         r.out.trustdom_handle = &trustdom_handle[i];
4452
4453                         torture_assert_ntstatus_ok(tctx,
4454                                 dcerpc_lsa_CreateTrustedDomainEx_r(b, tctx, &r),
4455                                 "CreateTrustedDomainEx failed");
4456
4457                         status = r.out.result;
4458                 }
4459
4460                 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
4461                         test_DeleteTrustedDomain(b, tctx, handle, trustinfo.netbios_name);
4462                         if (ex2_call) {
4463                                 torture_assert_ntstatus_ok(tctx,
4464                                         dcerpc_lsa_CreateTrustedDomainEx2_r(b, tctx, &r2),
4465                                         "CreateTrustedDomainEx2 failed");
4466                                 status = r2.out.result;
4467                         } else {
4468                                 torture_assert_ntstatus_ok(tctx,
4469                                         dcerpc_lsa_CreateTrustedDomainEx_r(b, tctx, &r),
4470                                         "CreateTrustedDomainEx2 failed");
4471                                 status = r.out.result;
4472                         }
4473                 }
4474                 if (!NT_STATUS_IS_OK(status)) {
4475                         torture_comment(tctx, "CreateTrustedDomainEx failed2 - %s\n", nt_errstr(status));
4476                         ret = false;
4477                 } else {
4478                         /* For outbound and MIT trusts there is no trust account */
4479                         if (trustinfo.trust_direction != 2 &&
4480                             trustinfo.trust_type != 3) {
4481
4482                                 if (torture_setting_bool(tctx, "samba3", false)) {
4483                                         torture_comment(tctx, "skipping trusted domain auth tests against samba3\n");
4484                                 } else if (ex2_call == false &&
4485                                            torture_setting_bool(tctx, "samba4", false)) {
4486                                         torture_comment(tctx, "skipping CreateTrustedDomainEx trusted domain auth tests against samba4\n");
4487
4488                                 } else {
4489                                         ok = check_dom_trust_pw(p, tctx,
4490                                                                 our_info->dns.name.string,
4491                                                                 our_info->dns.dns_domain.string,
4492                                                                 SEC_CHAN_DOMAIN,
4493                                                                 &trustinfo,
4494                                                                 NULL,
4495                                                                 "x" TRUSTPW "x", 0,
4496                                                                 NULL, 0,
4497                                                                 false);
4498                                         if (!ok) {
4499                                                 torture_comment(tctx, "Password check passed unexpectedly\n");
4500                                                 ret = false;
4501                                         }
4502                                         ok = check_dom_trust_pw(p, tctx,
4503                                                                 our_info->dns.name.string,
4504                                                                 our_info->dns.dns_domain.string,
4505                                                                 SEC_CHAN_DOMAIN,
4506                                                                 &trustinfo,
4507                                                                 incoming_v00,
4508                                                                 incoming_v0, 0,
4509                                                                 incoming_v1, 1,
4510                                                                 true);
4511                                         if (!ok) {
4512                                                 torture_comment(tctx, "Password check failed (SEC_CHAN_DOMAIN)\n");
4513                                                 ret = false;
4514                                         }
4515                                         ok = check_dom_trust_pw(p, tctx,
4516                                                                 our_info->dns.name.string,
4517                                                                 our_info->dns.dns_domain.string,
4518                                                                 SEC_CHAN_DNS_DOMAIN,
4519                                                                 &trustinfo,
4520                                                                 incoming_v0,
4521                                                                 incoming_v1, 1,
4522                                                                 incoming_v2, 2,
4523                                                                 true);
4524                                         if (!ok) {
4525                                                 torture_comment(tctx, "Password check failed v2 (SEC_CHAN_DNS_DOMAIN)\n");
4526                                                 ret = false;
4527                                         }
4528                                         ok = check_dom_trust_pw(p, tctx,
4529                                                                 our_info->dns.name.string,
4530                                                                 our_info->dns.dns_domain.string,
4531                                                                 SEC_CHAN_DNS_DOMAIN,
4532                                                                 &trustinfo,
4533                                                                 incoming_v1,
4534                                                                 incoming_v2, 2,
4535                                                                 incoming_v40, 40,
4536                                                                 true);
4537                                         if (!ok) {
4538                                                 torture_comment(tctx, "Password check failed v4 (SEC_CHAN_DNS_DOMAIN)\n");
4539                                                 ret = false;
4540                                         }
4541                                 }
4542                         }
4543
4544                         q.in.trustdom_handle = &trustdom_handle[i];
4545                         q.in.level = LSA_TRUSTED_DOMAIN_INFO_INFO_EX;
4546                         q.out.info = &info;
4547                         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfo_r(b, tctx, &q),
4548                                 "QueryTrustedDomainInfo failed");
4549                         if (!NT_STATUS_IS_OK(q.out.result)) {
4550                                 torture_comment(tctx, "QueryTrustedDomainInfo level 1 failed - %s\n", nt_errstr(q.out.result));
4551                                 ret = false;
4552                         } else if (!q.out.info) {
4553                                 torture_comment(tctx, "QueryTrustedDomainInfo level 1 failed to return an info pointer\n");
4554                                 ret = false;
4555                         } else {
4556                                 if (strcmp(info->info_ex.domain_name.string, trustinfo.domain_name.string) != 0) {
4557                                         torture_comment(tctx, "QueryTrustedDomainInfo returned inconsistent long name: %s != %s\n",
4558                                                info->info_ex.domain_name.string, trustinfo.domain_name.string);
4559                                         ret = false;
4560                                 }
4561                                 if (strcmp(info->info_ex.netbios_name.string, trustinfo.netbios_name.string) != 0) {
4562                                         torture_comment(tctx, "QueryTrustedDomainInfo returned inconsistent short name: %s != %s\n",
4563                                                info->info_ex.netbios_name.string, trustinfo.netbios_name.string);
4564                                         ret = false;
4565                                 }
4566                                 if (info->info_ex.trust_type != trustinfo.trust_type) {
4567                                         torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n",
4568                                                trust_name, info->info_ex.trust_type, trustinfo.trust_type);
4569                                         ret = false;
4570                                 }
4571                                 if (info->info_ex.trust_attributes != LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION) {
4572                                         torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n",
4573                                                trust_name, info->info_ex.trust_attributes, LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION);
4574                                         ret = false;
4575                                 }
4576                                 if (info->info_ex.trust_direction != trustinfo.trust_direction) {
4577                                         torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n",
4578                                                trust_name, info->info_ex.trust_direction, trustinfo.trust_direction);
4579                                         ret = false;
4580                                 }
4581                         }
4582                 }
4583         }
4584
4585         /* now that we have some domains to look over, we can test the enum calls */
4586         if (!test_EnumTrustDom(b, tctx, handle)) {
4587                 torture_comment(tctx, "test_EnumTrustDom failed\n");
4588                 ret = false;
4589         }
4590
4591         if (!test_EnumTrustDomEx(b, tctx, handle)) {
4592                 torture_comment(tctx, "test_EnumTrustDomEx failed\n");
4593                 ret = false;
4594         }
4595
4596         for (i=0; i<num_trusts; i++) {
4597                 if (!test_DeleteTrustedDomainBySid(b, tctx, handle, domsid[i])) {
4598                         torture_comment(tctx, "test_DeleteTrustedDomainBySid failed\n");
4599                         ret = false;
4600                 }
4601         }
4602
4603         return ret;
4604 }
4605
4606 static bool test_CreateTrustedDomainEx2(struct dcerpc_pipe *p,
4607                                         struct torture_context *tctx,
4608                                         struct policy_handle *handle,
4609                                         uint32_t num_trusts)
4610 {
4611         return test_CreateTrustedDomainEx_common(p, tctx, handle, num_trusts, true);
4612 }
4613
4614 static bool test_CreateTrustedDomainEx(struct dcerpc_pipe *p,
4615                                        struct torture_context *tctx,
4616                                        struct policy_handle *handle,
4617                                        uint32_t num_trusts)
4618 {
4619         return test_CreateTrustedDomainEx_common(p, tctx, handle, num_trusts, false);
4620 }
4621
4622 static bool test_QueryDomainInfoPolicy(struct dcerpc_binding_handle *b,
4623                                  struct torture_context *tctx,
4624                                  struct policy_handle *handle)
4625 {
4626         struct lsa_QueryDomainInformationPolicy r;
4627         union lsa_DomainInformationPolicy *info = NULL;
4628         int i;
4629         bool ret = true;
4630
4631         if (torture_setting_bool(tctx, "samba3", false)) {
4632                 torture_skip(tctx, "skipping QueryDomainInformationPolicy test\n");
4633         }
4634
4635         torture_comment(tctx, "\nTesting QueryDomainInformationPolicy\n");
4636
4637         for (i=2;i<4;i++) {
4638                 r.in.handle = handle;
4639                 r.in.level = i;
4640                 r.out.info = &info;
4641
4642                 torture_comment(tctx, "\nTrying QueryDomainInformationPolicy level %d\n", i);
4643
4644                 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryDomainInformationPolicy_r(b, tctx, &r),
4645                         "QueryDomainInformationPolicy failed");
4646
4647                 /* If the server does not support EFS, then this is the correct return */
4648                 if (i == LSA_DOMAIN_INFO_POLICY_EFS && NT_STATUS_EQUAL(r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4649                         continue;
4650                 } else if (!NT_STATUS_IS_OK(r.out.result)) {
4651                         torture_comment(tctx, "QueryDomainInformationPolicy failed - %s\n", nt_errstr(r.out.result));
4652                         ret = false;
4653                         continue;
4654                 }
4655         }
4656
4657         return ret;
4658 }
4659
4660
4661 static bool test_QueryInfoPolicyCalls(  bool version2,
4662                                         struct dcerpc_binding_handle *b,
4663                                         struct torture_context *tctx,
4664                                         struct policy_handle *handle)
4665 {
4666         struct lsa_QueryInfoPolicy r;
4667         union lsa_PolicyInformation *info = NULL;
4668         int i;
4669         bool ret = true;
4670         const char *call = talloc_asprintf(tctx, "QueryInfoPolicy%s", version2 ? "2":"");
4671
4672         torture_comment(tctx, "\nTesting %s\n", call);
4673
4674         if (version2 && torture_setting_bool(tctx, "samba3", false)) {
4675                 torture_skip(tctx, "skipping QueryInfoPolicy2 tests\n");
4676         }
4677
4678         for (i=1;i<=14;i++) {
4679                 r.in.handle = handle;
4680                 r.in.level = i;
4681                 r.out.info = &info;
4682
4683                 torture_comment(tctx, "\nTrying %s level %d\n", call, i);
4684
4685                 if (version2)
4686                         /* We can perform the cast, because both types are
4687                            structurally equal */
4688                         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryInfoPolicy2_r(b, tctx,
4689                                  (struct lsa_QueryInfoPolicy2*) &r),
4690                                  "QueryInfoPolicy2 failed");
4691                 else
4692                         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryInfoPolicy_r(b, tctx, &r),
4693                                 "QueryInfoPolicy2 failed");
4694
4695                 switch (i) {
4696                 case LSA_POLICY_INFO_MOD:
4697                 case LSA_POLICY_INFO_AUDIT_FULL_SET:
4698                 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
4699                         if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
4700                                 torture_comment(tctx, "Server should have failed level %u: %s\n", i, nt_errstr(r.out.result));
4701                                 ret = false;
4702                         }
4703                         break;
4704                 case LSA_POLICY_INFO_DOMAIN:
4705                 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
4706                 case LSA_POLICY_INFO_REPLICA:
4707                 case LSA_POLICY_INFO_QUOTA:
4708                 case LSA_POLICY_INFO_ROLE:
4709                 case LSA_POLICY_INFO_AUDIT_LOG:
4710                 case LSA_POLICY_INFO_AUDIT_EVENTS:
4711                 case LSA_POLICY_INFO_PD:
4712                         if (!NT_STATUS_IS_OK(r.out.result)) {
4713                                 torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
4714                                 ret = false;
4715                         }
4716                         break;
4717                 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
4718                 case LSA_POLICY_INFO_DNS_INT:
4719                 case LSA_POLICY_INFO_DNS:
4720                         if (torture_setting_bool(tctx, "samba3", false)) {
4721                                 /* Other levels not implemented yet */
4722                                 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_INFO_CLASS)) {
4723                                         torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
4724                                         ret = false;
4725                                 }
4726                         } else if (!NT_STATUS_IS_OK(r.out.result)) {
4727                                 torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
4728                                 ret = false;
4729                         }
4730                         break;
4731                 default:
4732                         if (torture_setting_bool(tctx, "samba4", false)) {
4733                                 /* Other levels not implemented yet */
4734                                 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_INFO_CLASS)) {
4735                                         torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
4736                                         ret = false;
4737                                 }
4738                         } else if (!NT_STATUS_IS_OK(r.out.result)) {
4739                                 torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
4740                                 ret = false;
4741                         }
4742                         break;
4743                 }
4744
4745                 if (NT_STATUS_IS_OK(r.out.result) && (i == LSA_POLICY_INFO_DNS
4746                         || i == LSA_POLICY_INFO_DNS_INT)) {
4747                         /* Let's look up some of these names */
4748
4749                         struct lsa_TransNameArray tnames;
4750                         tnames.count = 14;
4751                         tnames.names = talloc_zero_array(tctx, struct lsa_TranslatedName, tnames.count);
4752                         tnames.names[0].name.string = info->dns.name.string;
4753                         tnames.names[0].sid_type = SID_NAME_DOMAIN;
4754                         tnames.names[1].name.string = info->dns.dns_domain.string;
4755                         tnames.names[1].sid_type = SID_NAME_DOMAIN;
4756                         tnames.names[2].name.string = talloc_asprintf(tctx, "%s\\", info->dns.name.string);
4757                         tnames.names[2].sid_type = SID_NAME_DOMAIN;
4758                         tnames.names[3].name.string = talloc_asprintf(tctx, "%s\\", info->dns.dns_domain.string);
4759                         tnames.names[3].sid_type = SID_NAME_DOMAIN;
4760                         tnames.names[4].name.string = talloc_asprintf(tctx, "%s\\guest", info->dns.name.string);
4761                         tnames.names[4].sid_type = SID_NAME_USER;
4762                         tnames.names[5].name.string = talloc_asprintf(tctx, "%s\\krbtgt", info->dns.name.string);
4763                         tnames.names[5].sid_type = SID_NAME_USER;
4764                         tnames.names[6].name.string = talloc_asprintf(tctx, "%s\\guest", info->dns.dns_domain.string);
4765                         tnames.names[6].sid_type = SID_NAME_USER;
4766                         tnames.names[7].name.string = talloc_asprintf(tctx, "%s\\krbtgt", info->dns.dns_domain.string);
4767                         tnames.names[7].sid_type = SID_NAME_USER;
4768                         tnames.names[8].name.string = talloc_asprintf(tctx, "krbtgt@%s", info->dns.name.string);
4769                         tnames.names[8].sid_type = SID_NAME_USER;
4770                         tnames.names[9].name.string = talloc_asprintf(tctx, "krbtgt@%s", info->dns.dns_domain.string);
4771                         tnames.names[9].sid_type = SID_NAME_USER;
4772                         tnames.names[10].name.string = talloc_asprintf(tctx, "%s\\"TEST_MACHINENAME "$", info->dns.name.string);
4773                         tnames.names[10].sid_type = SID_NAME_USER;
4774                         tnames.names[11].name.string = talloc_asprintf(tctx, "%s\\"TEST_MACHINENAME "$", info->dns.dns_domain.string);
4775                         tnames.names[11].sid_type = SID_NAME_USER;
4776                         tnames.names[12].name.string = talloc_asprintf(tctx, TEST_MACHINENAME "$@%s", info->dns.name.string);
4777                         tnames.names[12].sid_type = SID_NAME_USER;
4778                         tnames.names[13].name.string = talloc_asprintf(tctx, TEST_MACHINENAME "$@%s", info->dns.dns_domain.string);
4779                         tnames.names[13].sid_type = SID_NAME_USER;
4780                         ret &= test_LookupNames(b, tctx, handle, &tnames);
4781
4782                 }
4783         }
4784
4785         return ret;
4786 }
4787
4788 static bool test_QueryInfoPolicy(struct dcerpc_binding_handle *b,
4789                                  struct torture_context *tctx,
4790                                  struct policy_handle *handle)
4791 {
4792         return test_QueryInfoPolicyCalls(false, b, tctx, handle);
4793 }
4794
4795 static bool test_QueryInfoPolicy2(struct dcerpc_binding_handle *b,
4796                                   struct torture_context *tctx,
4797                                   struct policy_handle *handle)
4798 {
4799         return test_QueryInfoPolicyCalls(true, b, tctx, handle);
4800 }
4801
4802 static bool test_GetUserName(struct dcerpc_binding_handle *b,
4803                              struct torture_context *tctx)
4804 {
4805         struct lsa_GetUserName r;
4806         bool ret = true;
4807         struct lsa_String *authority_name_p = NULL;
4808         struct lsa_String *account_name_p = NULL;
4809
4810         torture_comment(tctx, "\nTesting GetUserName\n");
4811
4812         r.in.system_name        = "\\";
4813         r.in.account_name       = &account_name_p;
4814         r.in.authority_name     = NULL;
4815         r.out.account_name      = &account_name_p;
4816
4817         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetUserName_r(b, tctx, &r),
4818                 "GetUserName failed");
4819
4820         if (!NT_STATUS_IS_OK(r.out.result)) {
4821                 torture_comment(tctx, "GetUserName failed - %s\n", nt_errstr(r.out.result));
4822                 ret = false;
4823         }
4824
4825         account_name_p = NULL;
4826         r.in.account_name       = &account_name_p;
4827         r.in.authority_name     = &authority_name_p;
4828         r.out.account_name      = &account_name_p;
4829
4830         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetUserName_r(b, tctx, &r),
4831                 "GetUserName failed");
4832
4833         if (!NT_STATUS_IS_OK(r.out.result)) {
4834                 torture_comment(tctx, "GetUserName failed - %s\n", nt_errstr(r.out.result));
4835                 ret = false;
4836         }
4837
4838         return ret;
4839 }
4840
4841 static bool test_GetUserName_fail(struct dcerpc_binding_handle *b,
4842                                   struct torture_context *tctx)
4843 {
4844         struct lsa_GetUserName r;
4845         struct lsa_String *account_name_p = NULL;
4846         NTSTATUS status;
4847
4848         torture_comment(tctx, "\nTesting GetUserName_fail\n");
4849
4850         r.in.system_name        = "\\";
4851         r.in.account_name       = &account_name_p;
4852         r.in.authority_name     = NULL;
4853         r.out.account_name      = &account_name_p;
4854
4855         status = dcerpc_lsa_GetUserName_r(b, tctx, &r);
4856         if (!NT_STATUS_IS_OK(status)) {
4857                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4858                         torture_comment(tctx,
4859                                         "GetUserName correctly returned with "
4860                                         "status: %s\n",
4861                                         nt_errstr(status));
4862                         return true;
4863                 }
4864
4865                 torture_assert_ntstatus_equal(tctx,
4866                                               status,
4867                                               NT_STATUS_ACCESS_DENIED,
4868                                               "GetUserName return value should "
4869                                               "be ACCESS_DENIED");
4870                 return true;
4871         }
4872
4873         if (!NT_STATUS_IS_OK(r.out.result)) {
4874                 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) ||
4875                     NT_STATUS_EQUAL(r.out.result, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
4876                         torture_comment(tctx,
4877                                         "GetUserName correctly returned with "
4878                                         "result: %s\n",
4879                                         nt_errstr(r.out.result));
4880                         return true;
4881                 }
4882         }
4883
4884         torture_assert_ntstatus_equal(tctx,
4885                                       r.out.result,
4886                                       NT_STATUS_OK,
4887                                       "GetUserName return value should be "
4888                                       "ACCESS_DENIED");
4889
4890         return false;
4891 }
4892
4893 bool test_lsa_Close(struct dcerpc_binding_handle *b,
4894                     struct torture_context *tctx,
4895                     struct policy_handle *handle)
4896 {
4897         struct lsa_Close r;
4898         struct policy_handle handle2;
4899
4900         torture_comment(tctx, "\nTesting Close\n");
4901
4902         r.in.handle = handle;
4903         r.out.handle = &handle2;
4904
4905         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Close_r(b, tctx, &r),
4906                 "Close failed");
4907         torture_assert_ntstatus_ok(tctx, r.out.result,
4908                 "Close failed");
4909
4910         torture_assert_ntstatus_equal(tctx, dcerpc_lsa_Close_r(b, tctx, &r),
4911                 NT_STATUS_RPC_SS_CONTEXT_MISMATCH, "Close should failed");
4912
4913         torture_comment(tctx, "\n");
4914
4915         return true;
4916 }
4917
4918 bool torture_rpc_lsa(struct torture_context *tctx)
4919 {
4920         NTSTATUS status;
4921         struct dcerpc_pipe *p;
4922         bool ret = true;
4923         struct policy_handle *handle = NULL;
4924         struct test_join *join = NULL;
4925         struct cli_credentials *machine_creds;
4926         struct dcerpc_binding_handle *b;
4927         enum dcerpc_transport_t transport;
4928
4929         status = torture_rpc_connection(tctx, &p, &ndr_table_lsarpc);
4930         if (!NT_STATUS_IS_OK(status)) {
4931                 return false;
4932         }
4933         b = p->binding_handle;
4934         transport = dcerpc_binding_get_transport(p->binding);
4935
4936         /* Test lsaLookupSids3 and lsaLookupNames4 over tcpip */
4937         if (transport == NCACN_IP_TCP) {
4938                 if (!test_OpenPolicy_fail(b, tctx)) {
4939                         ret = false;
4940                 }
4941
4942                 if (!test_OpenPolicy2_fail(b, tctx)) {
4943                         ret = false;
4944                 }
4945
4946                 if (!test_many_LookupSids(p, tctx, handle)) {
4947                         ret = false;
4948                 }
4949
4950                 return ret;
4951         }
4952
4953         if (!test_OpenPolicy(b, tctx)) {
4954                 ret = false;
4955         }
4956
4957         if (!test_lsa_OpenPolicy2(b, tctx, &handle)) {
4958                 ret = false;
4959         }
4960
4961         if (handle) {
4962                 join = torture_join_domain(tctx, TEST_MACHINENAME, ACB_WSTRUST, &machine_creds);
4963                 if (!join) {
4964                         ret = false;
4965                 }
4966
4967                 if (!test_LookupSids_async(b, tctx, handle)) {
4968                         ret = false;
4969                 }
4970
4971                 if (!test_QueryDomainInfoPolicy(b, tctx, handle)) {
4972                         ret = false;
4973                 }
4974
4975                 if (!test_CreateSecret(p, tctx, handle)) {
4976                         ret = false;
4977                 }
4978
4979                 if (!test_QueryInfoPolicy(b, tctx, handle)) {
4980                         ret = false;
4981                 }
4982
4983                 if (!test_QueryInfoPolicy2(b, tctx, handle)) {
4984                         ret = false;
4985                 }
4986
4987                 if (!test_Delete(b, tctx, handle)) {
4988                         ret = false;
4989                 }
4990
4991                 if (!test_many_LookupSids(p, tctx, handle)) {
4992                         ret = false;
4993                 }
4994
4995                 if (!test_lsa_Close(b, tctx, handle)) {
4996                         ret = false;
4997                 }
4998
4999                 torture_leave_domain(tctx, join);
5000
5001         } else {
5002                 if (!test_many_LookupSids(p, tctx, handle)) {
5003                         ret = false;
5004                 }
5005         }
5006
5007         if (!test_GetUserName(b, tctx)) {
5008                 ret = false;
5009         }
5010
5011         return ret;
5012 }
5013
5014 bool torture_rpc_lsa_get_user(struct torture_context *tctx)
5015 {
5016         NTSTATUS status;
5017         struct dcerpc_pipe *p;
5018         bool ret = true;
5019         struct dcerpc_binding_handle *b;
5020         enum dcerpc_transport_t transport;
5021
5022         status = torture_rpc_connection(tctx, &p, &ndr_table_lsarpc);
5023         if (!NT_STATUS_IS_OK(status)) {
5024                 return false;
5025         }
5026         b = p->binding_handle;
5027         transport = dcerpc_binding_get_transport(p->binding);
5028
5029         if (transport == NCACN_IP_TCP) {
5030                 if (!test_GetUserName_fail(b, tctx)) {
5031                         ret = false;
5032                 }
5033                 return ret;
5034         }
5035
5036         if (!test_GetUserName(b, tctx)) {
5037                 ret = false;
5038         }
5039
5040         return ret;
5041 }
5042
5043 static bool testcase_LookupNames(struct torture_context *tctx,
5044                                  struct dcerpc_pipe *p)
5045 {
5046         bool ret = true;
5047         struct policy_handle *handle;
5048         struct lsa_TransNameArray tnames;
5049         struct lsa_TransNameArray2 tnames2;
5050         struct dcerpc_binding_handle *b = p->binding_handle;
5051         enum dcerpc_transport_t transport = dcerpc_binding_get_transport(p->binding);
5052
5053         if (transport != NCACN_NP && transport != NCALRPC) {
5054                 torture_comment(tctx, "testcase_LookupNames is only available "
5055                                 "over NCACN_NP or NCALRPC");
5056                 return true;
5057         }
5058
5059         if (!test_OpenPolicy(b, tctx)) {
5060                 ret = false;
5061         }
5062
5063         if (!test_lsa_OpenPolicy2(b, tctx, &handle)) {
5064                 ret = false;
5065         }
5066
5067         if (!handle) {
5068                 ret = false;
5069         }
5070
5071         tnames.count = 1;
5072         tnames.names = talloc_array(tctx, struct lsa_TranslatedName, tnames.count);
5073         ZERO_STRUCT(tnames.names[0]);
5074         tnames.names[0].name.string = "BUILTIN";
5075         tnames.names[0].sid_type = SID_NAME_DOMAIN;
5076
5077         if (!test_LookupNames(b, tctx, handle, &tnames)) {
5078                 ret = false;
5079         }
5080
5081         tnames2.count = 1;
5082         tnames2.names = talloc_array(tctx, struct lsa_TranslatedName2, tnames2.count);
5083         ZERO_STRUCT(tnames2.names[0]);
5084         tnames2.names[0].name.string = "BUILTIN";
5085         tnames2.names[0].sid_type = SID_NAME_DOMAIN;
5086
5087         if (!test_LookupNames2(b, tctx, handle, &tnames2, true)) {
5088                 ret = false;
5089         }
5090
5091         if (!test_LookupNames3(b, tctx, handle, &tnames2, true)) {
5092                 ret = false;
5093         }
5094
5095         if (!test_LookupNames_wellknown(b, tctx, handle)) {
5096                 ret = false;
5097         }
5098
5099         if (!test_LookupNames_NULL(b, tctx, handle)) {
5100                 ret = false;
5101         }
5102
5103         if (!test_LookupNames_bogus(b, tctx, handle)) {
5104                 ret = false;
5105         }
5106
5107         if (!test_lsa_Close(b, tctx, handle)) {
5108                 ret = false;
5109         }
5110
5111         return ret;
5112 }
5113
5114 struct torture_suite *torture_rpc_lsa_lookup_names(TALLOC_CTX *mem_ctx)
5115 {
5116         struct torture_suite *suite;
5117         struct torture_rpc_tcase *tcase;
5118
5119         suite = torture_suite_create(mem_ctx, "lsa.lookupnames");
5120
5121         tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa",
5122                                                   &ndr_table_lsarpc);
5123         torture_rpc_tcase_add_test(tcase, "LookupNames",
5124                                    testcase_LookupNames);
5125
5126         return suite;
5127 }
5128
5129 struct lsa_trustdom_state {
5130         uint32_t num_trusts;
5131 };
5132
5133 static bool testcase_TrustedDomains(struct torture_context *tctx,
5134                                     struct dcerpc_pipe *p,
5135                                     void *data)
5136 {
5137         bool ret = true;
5138         struct policy_handle *handle;
5139         struct lsa_trustdom_state *state =
5140                 talloc_get_type_abort(data, struct lsa_trustdom_state);
5141         struct dcerpc_binding_handle *b = p->binding_handle;
5142         enum dcerpc_transport_t transport = dcerpc_binding_get_transport(p->binding);
5143
5144         if (transport != NCACN_NP && transport != NCALRPC) {
5145                 torture_comment(tctx, "testcase_TrustedDomains is only available "
5146                                 "over NCACN_NP or NCALRPC");
5147                 return true;
5148         }
5149
5150         torture_comment(tctx, "Testing %d domains\n", state->num_trusts);
5151
5152         if (!test_OpenPolicy(b, tctx)) {
5153                 ret = false;
5154         }
5155
5156         if (!test_lsa_OpenPolicy2(b, tctx, &handle)) {
5157                 ret = false;
5158         }
5159
5160         if (!handle) {
5161                 ret = false;
5162         }
5163
5164         if (!test_CreateTrustedDomain(b, tctx, handle, state->num_trusts)) {
5165                 ret = false;
5166         }
5167
5168         if (!test_CreateTrustedDomainEx(p, tctx, handle, state->num_trusts)) {
5169                 ret = false;
5170         }
5171
5172         if (!test_CreateTrustedDomainEx2(p, tctx, handle, state->num_trusts)) {
5173                 ret = false;
5174         }
5175
5176         if (!test_lsa_Close(b, tctx, handle)) {
5177                 ret = false;
5178         }
5179
5180         return ret;
5181 }
5182
5183 struct torture_suite *torture_rpc_lsa_trusted_domains(TALLOC_CTX *mem_ctx)
5184 {
5185         struct torture_suite *suite;
5186         struct torture_rpc_tcase *tcase;
5187         struct lsa_trustdom_state *state;
5188
5189         state = talloc(mem_ctx, struct lsa_trustdom_state);
5190
5191         state->num_trusts = 12;
5192
5193         suite = torture_suite_create(mem_ctx, "lsa.trusted.domains");
5194
5195         tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa",
5196                                                   &ndr_table_lsarpc);
5197         torture_rpc_tcase_add_test_ex(tcase, "TrustedDomains",
5198                                       testcase_TrustedDomains,
5199                                       state);
5200
5201         return suite;
5202 }
5203
5204 static bool testcase_Privileges(struct torture_context *tctx,
5205                                 struct dcerpc_pipe *p)
5206 {
5207         struct policy_handle *handle;
5208         struct dcerpc_binding_handle *b = p->binding_handle;
5209         enum dcerpc_transport_t transport = dcerpc_binding_get_transport(p->binding);
5210
5211         if (transport != NCACN_NP && transport != NCALRPC) {
5212                 torture_skip(tctx, "testcase_Privileges is only available "
5213                                 "over NCACN_NP or NCALRPC");
5214         }
5215
5216         if (!test_OpenPolicy(b, tctx)) {
5217                 return false;
5218         }
5219
5220         if (!test_lsa_OpenPolicy2(b, tctx, &handle)) {
5221                 return false;
5222         }
5223
5224         if (!handle) {
5225                 return false;
5226         }
5227
5228         if (!test_CreateAccount(b, tctx, handle)) {
5229                 return false;
5230         }
5231
5232         if (!test_EnumAccounts(b, tctx, handle)) {
5233                 return false;
5234         }
5235
5236         if (!test_EnumPrivs(b, tctx, handle)) {
5237                 return false;
5238         }
5239
5240         if (!test_lsa_Close(b, tctx, handle)) {
5241                 return false;
5242         }
5243
5244         return true;
5245 }
5246
5247
5248 struct torture_suite *torture_rpc_lsa_privileges(TALLOC_CTX *mem_ctx)
5249 {
5250         struct torture_suite *suite;
5251         struct torture_rpc_tcase *tcase;
5252
5253         suite = torture_suite_create(mem_ctx, "lsa.privileges");
5254
5255         tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa",
5256                                                   &ndr_table_lsarpc);
5257         torture_rpc_tcase_add_test(tcase, "Privileges",
5258                                    testcase_Privileges);
5259
5260         return suite;
5261 }