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