s3:utils: Fix 'Usage:' for 'net ads enctypes'
[samba4-gss.git] / source4 / torture / rpc / lsa.c
blobbac0f29695e4da95ad6d7b014fc724ff2525416c
1 /*
2 Unix SMB/CIFS implementation.
3 test suite for lsa rpc operations
5 Copyright (C) Andrew Tridgell 2003
6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2005
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.
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.
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/>.
22 #include "includes.h"
23 #include "torture/torture.h"
24 #include "source3/libads/netlogon_ping.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 #include "source3/rpc_client/init_lsa.h"
40 #include "librpc/gen_ndr/ndr_lsa.h"
41 #include "librpc/rpc/dcerpc_lsa.h"
43 #include <gnutls/gnutls.h>
44 #include <gnutls/crypto.h>
46 #define TEST_MACHINENAME "lsatestmach"
47 #define TRUSTPW "12345678"
49 static bool test_OpenPolicy(struct dcerpc_binding_handle *b,
50 struct torture_context *tctx)
52 struct lsa_ObjectAttribute attr;
53 struct policy_handle handle;
54 struct lsa_QosInfo qos;
55 struct lsa_OpenPolicy r;
56 uint16_t system_name = '\\';
58 torture_comment(tctx, "\nTesting OpenPolicy\n");
60 qos.len = 0;
61 qos.impersonation_level = 2;
62 qos.context_mode = 1;
63 qos.effective_only = 0;
65 attr.len = 0;
66 attr.root_dir = NULL;
67 attr.object_name = NULL;
68 attr.attributes = 0;
69 attr.sec_desc = NULL;
70 attr.sec_qos = &qos;
72 r.in.system_name = &system_name;
73 r.in.attr = &attr;
74 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
75 r.out.handle = &handle;
77 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenPolicy_r(b, tctx, &r),
78 "OpenPolicy failed");
80 torture_assert_ntstatus_ok(tctx,
81 r.out.result,
82 "OpenPolicy failed");
84 return true;
87 static bool test_OpenPolicy_fail(struct dcerpc_binding_handle *b,
88 struct torture_context *tctx)
90 struct lsa_ObjectAttribute attr;
91 struct policy_handle handle;
92 struct lsa_QosInfo qos;
93 struct lsa_OpenPolicy r;
94 uint16_t system_name = '\\';
95 NTSTATUS status;
97 torture_comment(tctx, "\nTesting OpenPolicy_fail\n");
99 qos.len = 0;
100 qos.impersonation_level = 2;
101 qos.context_mode = 1;
102 qos.effective_only = 0;
104 attr.len = 0;
105 attr.root_dir = NULL;
106 attr.object_name = NULL;
107 attr.attributes = 0;
108 attr.sec_desc = NULL;
109 attr.sec_qos = &qos;
111 r.in.system_name = &system_name;
112 r.in.attr = &attr;
113 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
114 r.out.handle = &handle;
116 status = dcerpc_lsa_OpenPolicy_r(b, tctx, &r);
117 if (!NT_STATUS_IS_OK(status)) {
118 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
119 torture_comment(tctx,
120 "OpenPolicy correctly returned with "
121 "status: %s\n",
122 nt_errstr(status));
123 return true;
126 torture_assert_ntstatus_equal(tctx,
127 status,
128 NT_STATUS_ACCESS_DENIED,
129 "OpenPolicy return value should "
130 "be ACCESS_DENIED");
131 return true;
134 if (!NT_STATUS_IS_OK(r.out.result)) {
135 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) ||
136 NT_STATUS_EQUAL(r.out.result, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
137 torture_comment(tctx,
138 "OpenPolicy correctly returned with "
139 "result: %s\n",
140 nt_errstr(r.out.result));
141 return true;
145 torture_assert_ntstatus_equal(tctx,
146 r.out.result,
147 NT_STATUS_OK,
148 "OpenPolicy return value should be "
149 "ACCESS_DENIED");
151 return false;
155 bool test_lsa_OpenPolicy2_ex(struct dcerpc_binding_handle *b,
156 struct torture_context *tctx,
157 struct policy_handle **handle,
158 NTSTATUS expected_status,
159 NTSTATUS expected_status2)
161 struct lsa_ObjectAttribute attr;
162 struct lsa_QosInfo qos;
163 struct lsa_OpenPolicy2 r;
164 NTSTATUS status;
166 torture_comment(tctx, "\nTesting OpenPolicy2\n");
168 *handle = talloc(tctx, struct policy_handle);
169 torture_assert(tctx, *handle != NULL, "talloc(tctx, struct policy_handle)");
171 qos.len = 0;
172 qos.impersonation_level = 2;
173 qos.context_mode = 1;
174 qos.effective_only = 0;
176 attr.len = 0;
177 attr.root_dir = NULL;
178 attr.object_name = NULL;
179 attr.attributes = 0;
180 attr.sec_desc = NULL;
181 attr.sec_qos = &qos;
183 r.in.system_name = "\\";
184 r.in.attr = &attr;
185 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
186 r.out.handle = *handle;
188 status = dcerpc_lsa_OpenPolicy2_r(b, tctx, &r);
190 /* Allow two possible failure status codes */
191 if (!NT_STATUS_EQUAL(status, expected_status2)) {
192 torture_assert_ntstatus_equal(tctx, status,
193 expected_status,
194 "OpenPolicy2 failed");
196 if (!NT_STATUS_IS_OK(expected_status) ||
197 !NT_STATUS_IS_OK(expected_status2)) {
198 return true;
201 torture_assert_ntstatus_ok(tctx,
202 r.out.result,
203 "OpenPolicy2 failed");
205 return true;
209 bool test_lsa_OpenPolicy2(struct dcerpc_binding_handle *b,
210 struct torture_context *tctx,
211 struct policy_handle **handle)
213 return test_lsa_OpenPolicy2_ex(b, tctx, handle,
214 NT_STATUS_OK, NT_STATUS_OK);
217 static bool test_OpenPolicy2_fail(struct dcerpc_binding_handle *b,
218 struct torture_context *tctx)
220 struct lsa_ObjectAttribute attr;
221 struct policy_handle handle;
222 struct lsa_QosInfo qos;
223 struct lsa_OpenPolicy2 r;
224 NTSTATUS status;
226 torture_comment(tctx, "\nTesting OpenPolicy2_fail\n");
228 qos.len = 0;
229 qos.impersonation_level = 2;
230 qos.context_mode = 1;
231 qos.effective_only = 0;
233 attr.len = 0;
234 attr.root_dir = NULL;
235 attr.object_name = NULL;
236 attr.attributes = 0;
237 attr.sec_desc = NULL;
238 attr.sec_qos = &qos;
240 r.in.system_name = "\\";
241 r.in.attr = &attr;
242 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
243 r.out.handle = &handle;
245 status = dcerpc_lsa_OpenPolicy2_r(b, tctx, &r);
246 if (!NT_STATUS_IS_OK(status)) {
247 if (NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_DISCONNECTED) ||
248 NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
249 torture_comment(tctx,
250 "OpenPolicy2 correctly returned with "
251 "status: %s\n",
252 nt_errstr(status));
253 return true;
256 torture_assert_ntstatus_equal(tctx,
257 status,
258 NT_STATUS_ACCESS_DENIED,
259 "OpenPolicy2 return value should "
260 "be ACCESS_DENIED");
261 return true;
264 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) ||
265 NT_STATUS_EQUAL(r.out.result, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
266 torture_comment(tctx,
267 "OpenPolicy2 correctly returned with "
268 "result: %s\n",
269 nt_errstr(r.out.result));
270 return true;
273 torture_fail(tctx,
274 "OpenPolicy2 return value should be "
275 "ACCESS_DENIED or RPC_PROTSEQ_NOT_SUPPORTED");
277 return false;
280 bool test_lsa_OpenPolicy3_ex(struct dcerpc_binding_handle *b,
281 struct torture_context *tctx,
282 struct policy_handle **handle,
283 NTSTATUS expected_status,
284 NTSTATUS expected_status2)
286 struct lsa_QosInfo qos = {
287 .impersonation_level = 2,
288 .context_mode = 1,
290 struct lsa_ObjectAttribute attr = {
291 .len = 0,
292 .sec_qos = &qos,
294 struct lsa_revision_info1 in_rinfo1 = {
295 .revision = 1,
296 .supported_features = LSA_FEATURE_TDO_AUTH_INFO_AES_CIPHER,
298 union lsa_revision_info in_rinfo = {
299 .info1 = in_rinfo1,
301 struct lsa_revision_info1 out_rinfo1 = {
302 .revision = 0,
304 union lsa_revision_info out_rinfo = {
305 .info1 = out_rinfo1,
307 uint32_t out_version = 0;
308 struct lsa_OpenPolicy3 r = {
309 .in.system_name = "\\",
310 .in.attr = &attr,
311 .in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED,
312 .in.in_version = 1,
313 .in.in_revision_info = &in_rinfo,
314 .out.out_version = &out_version,
315 .out.out_revision_info = &out_rinfo,
317 NTSTATUS status;
319 torture_comment(tctx, "\nTesting OpenPolicy3\n");
321 *handle = talloc(tctx, struct policy_handle);
322 torture_assert(tctx,
323 *handle != NULL,
324 "talloc(tctx, struct policy_handle)");
325 r.out.handle = *handle;
327 status = dcerpc_lsa_OpenPolicy3_r(b, tctx, &r);
329 /* Allow two possible failure status codes */
330 if (!NT_STATUS_EQUAL(status, expected_status2)) {
331 torture_assert_ntstatus_equal(tctx,
332 status,
333 expected_status,
334 "OpenPolicy3 failed");
336 if (!NT_STATUS_IS_OK(expected_status) ||
337 !NT_STATUS_IS_OK(expected_status2)) {
338 return true;
341 torture_assert_ntstatus_ok(tctx, r.out.result, "OpenPolicy3 failed");
342 torture_assert_int_equal(tctx, out_version, 1, "Invalid out_version");
343 torture_assert_int_equal(tctx,
344 out_rinfo1.revision,
346 "Invalid revision");
347 torture_assert_int_equal(tctx,
348 out_rinfo1.supported_features,
349 LSA_FEATURE_TDO_AUTH_INFO_AES_CIPHER,
350 "Invalid supported feature set");
352 return true;
355 bool test_lsa_OpenPolicy3(struct dcerpc_binding_handle *b,
356 struct torture_context *tctx,
357 struct policy_handle **handle)
359 return test_lsa_OpenPolicy3_ex(b,
360 tctx,
361 handle,
362 NT_STATUS_OK,
363 NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE);
366 static bool test_OpenPolicy3_fail(struct dcerpc_binding_handle *b,
367 struct torture_context *tctx)
369 struct policy_handle handle = {
370 .handle_type = 0,
372 struct lsa_QosInfo qos = {
373 .impersonation_level = 2,
374 .context_mode = 1,
376 struct lsa_ObjectAttribute attr = {
377 .len = 0,
378 .sec_qos = &qos,
380 struct lsa_revision_info1 in_rinfo1 = {
381 .revision = 0,
382 .supported_features = 0,
384 union lsa_revision_info in_rinfo = {
385 .info1 = in_rinfo1,
387 struct lsa_revision_info1 out_rinfo1 = {
388 .revision = 0,
390 union lsa_revision_info out_rinfo = {
391 .info1 = out_rinfo1,
393 uint32_t out_version = 0;
394 struct lsa_OpenPolicy3 r = {
395 .in.system_name = "\\",
396 .in.attr = &attr,
397 .in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED,
398 .in.in_version = 1,
399 .in.in_revision_info = &in_rinfo,
400 .out.out_version = &out_version,
401 .out.out_revision_info = &out_rinfo,
402 .out.handle = &handle,
404 NTSTATUS status;
406 torture_comment(tctx, "\nTesting OpenPolicy3_fail\n");
408 status = dcerpc_lsa_OpenPolicy3_r(b, tctx, &r);
409 if (!NT_STATUS_IS_OK(status)) {
410 if (NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_DISCONNECTED) ||
411 NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) ||
412 NT_STATUS_EQUAL(status,
413 NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
414 torture_comment(tctx,
415 "OpenPolicy3 correctly returned with "
416 "status: %s\n",
417 nt_errstr(status));
418 return true;
421 torture_assert_ntstatus_equal(tctx,
422 status,
423 NT_STATUS_ACCESS_DENIED,
424 "OpenPolicy3 return value should "
425 "be ACCESS_DENIED or CONNECTION_DISCONNECTED");
426 return true;
429 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) ||
430 NT_STATUS_EQUAL(r.out.result,
431 NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
432 torture_comment(tctx,
433 "OpenPolicy3 correctly returned with "
434 "result: %s\n",
435 nt_errstr(r.out.result));
436 return true;
439 torture_fail(tctx,
440 "OpenPolicy3 return value should be "
441 "ACCESS_DENIED or RPC_PROTSEQ_NOT_SUPPORTED");
443 return false;
446 static bool test_LookupNames(struct dcerpc_binding_handle *b,
447 struct torture_context *tctx,
448 struct policy_handle *handle,
449 enum lsa_LookupNamesLevel level,
450 struct lsa_TransNameArray *tnames)
452 struct lsa_LookupNames r;
453 struct lsa_TransSidArray sids;
454 struct lsa_RefDomainList *domains = NULL;
455 struct lsa_String *names;
456 uint32_t count = 0;
457 int i;
458 uint32_t *input_idx;
460 torture_comment(tctx, "\nTesting LookupNames with %d names\n", tnames->count);
462 sids.count = 0;
463 sids.sids = NULL;
466 r.in.num_names = 0;
468 input_idx = talloc_array(tctx, uint32_t, tnames->count);
469 names = talloc_array(tctx, struct lsa_String, tnames->count);
471 for (i=0;i<tnames->count;i++) {
472 if (tnames->names[i].sid_type != SID_NAME_UNKNOWN) {
473 init_lsa_String(&names[r.in.num_names], tnames->names[i].name.string);
474 input_idx[r.in.num_names] = i;
475 r.in.num_names++;
479 r.in.handle = handle;
480 r.in.names = names;
481 r.in.sids = &sids;
482 r.in.level = level;
483 r.in.count = &count;
484 r.out.count = &count;
485 r.out.sids = &sids;
486 r.out.domains = &domains;
488 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupNames_r(b, tctx, &r),
489 "LookupNames failed");
490 if (NT_STATUS_EQUAL(r.out.result, STATUS_SOME_UNMAPPED) ||
491 NT_STATUS_EQUAL(r.out.result, NT_STATUS_NONE_MAPPED)) {
492 for (i=0;i< r.in.num_names;i++) {
493 if (i < count && sids.sids[i].sid_type == SID_NAME_UNKNOWN) {
494 torture_comment(tctx, "LookupName of %s was unmapped\n",
495 tnames->names[i].name.string);
496 } else if (i >=count) {
497 torture_comment(tctx, "LookupName of %s failed to return a result\n",
498 tnames->names[i].name.string);
501 torture_assert_ntstatus_ok(tctx, r.out.result,
502 "LookupNames failed");
503 } else if (!NT_STATUS_IS_OK(r.out.result)) {
504 torture_assert_ntstatus_ok(tctx, r.out.result,
505 "LookupNames failed");
508 for (i=0;i< r.in.num_names;i++) {
509 torture_assert(tctx, (i < count),
510 talloc_asprintf(tctx,
511 "LookupName of %s failed to return a result\n",
512 tnames->names[input_idx[i]].name.string));
514 torture_assert_int_equal(tctx,
515 sids.sids[i].sid_type,
516 tnames->names[input_idx[i]].sid_type,
517 talloc_asprintf(tctx,
518 "LookupName of %s got unexpected name type: %s\n",
519 tnames->names[input_idx[i]].name.string,
520 sid_type_lookup(sids.sids[i].sid_type)));
521 if (sids.sids[i].sid_type != SID_NAME_DOMAIN) {
522 continue;
524 torture_assert_int_equal(tctx,
525 sids.sids[i].rid,
526 UINT32_MAX,
527 talloc_asprintf(tctx,
528 "LookupName of %s got unexpected rid: %d\n",
529 tnames->names[input_idx[i]].name.string,
530 sids.sids[i].rid));
533 return true;
536 static bool test_LookupNames_bogus(struct dcerpc_binding_handle *b,
537 struct torture_context *tctx,
538 struct policy_handle *handle,
539 enum lsa_LookupNamesLevel level)
541 struct lsa_LookupNames r;
542 struct lsa_TransSidArray sids;
543 struct lsa_RefDomainList *domains = NULL;
544 struct lsa_String names[1];
545 uint32_t count = 0;
547 torture_comment(tctx, "\nTesting LookupNames with bogus name\n");
549 sids.count = 0;
550 sids.sids = NULL;
552 init_lsa_String(&names[0], "NT AUTHORITY\\BOGUS");
554 r.in.handle = handle;
555 r.in.num_names = 1;
556 r.in.names = names;
557 r.in.sids = &sids;
558 r.in.level = level;
559 r.in.count = &count;
560 r.out.count = &count;
561 r.out.sids = &sids;
562 r.out.domains = &domains;
564 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupNames_r(b, tctx, &r),
565 "LookupNames bogus failed");
566 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_NONE_MAPPED)) {
567 torture_comment(tctx, "LookupNames failed - %s\n",
568 nt_errstr(r.out.result));
569 return false;
572 torture_comment(tctx, "\n");
574 return true;
577 static bool test_LookupNames_NULL(struct dcerpc_binding_handle *b,
578 struct torture_context *tctx,
579 struct policy_handle *handle,
580 enum lsa_LookupNamesLevel level)
582 struct lsa_LookupNames r;
583 struct lsa_TransSidArray sids;
584 struct lsa_RefDomainList *domains = NULL;
585 struct lsa_String names[1];
586 uint32_t count = 0;
588 torture_comment(tctx, "\nTesting LookupNames with NULL name\n");
590 sids.count = 0;
591 sids.sids = NULL;
593 names[0].string = NULL;
595 r.in.handle = handle;
596 r.in.num_names = 1;
597 r.in.names = names;
598 r.in.sids = &sids;
599 r.in.level = level;
600 r.in.count = &count;
601 r.out.count = &count;
602 r.out.sids = &sids;
603 r.out.domains = &domains;
605 /* nt4 returns NT_STATUS_NONE_MAPPED with sid_type
606 * SID_NAME_UNKNOWN, rid 0, and sid_index -1;
608 * w2k3/w2k8 return NT_STATUS_OK with sid_type
609 * SID_NAME_DOMAIN, rid -1 and sid_index 0 and BUILTIN domain
612 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupNames_r(b, tctx, &r),
613 "LookupNames with NULL name failed");
614 torture_assert_ntstatus_ok(tctx, r.out.result,
615 "LookupNames with NULL name failed");
617 torture_comment(tctx, "\n");
619 return true;
622 static bool test_LookupNames_wellknown(struct dcerpc_binding_handle *b,
623 struct torture_context *tctx,
624 struct policy_handle *handle,
625 enum lsa_LookupNamesLevel level)
627 struct lsa_TranslatedName name;
628 struct lsa_TransNameArray tnames;
629 bool ret = true;
631 torture_comment(tctx, "Testing LookupNames with well known names\n");
633 tnames.names = &name;
634 tnames.count = 1;
635 name.name.string = "NT AUTHORITY\\SYSTEM";
636 name.sid_type = SID_NAME_WKN_GRP;
637 ret &= test_LookupNames(b, tctx, handle, level, &tnames);
639 name.name.string = "NT AUTHORITY\\ANONYMOUS LOGON";
640 name.sid_type = SID_NAME_WKN_GRP;
641 ret &= test_LookupNames(b, tctx, handle, level, &tnames);
643 name.name.string = "NT AUTHORITY\\Authenticated Users";
644 name.sid_type = SID_NAME_WKN_GRP;
645 ret &= test_LookupNames(b, tctx, handle, level, &tnames);
647 #if 0
648 name.name.string = "NT AUTHORITY";
649 ret &= test_LookupNames(b, tctx, handle, level, &tnames);
651 name.name.string = "NT AUTHORITY\\";
652 ret &= test_LookupNames(b, tctx, handle, level, &tnames);
653 #endif
655 name.name.string = "BUILTIN\\";
656 name.sid_type = SID_NAME_DOMAIN;
657 ret &= test_LookupNames(b, tctx, handle, level, &tnames);
659 name.name.string = "BUILTIN\\Administrators";
660 name.sid_type = SID_NAME_ALIAS;
661 ret &= test_LookupNames(b, tctx, handle, level, &tnames);
663 name.name.string = "SYSTEM";
664 name.sid_type = SID_NAME_WKN_GRP;
665 ret &= test_LookupNames(b, tctx, handle, level, &tnames);
667 name.name.string = "Everyone";
668 name.sid_type = SID_NAME_WKN_GRP;
669 ret &= test_LookupNames(b, tctx, handle, level, &tnames);
670 return ret;
673 static bool test_LookupNames2(struct dcerpc_binding_handle *b,
674 struct torture_context *tctx,
675 struct policy_handle *handle,
676 enum lsa_LookupNamesLevel level,
677 struct lsa_TransNameArray2 *tnames,
678 bool check_result)
680 struct lsa_LookupNames2 r;
681 struct lsa_TransSidArray2 sids;
682 struct lsa_RefDomainList *domains = NULL;
683 struct lsa_String *names;
684 uint32_t *input_idx;
685 uint32_t count = 0;
686 int i;
688 torture_comment(tctx, "\nTesting LookupNames2 with %d names\n", tnames->count);
690 sids.count = 0;
691 sids.sids = NULL;
693 r.in.num_names = 0;
695 input_idx = talloc_array(tctx, uint32_t, tnames->count);
696 names = talloc_array(tctx, struct lsa_String, tnames->count);
698 for (i=0;i<tnames->count;i++) {
699 if (tnames->names[i].sid_type != SID_NAME_UNKNOWN) {
700 init_lsa_String(&names[r.in.num_names], tnames->names[i].name.string);
701 input_idx[r.in.num_names] = i;
702 r.in.num_names++;
706 r.in.handle = handle;
707 r.in.names = names;
708 r.in.sids = &sids;
709 r.in.level = level;
710 r.in.count = &count;
711 r.in.lookup_options = 0;
712 r.in.client_revision = 0;
713 r.out.count = &count;
714 r.out.sids = &sids;
715 r.out.domains = &domains;
717 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupNames2_r(b, tctx, &r),
718 "LookupNames2 failed");
719 torture_assert_ntstatus_ok(tctx, r.out.result, "LookupNames2 failed");
721 if (check_result) {
722 torture_assert_int_equal(tctx, count, sids.count,
723 "unexpected number of results returned");
724 if (sids.count > 0) {
725 torture_assert(tctx, sids.sids, "invalid sid buffer");
729 torture_comment(tctx, "\n");
731 return true;
735 static bool test_LookupNames3(struct dcerpc_binding_handle *b,
736 struct torture_context *tctx,
737 struct policy_handle *handle,
738 enum lsa_LookupNamesLevel level,
739 struct lsa_TransNameArray2 *tnames,
740 bool check_result)
742 struct lsa_LookupNames3 r;
743 struct lsa_TransSidArray3 sids;
744 struct lsa_RefDomainList *domains = NULL;
745 struct lsa_String *names;
746 uint32_t count = 0;
747 int i;
748 uint32_t *input_idx;
750 torture_comment(tctx, "\nTesting LookupNames3 with %d names\n", tnames->count);
752 sids.count = 0;
753 sids.sids = NULL;
755 r.in.num_names = 0;
757 input_idx = talloc_array(tctx, uint32_t, tnames->count);
758 names = talloc_array(tctx, struct lsa_String, tnames->count);
759 for (i=0;i<tnames->count;i++) {
760 if (tnames->names[i].sid_type != SID_NAME_UNKNOWN) {
761 init_lsa_String(&names[r.in.num_names], tnames->names[i].name.string);
762 input_idx[r.in.num_names] = i;
763 r.in.num_names++;
767 r.in.handle = handle;
768 r.in.names = names;
769 r.in.sids = &sids;
770 r.in.level = level;
771 r.in.count = &count;
772 r.in.lookup_options = 0;
773 r.in.client_revision = 0;
774 r.out.count = &count;
775 r.out.sids = &sids;
776 r.out.domains = &domains;
778 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupNames3_r(b, tctx, &r),
779 "LookupNames3 failed");
780 torture_assert_ntstatus_ok(tctx, r.out.result,
781 "LookupNames3 failed");
783 if (check_result) {
784 torture_assert_int_equal(tctx, count, sids.count,
785 "unexpected number of results returned");
786 if (sids.count > 0) {
787 torture_assert(tctx, sids.sids, "invalid sid buffer");
791 torture_comment(tctx, "\n");
793 return true;
796 static bool test_LookupNames4(struct dcerpc_binding_handle *b,
797 struct torture_context *tctx,
798 enum lsa_LookupNamesLevel level,
799 struct lsa_TransNameArray2 *tnames,
800 bool check_result)
802 struct lsa_LookupNames4 r;
803 struct lsa_TransSidArray3 sids;
804 struct lsa_RefDomainList *domains = NULL;
805 struct lsa_String *names;
806 uint32_t count = 0;
807 int i;
808 uint32_t *input_idx;
810 torture_comment(tctx, "\nTesting LookupNames4 with %d names\n", tnames->count);
812 sids.count = 0;
813 sids.sids = NULL;
815 r.in.num_names = 0;
817 input_idx = talloc_array(tctx, uint32_t, tnames->count);
818 names = talloc_array(tctx, struct lsa_String, tnames->count);
819 for (i=0;i<tnames->count;i++) {
820 if (tnames->names[i].sid_type != SID_NAME_UNKNOWN) {
821 init_lsa_String(&names[r.in.num_names], tnames->names[i].name.string);
822 input_idx[r.in.num_names] = i;
823 r.in.num_names++;
827 r.in.num_names = tnames->count;
828 r.in.names = names;
829 r.in.sids = &sids;
830 r.in.level = level;
831 r.in.count = &count;
832 r.in.lookup_options = 0;
833 r.in.client_revision = 0;
834 r.out.count = &count;
835 r.out.sids = &sids;
836 r.out.domains = &domains;
838 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupNames4_r(b, tctx, &r),
839 "LookupNames4 failed");
841 if (!NT_STATUS_IS_OK(r.out.result)) {
842 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NONE_MAPPED)) {
843 torture_comment(tctx,
844 "LookupNames4 failed: %s - not considered as an error",
845 nt_errstr(r.out.result));
847 return true;
850 torture_assert_ntstatus_ok(tctx,
851 r.out.result,
852 "LookupNames4 failed");
854 if (check_result) {
855 torture_assert_int_equal(tctx, count, sids.count,
856 "unexpected number of results returned");
857 if (sids.count > 0) {
858 torture_assert(tctx, sids.sids, "invalid sid buffer");
862 torture_comment(tctx, "\n");
864 return true;
867 static bool test_LookupNames4_fail(struct dcerpc_binding_handle *b,
868 struct torture_context *tctx,
869 enum lsa_LookupNamesLevel level)
871 struct lsa_LookupNames4 r;
872 struct lsa_TransSidArray3 sids;
873 struct lsa_RefDomainList *domains = NULL;
874 struct lsa_String *names = NULL;
875 uint32_t count = 0;
876 NTSTATUS status;
878 torture_comment(tctx, "\nTesting LookupNames4_fail");
880 sids.count = 0;
881 sids.sids = NULL;
883 r.in.num_names = 0;
885 r.in.num_names = count;
886 r.in.names = names;
887 r.in.sids = &sids;
888 r.in.level = level;
889 r.in.count = &count;
890 r.in.lookup_options = 0;
891 r.in.client_revision = 0;
892 r.out.count = &count;
893 r.out.sids = &sids;
894 r.out.domains = &domains;
896 status = dcerpc_lsa_LookupNames4_r(b, tctx, &r);
897 if (!NT_STATUS_IS_OK(status)) {
898 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) ||
899 NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_DISCONNECTED)) {
900 torture_comment(tctx,
901 "LookupNames4 correctly returned with "
902 "status: %s\n",
903 nt_errstr(status));
904 return true;
907 torture_assert_ntstatus_equal(tctx,
908 status,
909 NT_STATUS_ACCESS_DENIED,
910 "LookupNames4 return value should "
911 "be ACCESS_DENIED");
912 return true;
915 if (!NT_STATUS_IS_OK(r.out.result)) {
916 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) ||
917 NT_STATUS_EQUAL(r.out.result, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
918 torture_comment(tctx,
919 "LookupSids3 correctly returned with "
920 "result: %s\n",
921 nt_errstr(r.out.result));
922 return true;
926 torture_fail(tctx,
927 "LookupNames4 return value should be "
928 "ACCESS_DENIED or RPC_PROTSEQ_NOT_SUPPORTED");
930 return false;
934 static bool test_LookupSids(struct dcerpc_binding_handle *b,
935 struct torture_context *tctx,
936 struct policy_handle *handle,
937 enum lsa_LookupNamesLevel level,
938 struct lsa_SidArray *sids)
940 struct lsa_LookupSids r;
941 struct lsa_TransNameArray names;
942 struct lsa_RefDomainList *domains = NULL;
943 uint32_t count = sids->num_sids;
945 torture_comment(tctx, "\nTesting LookupSids\n");
947 names.count = 0;
948 names.names = NULL;
950 r.in.handle = handle;
951 r.in.sids = sids;
952 r.in.names = &names;
953 r.in.level = level;
954 r.in.count = &count;
955 r.out.count = &count;
956 r.out.names = &names;
957 r.out.domains = &domains;
959 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupSids_r(b, tctx, &r),
960 "LookupSids failed");
961 if (!NT_STATUS_EQUAL(r.out.result, STATUS_SOME_UNMAPPED)) {
962 torture_assert_ntstatus_ok(tctx, r.out.result,
963 "LookupSids failed");
966 torture_comment(tctx, "\n");
968 if (!test_LookupNames(b, tctx, handle, level, &names)) {
969 return false;
972 return true;
976 static bool test_LookupSids2(struct dcerpc_binding_handle *b,
977 struct torture_context *tctx,
978 struct policy_handle *handle,
979 enum lsa_LookupNamesLevel level,
980 struct lsa_SidArray *sids)
982 struct lsa_LookupSids2 r;
983 struct lsa_TransNameArray2 names;
984 struct lsa_RefDomainList *domains = NULL;
985 uint32_t count = sids->num_sids;
987 torture_comment(tctx, "\nTesting LookupSids2\n");
989 names.count = 0;
990 names.names = NULL;
992 r.in.handle = handle;
993 r.in.sids = sids;
994 r.in.names = &names;
995 r.in.level = level;
996 r.in.count = &count;
997 r.in.lookup_options = 0;
998 r.in.client_revision = 0;
999 r.out.count = &count;
1000 r.out.names = &names;
1001 r.out.domains = &domains;
1003 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupSids2_r(b, tctx, &r),
1004 "LookupSids2 failed");
1005 if (!NT_STATUS_IS_OK(r.out.result) &&
1006 !NT_STATUS_EQUAL(r.out.result, STATUS_SOME_UNMAPPED)) {
1007 torture_comment(tctx, "LookupSids2 failed - %s\n",
1008 nt_errstr(r.out.result));
1009 return false;
1012 torture_comment(tctx, "\n");
1014 if (!test_LookupNames2(b, tctx, handle, level, &names, false)) {
1015 return false;
1018 if (!test_LookupNames3(b, tctx, handle, level, &names, false)) {
1019 return false;
1022 return true;
1025 static bool test_LookupSids3(struct dcerpc_binding_handle *b,
1026 struct torture_context *tctx,
1027 enum lsa_LookupNamesLevel level,
1028 struct lsa_SidArray *sids)
1030 struct lsa_LookupSids3 r;
1031 struct lsa_TransNameArray2 names;
1032 struct lsa_RefDomainList *domains = NULL;
1033 uint32_t count = sids->num_sids;
1035 torture_comment(tctx, "\nTesting LookupSids3\n");
1037 names.count = 0;
1038 names.names = NULL;
1040 r.in.sids = sids;
1041 r.in.names = &names;
1042 r.in.level = level;
1043 r.in.count = &count;
1044 r.in.lookup_options = 0;
1045 r.in.client_revision = 0;
1046 r.out.domains = &domains;
1047 r.out.count = &count;
1048 r.out.names = &names;
1050 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupSids3_r(b, tctx, &r),
1051 "LookupSids3 failed");
1053 if (!NT_STATUS_IS_OK(r.out.result)) {
1054 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NONE_MAPPED)) {
1055 torture_comment(tctx,
1056 "LookupSids3 failed: %s - not considered as an error",
1057 nt_errstr(r.out.result));
1059 return true;
1062 torture_assert_ntstatus_ok(tctx,
1063 r.out.result,
1064 "LookupSids3 failed");
1066 return false;
1069 torture_comment(tctx, "\n");
1071 if (!test_LookupNames4(b, tctx, level, &names, true)) {
1072 return false;
1075 return true;
1078 static bool test_LookupSids3_fail(struct dcerpc_binding_handle *b,
1079 struct torture_context *tctx,
1080 enum lsa_LookupNamesLevel level,
1081 struct lsa_SidArray *sids)
1083 struct lsa_LookupSids3 r;
1084 struct lsa_TransNameArray2 names;
1085 struct lsa_RefDomainList *domains = NULL;
1086 uint32_t count = sids->num_sids;
1087 NTSTATUS status;
1089 torture_comment(tctx, "\nTesting LookupSids3\n");
1091 names.count = 0;
1092 names.names = NULL;
1094 r.in.sids = sids;
1095 r.in.names = &names;
1096 r.in.level = level;
1097 r.in.count = &count;
1098 r.in.lookup_options = 0;
1099 r.in.client_revision = 0;
1100 r.out.domains = &domains;
1101 r.out.count = &count;
1102 r.out.names = &names;
1104 status = dcerpc_lsa_LookupSids3_r(b, tctx, &r);
1105 if (!NT_STATUS_IS_OK(status)) {
1106 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) ||
1107 NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_DISCONNECTED)) {
1108 torture_comment(tctx,
1109 "LookupSids3 correctly returned with "
1110 "status: %s\n",
1111 nt_errstr(status));
1112 return true;
1115 torture_assert_ntstatus_equal(tctx,
1116 status,
1117 NT_STATUS_ACCESS_DENIED,
1118 "LookupSids3 return value should "
1119 "be ACCESS_DENIED");
1120 return true;
1123 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) ||
1124 NT_STATUS_EQUAL(r.out.result, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
1125 torture_comment(tctx,
1126 "LookupSids3 correctly returned with "
1127 "result: %s\n",
1128 nt_errstr(r.out.result));
1129 return true;
1132 torture_fail(tctx,
1133 "LookupSids3 return value should be "
1134 "ACCESS_DENIED or RPC_PROTSEQ_NOT_SUPPORTED");
1136 return false;
1139 bool test_many_LookupSids(struct dcerpc_pipe *p,
1140 struct torture_context *tctx,
1141 struct policy_handle *handle,
1142 enum lsa_LookupNamesLevel level)
1144 uint32_t count;
1145 struct lsa_SidArray sids;
1146 int i;
1147 struct dcerpc_binding_handle *b = p->binding_handle;
1148 enum dcerpc_transport_t transport =
1149 dcerpc_binding_handle_get_transport(b);
1151 torture_comment(tctx, "\nTesting LookupSids with lots of SIDs\n");
1153 sids.num_sids = 100;
1155 sids.sids = talloc_array(tctx, struct lsa_SidPtr, sids.num_sids);
1157 for (i=0; i<sids.num_sids; i++) {
1158 const char *sidstr = "S-1-5-32-545";
1159 sids.sids[i].sid = dom_sid_parse_talloc(tctx, sidstr);
1162 count = sids.num_sids;
1164 if (handle) {
1165 struct lsa_LookupSids r;
1166 struct lsa_TransNameArray names;
1167 struct lsa_RefDomainList *domains = NULL;
1168 names.count = 0;
1169 names.names = NULL;
1171 r.in.handle = handle;
1172 r.in.sids = &sids;
1173 r.in.names = &names;
1174 r.in.level = level;
1175 r.in.count = &names.count;
1176 r.out.count = &count;
1177 r.out.names = &names;
1178 r.out.domains = &domains;
1180 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupSids_r(b, tctx, &r),
1181 "LookupSids failed");
1182 if (!NT_STATUS_IS_OK(r.out.result)) {
1183 torture_comment(tctx, "LookupSids failed - %s\n",
1184 nt_errstr(r.out.result));
1185 return false;
1188 torture_comment(tctx, "\n");
1190 if (!test_LookupNames(b, tctx, handle, level, &names)) {
1191 return false;
1195 if (transport == NCACN_NP) {
1196 if (!test_LookupSids3_fail(b, tctx, level, &sids)) {
1197 return false;
1199 if (!test_LookupNames4_fail(b, tctx, level)) {
1200 return false;
1202 } else if (transport == NCACN_IP_TCP) {
1203 struct lsa_TransNameArray2 names;
1204 enum dcerpc_AuthType auth_type;
1205 enum dcerpc_AuthLevel auth_level;
1207 names.count = 0;
1208 names.names = NULL;
1210 dcerpc_binding_handle_auth_info(p->binding_handle,
1211 &auth_type, &auth_level);
1213 if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL &&
1214 auth_level >= DCERPC_AUTH_LEVEL_INTEGRITY) {
1215 if (!test_LookupSids3(b, tctx, level, &sids)) {
1216 return false;
1218 if (!test_LookupNames4(b, tctx, level, &names, true)) {
1219 return false;
1221 } else if (auth_type == DCERPC_AUTH_TYPE_KRB5 &&
1222 auth_level == DCERPC_AUTH_LEVEL_PRIVACY)
1224 if (!test_LookupSids3(b, tctx, level, &sids)) {
1225 return false;
1227 if (!test_LookupNames4(b, tctx, level, &names, true)) {
1228 return false;
1230 } else {
1232 * If we don't have a secure channel these tests must
1233 * fail with ACCESS_DENIED.
1235 if (!test_LookupSids3_fail(b, tctx, level, &sids)) {
1236 return false;
1238 if (!test_LookupNames4_fail(b, tctx, level)) {
1239 return false;
1244 torture_comment(tctx, "\n");
1248 return true;
1251 static void lookupsids_cb(struct tevent_req *subreq)
1253 int *replies = (int *)tevent_req_callback_data_void(subreq);
1254 NTSTATUS status;
1256 status = dcerpc_lsa_LookupSids_r_recv(subreq, subreq);
1257 TALLOC_FREE(subreq);
1258 if (!NT_STATUS_IS_OK(status)) {
1259 printf("lookupsids returned %s\n", nt_errstr(status));
1260 *replies = -1;
1263 if (*replies >= 0) {
1264 *replies += 1;
1268 static bool test_LookupSids_async(struct dcerpc_binding_handle *b,
1269 struct torture_context *tctx,
1270 struct policy_handle *handle,
1271 enum lsa_LookupNamesLevel level)
1273 struct lsa_SidArray sids;
1274 struct lsa_SidPtr sidptr;
1275 uint32_t *count;
1276 struct lsa_TransNameArray *names;
1277 struct lsa_LookupSids *r;
1278 struct lsa_RefDomainList *domains = NULL;
1279 struct tevent_req **req;
1280 int i, replies;
1281 bool ret = true;
1282 const int num_async_requests = 50;
1284 count = talloc_array(tctx, uint32_t, num_async_requests);
1285 names = talloc_array(tctx, struct lsa_TransNameArray, num_async_requests);
1286 r = talloc_array(tctx, struct lsa_LookupSids, num_async_requests);
1288 torture_comment(tctx, "\nTesting %d async lookupsids request\n", num_async_requests);
1290 req = talloc_array(tctx, struct tevent_req *, num_async_requests);
1292 sids.num_sids = 1;
1293 sids.sids = &sidptr;
1294 sidptr.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-545");
1296 replies = 0;
1298 for (i=0; i<num_async_requests; i++) {
1299 count[i] = 0;
1300 names[i].count = 0;
1301 names[i].names = NULL;
1303 r[i].in.handle = handle;
1304 r[i].in.sids = &sids;
1305 r[i].in.names = &names[i];
1306 r[i].in.level = level;
1307 r[i].in.count = &names[i].count;
1308 r[i].out.count = &count[i];
1309 r[i].out.names = &names[i];
1310 r[i].out.domains = &domains;
1312 req[i] = dcerpc_lsa_LookupSids_r_send(tctx, tctx->ev, b, &r[i]);
1313 if (req[i] == NULL) {
1314 ret = false;
1315 break;
1318 tevent_req_set_callback(req[i], lookupsids_cb, &replies);
1321 while (replies >= 0 && replies < num_async_requests) {
1322 tevent_loop_once(tctx->ev);
1325 talloc_free(req);
1327 if (replies < 0) {
1328 ret = false;
1331 return ret;
1334 static bool test_LookupPrivValue(struct dcerpc_binding_handle *b,
1335 struct torture_context *tctx,
1336 struct policy_handle *handle,
1337 struct lsa_String *name)
1339 struct lsa_LookupPrivValue r;
1340 struct lsa_LUID luid;
1342 r.in.handle = handle;
1343 r.in.name = name;
1344 r.out.luid = &luid;
1346 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupPrivValue_r(b, tctx, &r),
1347 "LookupPrivValue failed");
1348 torture_assert_ntstatus_ok(tctx, r.out.result,
1349 "LookupPrivValue failed");
1351 return true;
1354 static bool test_LookupPrivName(struct dcerpc_binding_handle *b,
1355 struct torture_context *tctx,
1356 struct policy_handle *handle,
1357 struct lsa_LUID *luid)
1359 struct lsa_LookupPrivName r;
1360 struct lsa_StringLarge *name = NULL;
1362 r.in.handle = handle;
1363 r.in.luid = luid;
1364 r.out.name = &name;
1366 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupPrivName_r(b, tctx, &r),
1367 "LookupPrivName failed");
1368 torture_assert_ntstatus_ok(tctx, r.out.result, "LookupPrivName failed");
1370 return true;
1373 static bool test_RemovePrivilegesFromAccount(struct dcerpc_binding_handle *b,
1374 struct torture_context *tctx,
1375 struct policy_handle *handle,
1376 struct policy_handle *acct_handle,
1377 struct lsa_LUID *luid)
1379 struct lsa_RemovePrivilegesFromAccount r;
1380 struct lsa_PrivilegeSet privs;
1381 bool ret = true;
1383 torture_comment(tctx, "\nTesting RemovePrivilegesFromAccount\n");
1385 r.in.handle = acct_handle;
1386 r.in.remove_all = 0;
1387 r.in.privs = &privs;
1389 privs.count = 1;
1390 privs.unknown = 0;
1391 privs.set = talloc_array(tctx, struct lsa_LUIDAttribute, 1);
1392 privs.set[0].luid = *luid;
1393 privs.set[0].attribute = 0;
1395 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_RemovePrivilegesFromAccount_r(b, tctx, &r),
1396 "RemovePrivilegesFromAccount failed");
1397 if (!NT_STATUS_IS_OK(r.out.result)) {
1399 struct lsa_LookupPrivName r_name;
1400 struct lsa_StringLarge *name = NULL;
1402 r_name.in.handle = handle;
1403 r_name.in.luid = luid;
1404 r_name.out.name = &name;
1406 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupPrivName_r(b, tctx, &r_name),
1407 "LookupPrivName failed");
1408 if (!NT_STATUS_IS_OK(r_name.out.result)) {
1409 torture_comment(tctx, "\nLookupPrivName failed - %s\n",
1410 nt_errstr(r_name.out.result));
1411 return false;
1413 /* Windows 2008 does not allow this to be removed */
1414 if (strcmp("SeAuditPrivilege", name->string) == 0) {
1415 return ret;
1418 torture_comment(tctx, "RemovePrivilegesFromAccount failed to remove %s - %s\n",
1419 name->string,
1420 nt_errstr(r.out.result));
1421 return false;
1424 return ret;
1427 static bool test_AddPrivilegesToAccount(struct dcerpc_binding_handle *b,
1428 struct torture_context *tctx,
1429 struct policy_handle *acct_handle,
1430 struct lsa_LUID *luid)
1432 struct lsa_AddPrivilegesToAccount r;
1433 struct lsa_PrivilegeSet privs;
1434 bool ret = true;
1436 torture_comment(tctx, "\nTesting AddPrivilegesToAccount\n");
1438 r.in.handle = acct_handle;
1439 r.in.privs = &privs;
1441 privs.count = 1;
1442 privs.unknown = 0;
1443 privs.set = talloc_array(tctx, struct lsa_LUIDAttribute, 1);
1444 privs.set[0].luid = *luid;
1445 privs.set[0].attribute = 0;
1447 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_AddPrivilegesToAccount_r(b, tctx, &r),
1448 "AddPrivilegesToAccount failed");
1449 torture_assert_ntstatus_ok(tctx, r.out.result,
1450 "AddPrivilegesToAccount failed");
1451 return ret;
1454 static bool test_EnumPrivsAccount(struct dcerpc_binding_handle *b,
1455 struct torture_context *tctx,
1456 struct policy_handle *handle,
1457 struct policy_handle *acct_handle)
1459 struct lsa_EnumPrivsAccount r;
1460 struct lsa_PrivilegeSet *privs = NULL;
1461 bool ret = true;
1463 torture_comment(tctx, "\nTesting EnumPrivsAccount\n");
1465 r.in.handle = acct_handle;
1466 r.out.privs = &privs;
1468 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumPrivsAccount_r(b, tctx, &r),
1469 "EnumPrivsAccount failed");
1470 torture_assert_ntstatus_ok(tctx, r.out.result,
1471 "EnumPrivsAccount failed");
1473 if (privs && privs->count > 0) {
1474 int i;
1475 for (i=0;i<privs->count;i++) {
1476 test_LookupPrivName(b, tctx, handle,
1477 &privs->set[i].luid);
1480 ret &= test_RemovePrivilegesFromAccount(b, tctx, handle, acct_handle,
1481 &privs->set[0].luid);
1482 ret &= test_AddPrivilegesToAccount(b, tctx, acct_handle,
1483 &privs->set[0].luid);
1486 return ret;
1489 static bool test_GetSystemAccessAccount(struct dcerpc_binding_handle *b,
1490 struct torture_context *tctx,
1491 struct policy_handle *handle,
1492 struct policy_handle *acct_handle)
1494 uint32_t access_mask;
1495 struct lsa_GetSystemAccessAccount r;
1497 torture_comment(tctx, "\nTesting GetSystemAccessAccount\n");
1499 r.in.handle = acct_handle;
1500 r.out.access_mask = &access_mask;
1502 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetSystemAccessAccount_r(b, tctx, &r),
1503 "GetSystemAccessAccount failed");
1504 torture_assert_ntstatus_ok(tctx, r.out.result,
1505 "GetSystemAccessAccount failed");
1507 if (r.out.access_mask != NULL) {
1508 torture_comment(tctx, "Rights:");
1509 if (*(r.out.access_mask) & LSA_POLICY_MODE_INTERACTIVE)
1510 torture_comment(tctx, " LSA_POLICY_MODE_INTERACTIVE");
1511 if (*(r.out.access_mask) & LSA_POLICY_MODE_NETWORK)
1512 torture_comment(tctx, " LSA_POLICY_MODE_NETWORK");
1513 if (*(r.out.access_mask) & LSA_POLICY_MODE_BATCH)
1514 torture_comment(tctx, " LSA_POLICY_MODE_BATCH");
1515 if (*(r.out.access_mask) & LSA_POLICY_MODE_SERVICE)
1516 torture_comment(tctx, " LSA_POLICY_MODE_SERVICE");
1517 if (*(r.out.access_mask) & LSA_POLICY_MODE_PROXY)
1518 torture_comment(tctx, " LSA_POLICY_MODE_PROXY");
1519 if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_INTERACTIVE)
1520 torture_comment(tctx, " LSA_POLICY_MODE_DENY_INTERACTIVE");
1521 if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_NETWORK)
1522 torture_comment(tctx, " LSA_POLICY_MODE_DENY_NETWORK");
1523 if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_BATCH)
1524 torture_comment(tctx, " LSA_POLICY_MODE_DENY_BATCH");
1525 if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_SERVICE)
1526 torture_comment(tctx, " LSA_POLICY_MODE_DENY_SERVICE");
1527 if (*(r.out.access_mask) & LSA_POLICY_MODE_REMOTE_INTERACTIVE)
1528 torture_comment(tctx, " LSA_POLICY_MODE_REMOTE_INTERACTIVE");
1529 if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_REMOTE_INTERACTIVE)
1530 torture_comment(tctx, " LSA_POLICY_MODE_DENY_REMOTE_INTERACTIVE");
1531 if (*(r.out.access_mask) & LSA_POLICY_MODE_ALL)
1532 torture_comment(tctx, " LSA_POLICY_MODE_ALL");
1533 if (*(r.out.access_mask) & LSA_POLICY_MODE_ALL_NT4)
1534 torture_comment(tctx, " LSA_POLICY_MODE_ALL_NT4");
1535 torture_comment(tctx, "\n");
1538 return true;
1541 static bool test_Delete(struct dcerpc_binding_handle *b,
1542 struct torture_context *tctx,
1543 struct policy_handle *handle)
1545 struct lsa_Delete r;
1547 torture_comment(tctx, "\nTesting Delete\n");
1549 r.in.handle = handle;
1550 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Delete_r(b, tctx, &r),
1551 "Delete failed");
1552 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_SUPPORTED,
1553 "Delete should have failed NT_STATUS_NOT_SUPPORTED");
1555 return true;
1558 static bool test_DeleteObject(struct dcerpc_binding_handle *b,
1559 struct torture_context *tctx,
1560 struct policy_handle *handle)
1562 struct lsa_DeleteObject r;
1564 torture_comment(tctx, "\nTesting DeleteObject\n");
1566 r.in.handle = handle;
1567 r.out.handle = handle;
1568 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_DeleteObject_r(b, tctx, &r),
1569 "DeleteObject failed");
1570 torture_assert_ntstatus_ok(tctx, r.out.result,
1571 "DeleteObject failed");
1573 return true;
1577 static bool test_CreateAccount(struct dcerpc_binding_handle *b,
1578 struct torture_context *tctx,
1579 struct policy_handle *handle)
1581 struct lsa_CreateAccount r;
1582 struct dom_sid2 *newsid;
1583 struct policy_handle acct_handle;
1585 newsid = dom_sid_parse_talloc(tctx, "S-1-5-12349876-4321-2854");
1587 torture_comment(tctx, "\nTesting CreateAccount\n");
1589 r.in.handle = handle;
1590 r.in.sid = newsid;
1591 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1592 r.out.acct_handle = &acct_handle;
1594 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CreateAccount_r(b, tctx, &r),
1595 "CreateAccount failed");
1596 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_OBJECT_NAME_COLLISION)) {
1597 struct lsa_OpenAccount r_o;
1598 r_o.in.handle = handle;
1599 r_o.in.sid = newsid;
1600 r_o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1601 r_o.out.acct_handle = &acct_handle;
1603 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(b, tctx, &r_o),
1604 "OpenAccount failed");
1605 torture_assert_ntstatus_ok(tctx, r_o.out.result,
1606 "OpenAccount failed");
1607 } else {
1608 torture_assert_ntstatus_ok(tctx, r.out.result,
1609 "CreateAccount failed");
1612 if (!test_Delete(b, tctx, &acct_handle)) {
1613 return false;
1616 if (!test_DeleteObject(b, tctx, &acct_handle)) {
1617 return false;
1620 return true;
1623 static bool test_DeleteTrustedDomain(struct dcerpc_binding_handle *b,
1624 struct torture_context *tctx,
1625 struct policy_handle *handle,
1626 struct lsa_StringLarge name)
1628 struct lsa_OpenTrustedDomainByName r;
1629 struct policy_handle trustdom_handle;
1631 r.in.handle = handle;
1632 r.in.name.string = name.string;
1633 r.in.access_mask = SEC_STD_DELETE;
1634 r.out.trustdom_handle = &trustdom_handle;
1636 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenTrustedDomainByName_r(b, tctx, &r),
1637 "OpenTrustedDomainByName failed");
1638 torture_assert_ntstatus_ok(tctx, r.out.result,
1639 "OpenTrustedDomainByName failed");
1641 if (!test_Delete(b, tctx, &trustdom_handle)) {
1642 return false;
1645 if (!test_DeleteObject(b, tctx, &trustdom_handle)) {
1646 return false;
1649 return true;
1652 static bool test_DeleteTrustedDomainBySid(struct dcerpc_binding_handle *b,
1653 struct torture_context *tctx,
1654 struct policy_handle *handle,
1655 struct dom_sid *sid)
1657 struct lsa_DeleteTrustedDomain r;
1659 r.in.handle = handle;
1660 r.in.dom_sid = sid;
1662 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_DeleteTrustedDomain_r(b, tctx, &r),
1663 "DeleteTrustedDomain failed");
1664 torture_assert_ntstatus_ok(tctx, r.out.result,
1665 "DeleteTrustedDomain failed");
1667 return true;
1671 static bool test_CreateSecret(struct dcerpc_pipe *p,
1672 struct torture_context *tctx,
1673 struct policy_handle *handle)
1675 struct lsa_CreateSecret r;
1676 struct lsa_OpenSecret r2;
1677 struct lsa_SetSecret r3;
1678 struct lsa_QuerySecret r4;
1679 struct lsa_SetSecret r5;
1680 struct lsa_QuerySecret r6;
1681 struct lsa_SetSecret r7;
1682 struct lsa_QuerySecret r8;
1683 struct policy_handle sec_handle, sec_handle2, sec_handle3;
1684 struct lsa_DeleteObject d_o;
1685 struct lsa_DATA_BUF buf1;
1686 struct lsa_DATA_BUF_PTR bufp1;
1687 struct lsa_DATA_BUF_PTR bufp2;
1688 DATA_BLOB enc_key;
1689 bool ret = true;
1690 DATA_BLOB session_key;
1691 NTTIME old_mtime, new_mtime;
1692 DATA_BLOB blob1;
1693 const char *secret1 = "abcdef12345699qwerty";
1694 char *secret2;
1695 const char *secret3 = "ABCDEF12345699QWERTY";
1696 char *secret4;
1697 const char *secret5 = "NEW-SAMBA4-SECRET";
1698 char *secret6;
1699 char *secname[2];
1700 int i;
1701 const int LOCAL = 0;
1702 const int GLOBAL = 1;
1703 struct dcerpc_binding_handle *b = p->binding_handle;
1705 secname[LOCAL] = talloc_asprintf(tctx, "torturesecret-%u", (unsigned int)random());
1706 secname[GLOBAL] = talloc_asprintf(tctx, "G$torturesecret-%u", (unsigned int)random());
1708 for (i=0; i< 2; i++) {
1709 torture_comment(tctx, "\nTesting CreateSecret of %s\n", secname[i]);
1711 init_lsa_String(&r.in.name, secname[i]);
1713 r.in.handle = handle;
1714 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1715 r.out.sec_handle = &sec_handle;
1717 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CreateSecret_r(b, tctx, &r),
1718 "CreateSecret failed");
1719 torture_assert_ntstatus_ok(tctx, r.out.result,
1720 "CreateSecret failed");
1722 r.in.handle = handle;
1723 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1724 r.out.sec_handle = &sec_handle3;
1726 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CreateSecret_r(b, tctx, &r),
1727 "CreateSecret failed");
1728 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_COLLISION,
1729 "CreateSecret should have failed OBJECT_NAME_COLLISION");
1731 r2.in.handle = handle;
1732 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1733 r2.in.name = r.in.name;
1734 r2.out.sec_handle = &sec_handle2;
1736 torture_comment(tctx, "Testing OpenSecret\n");
1738 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenSecret_r(b, tctx, &r2),
1739 "OpenSecret failed");
1740 torture_assert_ntstatus_ok(tctx, r2.out.result,
1741 "OpenSecret failed");
1743 torture_assert_ntstatus_ok(tctx,
1744 dcerpc_binding_handle_transport_session_key(b, tctx, &session_key),
1745 "transport_session_key failed");
1747 enc_key = sess_encrypt_string(secret1, &session_key);
1749 r3.in.sec_handle = &sec_handle;
1750 r3.in.new_val = &buf1;
1751 r3.in.old_val = NULL;
1752 r3.in.new_val->data = enc_key.data;
1753 r3.in.new_val->length = enc_key.length;
1754 r3.in.new_val->size = enc_key.length;
1756 torture_comment(tctx, "Testing SetSecret\n");
1758 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_SetSecret_r(b, tctx, &r3),
1759 "SetSecret failed");
1760 torture_assert_ntstatus_ok(tctx, r3.out.result,
1761 "SetSecret failed");
1763 r3.in.sec_handle = &sec_handle;
1764 r3.in.new_val = &buf1;
1765 r3.in.old_val = NULL;
1766 r3.in.new_val->data = enc_key.data;
1767 r3.in.new_val->length = enc_key.length;
1768 r3.in.new_val->size = enc_key.length;
1770 /* break the encrypted data */
1771 enc_key.data[0]++;
1773 torture_comment(tctx, "Testing SetSecret with broken key\n");
1775 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_SetSecret_r(b, tctx, &r3),
1776 "SetSecret failed");
1777 torture_assert_ntstatus_equal(tctx, r3.out.result, NT_STATUS_UNKNOWN_REVISION,
1778 "SetSecret should have failed UNKNOWN_REVISION");
1780 data_blob_free(&enc_key);
1782 ZERO_STRUCT(new_mtime);
1783 ZERO_STRUCT(old_mtime);
1785 /* fetch the secret back again */
1786 r4.in.sec_handle = &sec_handle;
1787 r4.in.new_val = &bufp1;
1788 r4.in.new_mtime = &new_mtime;
1789 r4.in.old_val = NULL;
1790 r4.in.old_mtime = NULL;
1792 bufp1.buf = NULL;
1794 torture_comment(tctx, "Testing QuerySecret\n");
1795 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QuerySecret_r(b, tctx, &r4),
1796 "QuerySecret failed");
1797 if (!NT_STATUS_IS_OK(r4.out.result)) {
1798 torture_comment(tctx, "QuerySecret failed - %s\n", nt_errstr(r4.out.result));
1799 ret = false;
1800 } else {
1801 if (r4.out.new_val == NULL || r4.out.new_val->buf == NULL) {
1802 torture_comment(tctx, "No secret buffer returned\n");
1803 ret = false;
1804 } else {
1805 blob1.data = r4.out.new_val->buf->data;
1806 blob1.length = r4.out.new_val->buf->size;
1808 secret2 = sess_decrypt_string(tctx,
1809 &blob1, &session_key);
1811 if (strcmp(secret1, secret2) != 0) {
1812 torture_comment(tctx, "Returned secret (r4) '%s' doesn't match '%s'\n",
1813 secret2, secret1);
1814 ret = false;
1819 enc_key = sess_encrypt_string(secret3, &session_key);
1821 r5.in.sec_handle = &sec_handle;
1822 r5.in.new_val = &buf1;
1823 r5.in.old_val = NULL;
1824 r5.in.new_val->data = enc_key.data;
1825 r5.in.new_val->length = enc_key.length;
1826 r5.in.new_val->size = enc_key.length;
1829 smb_msleep(200);
1830 torture_comment(tctx, "Testing SetSecret (existing value should move to old)\n");
1832 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_SetSecret_r(b, tctx, &r5),
1833 "SetSecret failed");
1834 if (!NT_STATUS_IS_OK(r5.out.result)) {
1835 torture_comment(tctx, "SetSecret failed - %s\n", nt_errstr(r5.out.result));
1836 ret = false;
1839 data_blob_free(&enc_key);
1841 ZERO_STRUCT(new_mtime);
1842 ZERO_STRUCT(old_mtime);
1844 /* fetch the secret back again */
1845 r6.in.sec_handle = &sec_handle;
1846 r6.in.new_val = &bufp1;
1847 r6.in.new_mtime = &new_mtime;
1848 r6.in.old_val = &bufp2;
1849 r6.in.old_mtime = &old_mtime;
1851 bufp1.buf = NULL;
1852 bufp2.buf = NULL;
1854 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QuerySecret_r(b, tctx, &r6),
1855 "QuerySecret failed");
1856 if (!NT_STATUS_IS_OK(r6.out.result)) {
1857 torture_comment(tctx, "QuerySecret failed - %s\n", nt_errstr(r6.out.result));
1858 ret = false;
1859 secret4 = NULL;
1860 } else {
1862 if (r6.out.new_val->buf == NULL || r6.out.old_val->buf == NULL
1863 || r6.out.new_mtime == NULL || r6.out.old_mtime == NULL) {
1864 torture_comment(tctx, "Both secret buffers and both times not returned\n");
1865 ret = false;
1866 secret4 = NULL;
1867 } else {
1868 blob1.data = r6.out.new_val->buf->data;
1869 blob1.length = r6.out.new_val->buf->size;
1871 secret4 = sess_decrypt_string(tctx,
1872 &blob1, &session_key);
1874 if (strcmp(secret3, secret4) != 0) {
1875 torture_comment(tctx, "Returned NEW secret %s doesn't match %s\n", secret4, secret3);
1876 ret = false;
1879 blob1.data = r6.out.old_val->buf->data;
1880 blob1.length = r6.out.old_val->buf->length;
1882 secret2 = sess_decrypt_string(tctx,
1883 &blob1, &session_key);
1885 if (strcmp(secret1, secret2) != 0) {
1886 torture_comment(tctx, "Returned OLD secret %s doesn't match %s\n", secret2, secret1);
1887 ret = false;
1890 if (*r6.out.new_mtime == *r6.out.old_mtime) {
1891 torture_comment(tctx, "Returned secret (r6-%d) %s must not have same mtime for both secrets: %s != %s\n",
1893 secname[i],
1894 nt_time_string(tctx, *r6.out.old_mtime),
1895 nt_time_string(tctx, *r6.out.new_mtime));
1896 ret = false;
1901 enc_key = sess_encrypt_string(secret5, &session_key);
1903 r7.in.sec_handle = &sec_handle;
1904 r7.in.old_val = &buf1;
1905 r7.in.old_val->data = enc_key.data;
1906 r7.in.old_val->length = enc_key.length;
1907 r7.in.old_val->size = enc_key.length;
1908 r7.in.new_val = NULL;
1910 torture_comment(tctx, "Testing SetSecret of old Secret only\n");
1912 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_SetSecret_r(b, tctx, &r7),
1913 "SetSecret failed");
1914 if (!NT_STATUS_IS_OK(r7.out.result)) {
1915 torture_comment(tctx, "SetSecret failed - %s\n", nt_errstr(r7.out.result));
1916 ret = false;
1919 data_blob_free(&enc_key);
1921 /* fetch the secret back again */
1922 r8.in.sec_handle = &sec_handle;
1923 r8.in.new_val = &bufp1;
1924 r8.in.new_mtime = &new_mtime;
1925 r8.in.old_val = &bufp2;
1926 r8.in.old_mtime = &old_mtime;
1928 bufp1.buf = NULL;
1929 bufp2.buf = NULL;
1931 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QuerySecret_r(b, tctx, &r8),
1932 "QuerySecret failed");
1933 if (!NT_STATUS_IS_OK(r8.out.result)) {
1934 torture_comment(tctx, "QuerySecret failed - %s\n", nt_errstr(r8.out.result));
1935 ret = false;
1936 } else {
1937 if (!r8.out.new_val || !r8.out.old_val) {
1938 torture_comment(tctx, "in/out pointers not returned, despite being set on in for QuerySecret\n");
1939 ret = false;
1940 } else if (r8.out.new_val->buf != NULL) {
1941 torture_comment(tctx, "NEW secret buffer must not be returned after OLD set\n");
1942 ret = false;
1943 } else if (r8.out.old_val->buf == NULL) {
1944 torture_comment(tctx, "OLD secret buffer was not returned after OLD set\n");
1945 ret = false;
1946 } else if (r8.out.new_mtime == NULL || r8.out.old_mtime == NULL) {
1947 torture_comment(tctx, "Both times not returned after OLD set\n");
1948 ret = false;
1949 } else {
1950 blob1.data = r8.out.old_val->buf->data;
1951 blob1.length = r8.out.old_val->buf->size;
1953 secret6 = sess_decrypt_string(tctx,
1954 &blob1, &session_key);
1956 if (strcmp(secret5, secret6) != 0) {
1957 torture_comment(tctx, "Returned OLD secret %s doesn't match %s\n", secret5, secret6);
1958 ret = false;
1961 if (*r8.out.new_mtime != *r8.out.old_mtime) {
1962 torture_comment(tctx, "Returned secret (r8) %s did not had same mtime for both secrets: %s != %s\n",
1963 secname[i],
1964 nt_time_string(tctx, *r8.out.old_mtime),
1965 nt_time_string(tctx, *r8.out.new_mtime));
1966 ret = false;
1971 if (!test_Delete(b, tctx, &sec_handle)) {
1972 ret = false;
1975 if (!test_DeleteObject(b, tctx, &sec_handle)) {
1976 return false;
1979 d_o.in.handle = &sec_handle2;
1980 d_o.out.handle = &sec_handle2;
1981 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_DeleteObject_r(b, tctx, &d_o),
1982 "DeleteObject failed");
1983 torture_assert_ntstatus_equal(tctx, d_o.out.result, NT_STATUS_INVALID_HANDLE,
1984 "OpenSecret expected INVALID_HANDLE");
1986 torture_comment(tctx, "Testing OpenSecret of just-deleted secret\n");
1988 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenSecret_r(b, tctx, &r2),
1989 "OpenSecret failed");
1990 torture_assert_ntstatus_equal(tctx, r2.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND,
1991 "OpenSecret expected OBJECT_NAME_NOT_FOUND");
1993 return ret;
1997 static bool test_EnumAccountRights(struct dcerpc_binding_handle *b,
1998 struct torture_context *tctx,
1999 struct policy_handle *acct_handle,
2000 struct dom_sid *sid)
2002 struct lsa_EnumAccountRights r;
2003 struct lsa_RightSet rights;
2005 torture_comment(tctx, "\nTesting EnumAccountRights\n");
2007 r.in.handle = acct_handle;
2008 r.in.sid = sid;
2009 r.out.rights = &rights;
2011 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(b, tctx, &r),
2012 "EnumAccountRights failed");
2013 if (!NT_STATUS_IS_OK(r.out.result)) {
2014 torture_comment(tctx, "EnumAccountRights of %s failed - %s\n",
2015 dom_sid_string(tctx, sid), nt_errstr(r.out.result));
2017 torture_assert_ntstatus_ok(tctx, r.out.result,
2018 "EnumAccountRights failed");
2020 return true;
2024 static bool test_QuerySecurity(struct dcerpc_binding_handle *b,
2025 struct torture_context *tctx,
2026 struct policy_handle *handle,
2027 struct policy_handle *acct_handle)
2029 struct lsa_QuerySecurity r;
2030 struct sec_desc_buf *sdbuf = NULL;
2032 if (torture_setting_bool(tctx, "samba4", false)) {
2033 torture_comment(tctx, "\nskipping QuerySecurity test against Samba4\n");
2034 return true;
2037 torture_comment(tctx, "\nTesting QuerySecurity\n");
2039 r.in.handle = acct_handle;
2040 r.in.sec_info = SECINFO_OWNER |
2041 SECINFO_GROUP |
2042 SECINFO_DACL;
2043 r.out.sdbuf = &sdbuf;
2045 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QuerySecurity_r(b, tctx, &r),
2046 "QuerySecurity failed");
2047 if (!NT_STATUS_IS_OK(r.out.result)) {
2048 torture_comment(tctx, "QuerySecurity failed - %s\n", nt_errstr(r.out.result));
2049 return false;
2052 return true;
2055 static bool test_OpenAccount(struct dcerpc_binding_handle *b,
2056 struct torture_context *tctx,
2057 struct policy_handle *handle,
2058 struct dom_sid *sid)
2060 struct lsa_OpenAccount r;
2061 struct policy_handle acct_handle;
2063 torture_comment(tctx, "\nTesting OpenAccount\n");
2065 r.in.handle = handle;
2066 r.in.sid = sid;
2067 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2068 r.out.acct_handle = &acct_handle;
2070 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(b, tctx, &r),
2071 "OpenAccount failed");
2072 torture_assert_ntstatus_ok(tctx, r.out.result,
2073 "OpenAccount failed");
2075 if (!test_EnumPrivsAccount(b, tctx, handle, &acct_handle)) {
2076 return false;
2079 if (!test_GetSystemAccessAccount(b, tctx, handle, &acct_handle)) {
2080 return false;
2083 if (!test_QuerySecurity(b, tctx, handle, &acct_handle)) {
2084 return false;
2087 return true;
2090 static bool test_EnumAccounts(struct dcerpc_binding_handle *b,
2091 struct torture_context *tctx,
2092 struct policy_handle *handle)
2094 struct lsa_EnumAccounts r;
2095 struct lsa_SidArray sids1, sids2;
2096 uint32_t resume_handle = 0;
2097 int i;
2098 bool ret = true;
2100 torture_comment(tctx, "\nTesting EnumAccounts\n");
2102 r.in.handle = handle;
2103 r.in.resume_handle = &resume_handle;
2104 r.in.num_entries = 100;
2105 r.out.resume_handle = &resume_handle;
2106 r.out.sids = &sids1;
2108 resume_handle = 0;
2109 while (true) {
2110 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(b, tctx, &r),
2111 "EnumAccounts failed");
2112 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES)) {
2113 break;
2115 torture_assert_ntstatus_ok(tctx, r.out.result,
2116 "EnumAccounts failed");
2118 if (!test_LookupSids(b, tctx, handle, LSA_LOOKUP_NAMES_ALL, &sids1)) {
2119 return false;
2122 if (!test_LookupSids2(b, tctx, handle, LSA_LOOKUP_NAMES_ALL, &sids1)) {
2123 return false;
2126 /* Can't test lookupSids3 here, as clearly we must not
2127 * be on schannel, or we would not be able to do the
2128 * rest */
2130 torture_comment(tctx, "Testing all accounts\n");
2131 for (i=0;i<sids1.num_sids;i++) {
2132 ret &= test_OpenAccount(b, tctx, handle, sids1.sids[i].sid);
2133 ret &= test_EnumAccountRights(b, tctx, handle, sids1.sids[i].sid);
2135 torture_comment(tctx, "\n");
2138 if (sids1.num_sids < 3) {
2139 return ret;
2142 torture_comment(tctx, "Trying EnumAccounts partial listing (asking for 1 at 2)\n");
2143 resume_handle = 2;
2144 r.in.num_entries = 1;
2145 r.out.sids = &sids2;
2147 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(b, tctx, &r),
2148 "EnumAccounts failed");
2149 torture_assert_ntstatus_ok(tctx, r.out.result,
2150 "EnumAccounts failed");
2152 if (sids2.num_sids != 1) {
2153 torture_comment(tctx, "Returned wrong number of entries (%d)\n", sids2.num_sids);
2154 return false;
2157 return true;
2160 static bool test_LookupPrivDisplayName(struct dcerpc_binding_handle *b,
2161 struct torture_context *tctx,
2162 struct policy_handle *handle,
2163 struct lsa_String *priv_name)
2165 struct lsa_LookupPrivDisplayName r;
2166 /* produce a reasonable range of language output without screwing up
2167 terminals */
2168 uint16_t language_id = (random() % 4) + 0x409;
2169 uint16_t returned_language_id = 0;
2170 struct lsa_StringLarge *disp_name = NULL;
2172 torture_comment(tctx, "\nTesting LookupPrivDisplayName(%s)\n", priv_name->string);
2174 r.in.handle = handle;
2175 r.in.name = priv_name;
2176 r.in.language_id = language_id;
2177 r.in.language_id_sys = 0;
2178 r.out.returned_language_id = &returned_language_id;
2179 r.out.disp_name = &disp_name;
2181 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupPrivDisplayName_r(b, tctx, &r),
2182 "LookupPrivDisplayName failed");
2183 if (!NT_STATUS_IS_OK(r.out.result)) {
2184 torture_comment(tctx, "LookupPrivDisplayName failed - %s\n", nt_errstr(r.out.result));
2185 return false;
2187 torture_comment(tctx, "%s -> \"%s\" (language 0x%x/0x%x)\n",
2188 priv_name->string, disp_name->string,
2189 r.in.language_id, *r.out.returned_language_id);
2191 return true;
2194 static bool test_EnumAccountsWithUserRight(struct dcerpc_binding_handle *b,
2195 struct torture_context *tctx,
2196 struct policy_handle *handle,
2197 struct lsa_String *priv_name)
2199 struct lsa_EnumAccountsWithUserRight r;
2200 struct lsa_SidArray sids;
2202 ZERO_STRUCT(sids);
2204 torture_comment(tctx, "\nTesting EnumAccountsWithUserRight(%s)\n", priv_name->string);
2206 r.in.handle = handle;
2207 r.in.name = priv_name;
2208 r.out.sids = &sids;
2210 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountsWithUserRight_r(b, tctx, &r),
2211 "EnumAccountsWithUserRight failed");
2213 /* NT_STATUS_NO_MORE_ENTRIES means no one has this privilege */
2214 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES)) {
2215 return true;
2218 if (!NT_STATUS_IS_OK(r.out.result)) {
2219 torture_comment(tctx, "EnumAccountsWithUserRight failed - %s\n", nt_errstr(r.out.result));
2220 return false;
2223 return true;
2227 static bool test_EnumPrivs(struct dcerpc_binding_handle *b,
2228 struct torture_context *tctx,
2229 struct policy_handle *handle)
2231 struct lsa_EnumPrivs r;
2232 struct lsa_PrivArray privs1;
2233 uint32_t resume_handle = 0;
2234 int i;
2235 bool ret = true;
2237 torture_comment(tctx, "\nTesting EnumPrivs\n");
2239 r.in.handle = handle;
2240 r.in.resume_handle = &resume_handle;
2241 r.in.max_count = 100;
2242 r.out.resume_handle = &resume_handle;
2243 r.out.privs = &privs1;
2245 resume_handle = 0;
2246 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumPrivs_r(b, tctx, &r),
2247 "EnumPrivs failed");
2248 torture_assert_ntstatus_ok(tctx, r.out.result,
2249 "EnumPrivs failed");
2251 for (i = 0; i< privs1.count; i++) {
2252 test_LookupPrivDisplayName(b, tctx, handle, (struct lsa_String *)&privs1.privs[i].name);
2253 test_LookupPrivValue(b, tctx, handle, (struct lsa_String *)&privs1.privs[i].name);
2254 if (!test_EnumAccountsWithUserRight(b, tctx, handle, (struct lsa_String *)&privs1.privs[i].name)) {
2255 ret = false;
2259 return ret;
2262 static bool test_QueryForestTrustInformation(struct dcerpc_binding_handle *b,
2263 struct torture_context *tctx,
2264 struct policy_handle *handle,
2265 const char *trusted_domain_name)
2267 bool ret = true;
2268 struct lsa_lsaRQueryForestTrustInformation r;
2269 struct lsa_String string;
2270 struct lsa_ForestTrustInformation info, *info_ptr;
2272 torture_comment(tctx, "\nTesting lsaRQueryForestTrustInformation\n");
2274 if (torture_setting_bool(tctx, "samba4", false)) {
2275 torture_comment(tctx, "skipping QueryForestTrustInformation against Samba4\n");
2276 return true;
2279 ZERO_STRUCT(string);
2281 if (trusted_domain_name) {
2282 init_lsa_String(&string, trusted_domain_name);
2285 info_ptr = &info;
2287 r.in.handle = handle;
2288 r.in.trusted_domain_name = &string;
2289 r.in.highest_record_type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
2290 r.out.forest_trust_info = &info_ptr;
2292 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_lsaRQueryForestTrustInformation_r(b, tctx, &r),
2293 "lsaRQueryForestTrustInformation failed");
2295 if (!NT_STATUS_IS_OK(r.out.result)) {
2296 torture_comment(tctx, "lsaRQueryForestTrustInformation of %s failed - %s\n", trusted_domain_name, nt_errstr(r.out.result));
2297 ret = false;
2300 return ret;
2303 static bool test_query_each_TrustDomEx(struct dcerpc_binding_handle *b,
2304 struct torture_context *tctx,
2305 struct policy_handle *handle,
2306 struct lsa_DomainListEx *domains)
2308 int i;
2309 bool ret = true;
2311 for (i=0; i< domains->count; i++) {
2313 if (domains->domains[i].trust_attributes & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
2314 ret &= test_QueryForestTrustInformation(b, tctx, handle,
2315 domains->domains[i].domain_name.string);
2319 return ret;
2322 static bool test_query_each_TrustDom(struct dcerpc_binding_handle *b,
2323 struct torture_context *tctx,
2324 struct policy_handle *handle,
2325 struct lsa_DomainList *domains)
2327 int i,j;
2328 bool ret = true;
2330 torture_comment(tctx, "\nTesting OpenTrustedDomain, OpenTrustedDomainByName and QueryInfoTrustedDomain\n");
2331 for (i=0; i< domains->count; i++) {
2332 struct lsa_OpenTrustedDomain trust;
2333 struct lsa_OpenTrustedDomainByName trust_by_name;
2334 struct policy_handle trustdom_handle;
2335 struct policy_handle handle2;
2336 struct lsa_Close c;
2337 struct lsa_CloseTrustedDomainEx c_trust;
2338 int levels [] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
2339 int ok[] = {1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1};
2341 if (domains->domains[i].sid) {
2342 trust.in.handle = handle;
2343 trust.in.sid = domains->domains[i].sid;
2344 trust.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2345 trust.out.trustdom_handle = &trustdom_handle;
2347 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenTrustedDomain_r(b, tctx, &trust),
2348 "OpenTrustedDomain failed");
2350 if (NT_STATUS_EQUAL(trust.out.result, NT_STATUS_NO_SUCH_DOMAIN)) {
2351 torture_comment(tctx, "DOMAIN(%s, %s) not a direct trust?\n",
2352 domains->domains[i].name.string,
2353 dom_sid_string(tctx, domains->domains[i].sid));
2354 continue;
2356 if (!NT_STATUS_IS_OK(trust.out.result)) {
2357 torture_comment(tctx, "OpenTrustedDomain failed - %s\n", nt_errstr(trust.out.result));
2358 return false;
2361 c.in.handle = &trustdom_handle;
2362 c.out.handle = &handle2;
2364 c_trust.in.handle = &trustdom_handle;
2365 c_trust.out.handle = &handle2;
2367 for (j=0; j < ARRAY_SIZE(levels); j++) {
2368 struct lsa_QueryTrustedDomainInfo q;
2369 union lsa_TrustedDomainInfo *info = NULL;
2370 q.in.trustdom_handle = &trustdom_handle;
2371 q.in.level = levels[j];
2372 q.out.info = &info;
2373 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfo_r(b, tctx, &q),
2374 "QueryTrustedDomainInfo failed");
2375 if (!NT_STATUS_IS_OK(q.out.result) && ok[j]) {
2376 torture_comment(tctx, "QueryTrustedDomainInfo level %d failed - %s\n",
2377 levels[j], nt_errstr(q.out.result));
2378 ret = false;
2379 } else if (NT_STATUS_IS_OK(q.out.result) && !ok[j]) {
2380 torture_comment(tctx, "QueryTrustedDomainInfo level %d unexpectedly succeeded - %s\n",
2381 levels[j], nt_errstr(q.out.result));
2382 ret = false;
2386 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CloseTrustedDomainEx_r(b, tctx, &c_trust),
2387 "CloseTrustedDomainEx failed");
2388 if (!NT_STATUS_EQUAL(c_trust.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
2389 torture_comment(tctx, "Expected CloseTrustedDomainEx to return NT_STATUS_NOT_IMPLEMENTED, instead - %s\n", nt_errstr(c_trust.out.result));
2390 return false;
2393 c.in.handle = &trustdom_handle;
2394 c.out.handle = &handle2;
2396 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Close_r(b, tctx, &c),
2397 "Close failed");
2398 if (!NT_STATUS_IS_OK(c.out.result)) {
2399 torture_comment(tctx, "Close of trusted domain failed - %s\n", nt_errstr(c.out.result));
2400 return false;
2403 for (j=0; j < ARRAY_SIZE(levels); j++) {
2404 struct lsa_QueryTrustedDomainInfoBySid q;
2405 union lsa_TrustedDomainInfo *info = NULL;
2407 if (!domains->domains[i].sid) {
2408 continue;
2411 q.in.handle = handle;
2412 q.in.dom_sid = domains->domains[i].sid;
2413 q.in.level = levels[j];
2414 q.out.info = &info;
2416 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfoBySid_r(b, tctx, &q),
2417 "lsa_QueryTrustedDomainInfoBySid failed");
2418 if (!NT_STATUS_IS_OK(q.out.result) && ok[j]) {
2419 torture_comment(tctx, "QueryTrustedDomainInfoBySid level %d failed - %s\n",
2420 levels[j], nt_errstr(q.out.result));
2421 ret = false;
2422 } else if (NT_STATUS_IS_OK(q.out.result) && !ok[j]) {
2423 torture_comment(tctx, "QueryTrustedDomainInfoBySid level %d unexpectedly succeeded - %s\n",
2424 levels[j], nt_errstr(q.out.result));
2425 ret = false;
2430 trust_by_name.in.handle = handle;
2431 trust_by_name.in.name.string = domains->domains[i].name.string;
2432 trust_by_name.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2433 trust_by_name.out.trustdom_handle = &trustdom_handle;
2435 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenTrustedDomainByName_r(b, tctx, &trust_by_name),
2436 "OpenTrustedDomainByName failed");
2438 if (NT_STATUS_EQUAL(trust_by_name.out.result, NT_STATUS_NO_SUCH_DOMAIN)) {
2439 torture_comment(tctx, "DOMAIN(%s, %s) not a direct trust?\n",
2440 domains->domains[i].name.string,
2441 dom_sid_string(tctx, domains->domains[i].sid));
2442 continue;
2444 if (!NT_STATUS_IS_OK(trust_by_name.out.result)) {
2445 torture_comment(tctx, "OpenTrustedDomainByName failed - %s\n", nt_errstr(trust_by_name.out.result));
2446 return false;
2449 for (j=0; j < ARRAY_SIZE(levels); j++) {
2450 struct lsa_QueryTrustedDomainInfo q;
2451 union lsa_TrustedDomainInfo *info = NULL;
2452 q.in.trustdom_handle = &trustdom_handle;
2453 q.in.level = levels[j];
2454 q.out.info = &info;
2455 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfo_r(b, tctx, &q),
2456 "QueryTrustedDomainInfo failed");
2457 if (!NT_STATUS_IS_OK(q.out.result) && ok[j]) {
2458 torture_comment(tctx, "QueryTrustedDomainInfo level %d failed - %s\n",
2459 levels[j], nt_errstr(q.out.result));
2460 ret = false;
2461 } else if (NT_STATUS_IS_OK(q.out.result) && !ok[j]) {
2462 torture_comment(tctx, "QueryTrustedDomainInfo level %d unexpectedly succeeded - %s\n",
2463 levels[j], nt_errstr(q.out.result));
2464 ret = false;
2468 c.in.handle = &trustdom_handle;
2469 c.out.handle = &handle2;
2471 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Close_r(b, tctx, &c),
2472 "Close failed");
2473 if (!NT_STATUS_IS_OK(c.out.result)) {
2474 torture_comment(tctx, "Close of trusted domain failed - %s\n", nt_errstr(c.out.result));
2475 return false;
2478 for (j=0; j < ARRAY_SIZE(levels); j++) {
2479 struct lsa_QueryTrustedDomainInfoByName q;
2480 union lsa_TrustedDomainInfo *info = NULL;
2481 struct lsa_String name;
2483 name.string = domains->domains[i].name.string;
2485 q.in.handle = handle;
2486 q.in.trusted_domain = &name;
2487 q.in.level = levels[j];
2488 q.out.info = &info;
2489 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfoByName_r(b, tctx, &q),
2490 "QueryTrustedDomainInfoByName failed");
2491 if (!NT_STATUS_IS_OK(q.out.result) && ok[j]) {
2492 torture_comment(tctx, "QueryTrustedDomainInfoByName level %d failed - %s\n",
2493 levels[j], nt_errstr(q.out.result));
2494 ret = false;
2495 } else if (NT_STATUS_IS_OK(q.out.result) && !ok[j]) {
2496 torture_comment(tctx, "QueryTrustedDomainInfoByName level %d unexpectedly succeeded - %s\n",
2497 levels[j], nt_errstr(q.out.result));
2498 ret = false;
2502 return ret;
2505 static bool test_EnumTrustDom(struct dcerpc_binding_handle *b,
2506 struct torture_context *tctx,
2507 struct policy_handle *handle)
2509 struct lsa_EnumTrustDom r;
2510 uint32_t in_resume_handle = 0;
2511 uint32_t out_resume_handle;
2512 struct lsa_DomainList domains;
2513 bool ret = true;
2515 torture_comment(tctx, "\nTesting EnumTrustDom\n");
2517 r.in.handle = handle;
2518 r.in.resume_handle = &in_resume_handle;
2519 r.in.max_size = 0;
2520 r.out.domains = &domains;
2521 r.out.resume_handle = &out_resume_handle;
2523 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustDom_r(b, tctx, &r),
2524 "lsa_EnumTrustDom failed");
2526 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
2527 * always be larger than the previous input resume handle, in
2528 * particular when hitting the last query it is vital to set the
2529 * resume handle correctly to avoid infinite client loops, as
2530 * seen e.g. with Windows XP SP3 when resume handle is 0 and
2531 * status is NT_STATUS_OK - gd */
2533 if (NT_STATUS_IS_OK(r.out.result) ||
2534 NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES) ||
2535 NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
2537 if (out_resume_handle <= in_resume_handle) {
2538 torture_comment(tctx, "EnumTrustDom failed - should have returned output resume_handle (0x%08x) larger than input resume handle (0x%08x)\n",
2539 out_resume_handle, in_resume_handle);
2540 return false;
2544 if (NT_STATUS_IS_OK(r.out.result)) {
2545 if (domains.count == 0) {
2546 torture_comment(tctx, "EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
2547 return false;
2549 } else if (!(NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) || NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES))) {
2550 torture_comment(tctx, "EnumTrustDom of zero size failed - %s\n", nt_errstr(r.out.result));
2551 return false;
2554 /* Start from the bottom again */
2555 in_resume_handle = 0;
2557 do {
2558 r.in.handle = handle;
2559 r.in.resume_handle = &in_resume_handle;
2560 r.in.max_size = LSA_ENUM_TRUST_DOMAIN_MULTIPLIER * 3;
2561 r.out.domains = &domains;
2562 r.out.resume_handle = &out_resume_handle;
2564 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustDom_r(b, tctx, &r),
2565 "EnumTrustDom failed");
2567 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
2568 * always be larger than the previous input resume handle, in
2569 * particular when hitting the last query it is vital to set the
2570 * resume handle correctly to avoid infinite client loops, as
2571 * seen e.g. with Windows XP SP3 when resume handle is 0 and
2572 * status is NT_STATUS_OK - gd */
2574 if (NT_STATUS_IS_OK(r.out.result) ||
2575 NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES) ||
2576 NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
2578 if (out_resume_handle <= in_resume_handle) {
2579 torture_comment(tctx, "EnumTrustDom failed - should have returned output resume_handle (0x%08x) larger than input resume handle (0x%08x)\n",
2580 out_resume_handle, in_resume_handle);
2581 return false;
2585 /* NO_MORE_ENTRIES is allowed */
2586 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES)) {
2587 if (domains.count == 0) {
2588 return true;
2590 torture_comment(tctx, "EnumTrustDom failed - should have returned 0 trusted domains with 'NT_STATUS_NO_MORE_ENTRIES'\n");
2591 return false;
2592 } else if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES)) {
2593 /* Windows 2003 gets this off by one on the first run */
2594 if (r.out.domains->count < 3 || r.out.domains->count > 4) {
2595 torture_comment(tctx, "EnumTrustDom didn't fill the buffer we "
2596 "asked it to (got %d, expected %d / %d == %d entries)\n",
2597 r.out.domains->count, LSA_ENUM_TRUST_DOMAIN_MULTIPLIER * 3,
2598 LSA_ENUM_TRUST_DOMAIN_MULTIPLIER, r.in.max_size);
2599 ret = false;
2601 } else if (!NT_STATUS_IS_OK(r.out.result)) {
2602 torture_comment(tctx, "EnumTrustDom failed - %s\n", nt_errstr(r.out.result));
2603 return false;
2606 if (domains.count == 0) {
2607 torture_comment(tctx, "EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
2608 return false;
2611 ret &= test_query_each_TrustDom(b, tctx, handle, &domains);
2613 in_resume_handle = out_resume_handle;
2615 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
2617 return ret;
2620 static bool test_EnumTrustDomEx(struct dcerpc_binding_handle *b,
2621 struct torture_context *tctx,
2622 struct policy_handle *handle)
2624 struct lsa_EnumTrustedDomainsEx r_ex;
2625 uint32_t in_resume_handle = 0;
2626 uint32_t out_resume_handle;
2627 struct lsa_DomainListEx domains_ex;
2628 bool ret = true;
2630 torture_comment(tctx, "\nTesting EnumTrustedDomainsEx\n");
2632 r_ex.in.handle = handle;
2633 r_ex.in.resume_handle = &in_resume_handle;
2634 r_ex.in.max_size = 0;
2635 r_ex.out.domains = &domains_ex;
2636 r_ex.out.resume_handle = &out_resume_handle;
2638 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustedDomainsEx_r(b, tctx, &r_ex),
2639 "EnumTrustedDomainsEx failed");
2641 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
2642 * always be larger than the previous input resume handle, in
2643 * particular when hitting the last query it is vital to set the
2644 * resume handle correctly to avoid infinite client loops, as
2645 * seen e.g. with Windows XP SP3 when resume handle is 0 and
2646 * status is NT_STATUS_OK - gd */
2648 if (NT_STATUS_IS_OK(r_ex.out.result) ||
2649 NT_STATUS_EQUAL(r_ex.out.result, NT_STATUS_NO_MORE_ENTRIES) ||
2650 NT_STATUS_EQUAL(r_ex.out.result, STATUS_MORE_ENTRIES))
2652 if (out_resume_handle <= in_resume_handle) {
2653 torture_comment(tctx, "EnumTrustDomEx failed - should have returned output resume_handle (0x%08x) larger than input resume handle (0x%08x)\n",
2654 out_resume_handle, in_resume_handle);
2655 return false;
2659 if (NT_STATUS_IS_OK(r_ex.out.result)) {
2660 if (domains_ex.count == 0) {
2661 torture_comment(tctx, "EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
2662 return false;
2664 } else if (!(NT_STATUS_EQUAL(r_ex.out.result, STATUS_MORE_ENTRIES) ||
2665 NT_STATUS_EQUAL(r_ex.out.result, NT_STATUS_NO_MORE_ENTRIES))) {
2666 torture_comment(tctx, "EnumTrustDom of zero size failed - %s\n",
2667 nt_errstr(r_ex.out.result));
2668 return false;
2671 in_resume_handle = 0;
2672 do {
2673 r_ex.in.handle = handle;
2674 r_ex.in.resume_handle = &in_resume_handle;
2675 r_ex.in.max_size = LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER * 3;
2676 r_ex.out.domains = &domains_ex;
2677 r_ex.out.resume_handle = &out_resume_handle;
2679 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustedDomainsEx_r(b, tctx, &r_ex),
2680 "EnumTrustedDomainsEx failed");
2682 in_resume_handle = out_resume_handle;
2684 /* NO_MORE_ENTRIES is allowed */
2685 if (NT_STATUS_EQUAL(r_ex.out.result, NT_STATUS_NO_MORE_ENTRIES)) {
2686 if (domains_ex.count == 0) {
2687 return true;
2689 torture_comment(tctx, "EnumTrustDomainsEx failed - should have returned 0 trusted domains with 'NT_STATUS_NO_MORE_ENTRIES'\n");
2690 return false;
2691 } else if (NT_STATUS_EQUAL(r_ex.out.result, STATUS_MORE_ENTRIES)) {
2692 /* Windows 2003 gets this off by one on the first run */
2693 if (r_ex.out.domains->count < 3 || r_ex.out.domains->count > 4) {
2694 torture_comment(tctx, "EnumTrustDom didn't fill the buffer we "
2695 "asked it to (got %d, expected %d / %d == %d entries)\n",
2696 r_ex.out.domains->count,
2697 r_ex.in.max_size,
2698 LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER,
2699 r_ex.in.max_size / LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER);
2701 } else if (!NT_STATUS_IS_OK(r_ex.out.result)) {
2702 torture_comment(tctx, "EnumTrustedDomainEx failed - %s\n", nt_errstr(r_ex.out.result));
2703 return false;
2706 if (domains_ex.count == 0) {
2707 torture_comment(tctx, "EnumTrustDomainEx failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
2708 return false;
2711 ret &= test_query_each_TrustDomEx(b, tctx, handle, &domains_ex);
2713 } while (NT_STATUS_EQUAL(r_ex.out.result, STATUS_MORE_ENTRIES));
2715 return ret;
2719 static bool test_CreateTrustedDomain(struct dcerpc_binding_handle *b,
2720 struct torture_context *tctx,
2721 struct policy_handle *handle,
2722 uint32_t num_trusts)
2724 bool ret = true;
2725 struct lsa_CreateTrustedDomain r;
2726 struct lsa_DomainInfo trustinfo;
2727 struct dom_sid **domsid;
2728 struct policy_handle *trustdom_handle;
2729 struct lsa_QueryTrustedDomainInfo q;
2730 union lsa_TrustedDomainInfo *info = NULL;
2731 int i;
2733 torture_comment(tctx, "\nTesting CreateTrustedDomain for %d domains\n", num_trusts);
2735 if (!test_EnumTrustDom(b, tctx, handle)) {
2736 ret = false;
2739 if (!test_EnumTrustDomEx(b, tctx, handle)) {
2740 ret = false;
2743 domsid = talloc_array(tctx, struct dom_sid *, num_trusts);
2744 trustdom_handle = talloc_array(tctx, struct policy_handle, num_trusts);
2746 for (i=0; i< num_trusts; i++) {
2747 char *trust_name = talloc_asprintf(tctx, "TORTURE1%02d", i);
2748 char *trust_sid = talloc_asprintf(tctx, "S-1-5-21-97398-379795-1%02d", i);
2750 domsid[i] = dom_sid_parse_talloc(tctx, trust_sid);
2752 trustinfo.sid = domsid[i];
2753 init_lsa_String((struct lsa_String *)&trustinfo.name, trust_name);
2755 r.in.policy_handle = handle;
2756 r.in.info = &trustinfo;
2757 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2758 r.out.trustdom_handle = &trustdom_handle[i];
2760 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CreateTrustedDomain_r(b, tctx, &r),
2761 "CreateTrustedDomain failed");
2762 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_OBJECT_NAME_COLLISION)) {
2763 test_DeleteTrustedDomain(b, tctx, handle, trustinfo.name);
2764 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CreateTrustedDomain_r(b, tctx, &r),
2765 "CreateTrustedDomain failed");
2767 if (!NT_STATUS_IS_OK(r.out.result)) {
2768 torture_comment(tctx, "CreateTrustedDomain failed - %s\n", nt_errstr(r.out.result));
2769 ret = false;
2770 } else {
2772 q.in.trustdom_handle = &trustdom_handle[i];
2773 q.in.level = LSA_TRUSTED_DOMAIN_INFO_INFO_EX;
2774 q.out.info = &info;
2775 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfo_r(b, tctx, &q),
2776 "QueryTrustedDomainInfo failed");
2777 if (!NT_STATUS_IS_OK(q.out.result)) {
2778 torture_comment(tctx, "QueryTrustedDomainInfo level %d failed - %s\n", q.in.level, nt_errstr(q.out.result));
2779 ret = false;
2780 } else if (!q.out.info) {
2781 ret = false;
2782 } else {
2783 if (strcmp(info->info_ex.domain_name.string, trustinfo.name.string) != 0) {
2784 torture_comment(tctx, "QueryTrustedDomainInfo returned inconsistent long name: %s != %s\n",
2785 info->info_ex.domain_name.string, trustinfo.name.string);
2786 ret = false;
2788 if (strcmp(info->info_ex.netbios_name.string, trustinfo.name.string) != 0) {
2789 torture_comment(tctx, "QueryTrustedDomainInfo returned inconsistent short name: %s != %s\n",
2790 info->info_ex.netbios_name.string, trustinfo.name.string);
2791 ret = false;
2793 if (info->info_ex.trust_type != LSA_TRUST_TYPE_DOWNLEVEL) {
2794 torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n",
2795 trust_name, info->info_ex.trust_type, LSA_TRUST_TYPE_DOWNLEVEL);
2796 ret = false;
2798 if (info->info_ex.trust_attributes != 0) {
2799 torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n",
2800 trust_name, info->info_ex.trust_attributes, 0);
2801 ret = false;
2803 if (info->info_ex.trust_direction != LSA_TRUST_DIRECTION_OUTBOUND) {
2804 torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n",
2805 trust_name, info->info_ex.trust_direction, LSA_TRUST_DIRECTION_OUTBOUND);
2806 ret = false;
2812 /* now that we have some domains to look over, we can test the enum calls */
2813 if (!test_EnumTrustDom(b, tctx, handle)) {
2814 ret = false;
2817 if (!test_EnumTrustDomEx(b, tctx, handle)) {
2818 ret = false;
2821 for (i=0; i<num_trusts; i++) {
2822 if (!test_DeleteTrustedDomainBySid(b, tctx, handle, domsid[i])) {
2823 ret = false;
2827 return ret;
2830 static bool gen_authinfo(TALLOC_CTX *mem_ctx,
2831 const char *incoming_old, const char *incoming_new,
2832 const char *outgoing_old, const char *outgoing_new,
2833 struct lsa_TrustDomainInfoAuthInfo **_authinfo)
2835 struct lsa_TrustDomainInfoAuthInfo *authinfo;
2836 struct lsa_TrustDomainInfoBuffer *in_buffer;
2837 struct lsa_TrustDomainInfoBuffer *io_buffer;
2838 struct lsa_TrustDomainInfoBuffer *on_buffer;
2839 struct lsa_TrustDomainInfoBuffer *oo_buffer;
2840 size_t converted_size;
2841 bool ok;
2843 authinfo = talloc_zero(mem_ctx, struct lsa_TrustDomainInfoAuthInfo);
2844 if (authinfo == NULL) {
2845 return false;
2848 in_buffer = talloc_zero(authinfo, struct lsa_TrustDomainInfoBuffer);
2849 if (in_buffer == NULL) {
2850 return false;
2852 in_buffer->AuthType = TRUST_AUTH_TYPE_CLEAR;
2853 ok = convert_string_talloc(in_buffer, CH_UNIX, CH_UTF16,
2854 incoming_new,
2855 strlen(incoming_new),
2856 &in_buffer->data.data,
2857 &converted_size);
2858 if (!ok) {
2859 return false;
2861 in_buffer->data.size = converted_size;
2863 io_buffer = talloc_zero(authinfo, struct lsa_TrustDomainInfoBuffer);
2864 if (io_buffer == NULL) {
2865 return false;
2867 io_buffer->AuthType = TRUST_AUTH_TYPE_CLEAR;
2868 ok = convert_string_talloc(io_buffer, CH_UNIX, CH_UTF16,
2869 incoming_old,
2870 strlen(incoming_old),
2871 &io_buffer->data.data,
2872 &converted_size);
2873 if (!ok) {
2874 return false;
2876 io_buffer->data.size = converted_size;
2878 on_buffer = talloc_zero(authinfo, struct lsa_TrustDomainInfoBuffer);
2879 if (on_buffer == NULL) {
2880 return false;
2882 on_buffer->AuthType = TRUST_AUTH_TYPE_CLEAR;
2883 ok = convert_string_talloc(on_buffer, CH_UNIX, CH_UTF16,
2884 outgoing_new,
2885 strlen(outgoing_new),
2886 &on_buffer->data.data,
2887 &converted_size);
2888 if (!ok) {
2889 return false;
2891 on_buffer->data.size = converted_size;
2893 oo_buffer = talloc_zero(authinfo, struct lsa_TrustDomainInfoBuffer);
2894 if (oo_buffer == NULL) {
2895 return false;
2897 oo_buffer->AuthType = TRUST_AUTH_TYPE_CLEAR;
2898 ok = convert_string_talloc(oo_buffer, CH_UNIX, CH_UTF16,
2899 outgoing_old,
2900 strlen(outgoing_old),
2901 &oo_buffer->data.data,
2902 &converted_size);
2903 if (!ok) {
2904 return false;
2906 oo_buffer->data.size = converted_size;
2908 authinfo->incoming_count = 1;
2909 authinfo->incoming_current_auth_info = in_buffer;
2910 authinfo->incoming_previous_auth_info = io_buffer;
2911 authinfo->outgoing_count = 1;
2912 authinfo->outgoing_current_auth_info = on_buffer;
2913 authinfo->outgoing_previous_auth_info = oo_buffer;
2915 *_authinfo = authinfo;
2917 return true;
2920 static bool check_pw_with_ServerAuthenticate3(struct dcerpc_pipe *p,
2921 struct torture_context *tctx,
2922 uint32_t negotiate_flags,
2923 const char *server_name,
2924 struct cli_credentials *machine_credentials,
2925 struct netlogon_creds_CredentialState **creds_out)
2927 struct netr_ServerReqChallenge r;
2928 struct netr_ServerAuthenticate3 a;
2929 struct netr_Credential credentials1, credentials2, credentials3;
2930 struct netlogon_creds_CredentialState *creds;
2931 const struct samr_Password *new_password = NULL;
2932 const struct samr_Password *old_password = NULL;
2933 uint32_t rid;
2934 struct dcerpc_binding_handle *b = p->binding_handle;
2936 new_password = cli_credentials_get_nt_hash(machine_credentials, tctx);
2937 old_password = cli_credentials_get_old_nt_hash(machine_credentials, tctx);
2939 r.in.server_name = server_name;
2940 r.in.computer_name = cli_credentials_get_workstation(machine_credentials);
2941 r.in.credentials = &credentials1;
2942 r.out.return_credentials = &credentials2;
2944 netlogon_creds_random_challenge(&credentials1);
2946 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
2947 "ServerReqChallenge failed");
2948 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
2950 a.in.server_name = server_name;
2951 a.in.account_name = cli_credentials_get_username(machine_credentials);
2952 a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2953 a.in.computer_name = cli_credentials_get_workstation(machine_credentials);
2954 a.in.negotiate_flags = &negotiate_flags;
2955 a.in.credentials = &credentials3;
2956 a.out.return_credentials = &credentials3;
2957 a.out.negotiate_flags = &negotiate_flags;
2958 a.out.rid = &rid;
2960 creds = netlogon_creds_client_init(tctx, a.in.account_name,
2961 a.in.computer_name,
2962 a.in.secure_channel_type,
2963 &credentials1, &credentials2,
2964 new_password, &credentials3,
2965 negotiate_flags,
2966 negotiate_flags);
2968 torture_assert(tctx, creds != NULL, "memory allocation");
2970 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
2971 "ServerAuthenticate3 failed");
2972 if (!NT_STATUS_IS_OK(a.out.result)) {
2973 if (!NT_STATUS_EQUAL(a.out.result, NT_STATUS_ACCESS_DENIED)) {
2974 torture_assert_ntstatus_ok(tctx, a.out.result,
2975 "ServerAuthenticate3 failed");
2977 return false;
2979 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
2981 if (old_password != NULL) {
2982 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
2983 "ServerReqChallenge failed");
2984 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
2986 creds = netlogon_creds_client_init(tctx, a.in.account_name,
2987 a.in.computer_name,
2988 a.in.secure_channel_type,
2989 &credentials1, &credentials2,
2990 old_password, &credentials3,
2991 negotiate_flags,
2992 negotiate_flags);
2994 torture_assert(tctx, creds != NULL, "memory allocation");
2996 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
2997 "ServerAuthenticate3 failed");
2998 if (!NT_STATUS_IS_OK(a.out.result)) {
2999 if (!NT_STATUS_EQUAL(a.out.result, NT_STATUS_ACCESS_DENIED)) {
3000 torture_assert_ntstatus_ok(tctx, a.out.result,
3001 "ServerAuthenticate3 (old) failed");
3003 return false;
3005 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential (old) chaining failed");
3008 /* Prove that requesting a challenge again won't break it */
3009 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
3010 "ServerReqChallenge failed");
3011 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
3013 *creds_out = creds;
3014 return true;
3017 #ifdef SAMBA4_USES_HEIMDAL
3020 * This function is set in torture_krb5_init_context as krb5
3021 * send_and_recv function. This allows us to override what server the
3022 * test is aimed at, and to inspect the packets just before they are
3023 * sent to the network, and before they are processed on the recv
3024 * side.
3026 * The torture_krb5_pre_send_test() and torture_krb5_post_recv_test()
3027 * functions are implement the actual tests.
3029 * When this asserts, the caller will get a spurious 'cannot contact
3030 * any KDC' message.
3033 struct check_pw_with_krb5_ctx {
3034 struct addrinfo *server;
3035 const char *server_nb_domain;
3036 const char *server_dns_domain;
3037 struct {
3038 unsigned io;
3039 unsigned fail;
3040 unsigned errors;
3041 unsigned error_io;
3042 unsigned ok;
3043 } counts;
3044 krb5_error error;
3045 struct smb_krb5_context *smb_krb5_context;
3046 krb5_get_init_creds_opt *krb_options;
3047 krb5_creds my_creds;
3048 krb5_get_creds_opt opt_canon;
3049 krb5_get_creds_opt opt_nocanon;
3050 krb5_principal upn_realm;
3051 krb5_principal upn_dns;
3052 krb5_principal upn_netbios;
3053 krb5_ccache krbtgt_ccache;
3054 krb5_principal krbtgt_trust_realm;
3055 krb5_creds *krbtgt_trust_realm_creds;
3056 krb5_principal krbtgt_trust_dns;
3057 krb5_creds *krbtgt_trust_dns_creds;
3058 krb5_principal krbtgt_trust_netbios;
3059 krb5_creds *krbtgt_trust_netbios_creds;
3060 krb5_principal cifs_trust_dns;
3061 krb5_creds *cifs_trust_dns_creds;
3062 krb5_principal cifs_trust_netbios;
3063 krb5_creds *cifs_trust_netbios_creds;
3064 krb5_principal drs_trust_dns;
3065 krb5_creds *drs_trust_dns_creds;
3066 krb5_principal drs_trust_netbios;
3067 krb5_creds *drs_trust_netbios_creds;
3068 krb5_principal four_trust_dns;
3069 krb5_creds *four_trust_dns_creds;
3070 krb5_creds krbtgt_referral_creds;
3071 Ticket krbtgt_referral_ticket;
3072 krb5_keyblock krbtgt_referral_keyblock;
3073 EncTicketPart krbtgt_referral_enc_part;
3076 static krb5_error_code check_pw_with_krb5_send_to_realm(
3077 struct smb_krb5_context *smb_krb5_context,
3078 void *data, /* struct check_pw_with_krb5_ctx */
3079 krb5_const_realm realm,
3080 time_t timeout,
3081 const krb5_data *send_buf,
3082 krb5_data *recv_buf)
3084 struct check_pw_with_krb5_ctx *ctx =
3085 talloc_get_type_abort(data, struct check_pw_with_krb5_ctx);
3086 krb5_error_code k5ret;
3087 size_t used;
3088 int ret;
3090 SMB_ASSERT(smb_krb5_context == ctx->smb_krb5_context);
3092 if (!strequal_m(realm, ctx->server_nb_domain) &&
3093 !strequal_m(realm, ctx->server_dns_domain))
3095 return KRB5_KDC_UNREACH;
3098 krb5_free_error_contents(ctx->smb_krb5_context->krb5_context,
3099 &ctx->error);
3100 ctx->counts.io++;
3102 k5ret = smb_krb5_send_and_recv_func_forced_tcp(ctx->smb_krb5_context,
3103 ctx->server,
3104 timeout, send_buf, recv_buf);
3105 if (k5ret != 0) {
3106 ctx->counts.fail++;
3107 return k5ret;
3110 ret = decode_KRB_ERROR(recv_buf->data, recv_buf->length,
3111 &ctx->error, &used);
3112 if (ret == 0) {
3113 ctx->counts.errors++;
3114 ctx->counts.error_io = ctx->counts.io;
3115 } else {
3116 ctx->counts.ok++;
3119 return k5ret;
3122 static int check_pw_with_krb5_ctx_destructor(struct check_pw_with_krb5_ctx *ctx)
3124 if (ctx->server != NULL) {
3125 freeaddrinfo(ctx->server);
3126 ctx->server = NULL;
3129 if (ctx->krb_options != NULL) {
3130 krb5_get_init_creds_opt_free(ctx->smb_krb5_context->krb5_context,
3131 ctx->krb_options);
3132 ctx->krb_options = NULL;
3135 krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3136 &ctx->my_creds);
3138 if (ctx->opt_canon != NULL) {
3139 krb5_get_creds_opt_free(ctx->smb_krb5_context->krb5_context,
3140 ctx->opt_canon);
3141 ctx->opt_canon = NULL;
3144 if (ctx->opt_nocanon != NULL) {
3145 krb5_get_creds_opt_free(ctx->smb_krb5_context->krb5_context,
3146 ctx->opt_nocanon);
3147 ctx->opt_nocanon = NULL;
3150 if (ctx->krbtgt_ccache != NULL) {
3151 krb5_cc_close(ctx->smb_krb5_context->krb5_context,
3152 ctx->krbtgt_ccache);
3153 ctx->krbtgt_ccache = NULL;
3156 if (ctx->upn_realm != NULL) {
3157 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3158 ctx->upn_realm);
3159 ctx->upn_realm = NULL;
3162 if (ctx->upn_dns != NULL) {
3163 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3164 ctx->upn_dns);
3165 ctx->upn_dns = NULL;
3168 if (ctx->upn_netbios != NULL) {
3169 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3170 ctx->upn_netbios);
3171 ctx->upn_netbios = NULL;
3174 if (ctx->krbtgt_trust_realm != NULL) {
3175 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3176 ctx->krbtgt_trust_realm);
3177 ctx->krbtgt_trust_realm = NULL;
3180 if (ctx->krbtgt_trust_realm_creds != NULL) {
3181 krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3182 ctx->krbtgt_trust_realm_creds);
3183 ctx->krbtgt_trust_realm_creds = NULL;
3186 if (ctx->krbtgt_trust_dns != NULL) {
3187 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3188 ctx->krbtgt_trust_dns);
3189 ctx->krbtgt_trust_dns = NULL;
3192 if (ctx->krbtgt_trust_dns_creds != NULL) {
3193 krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3194 ctx->krbtgt_trust_dns_creds);
3195 ctx->krbtgt_trust_dns_creds = NULL;
3198 if (ctx->krbtgt_trust_netbios != NULL) {
3199 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3200 ctx->krbtgt_trust_netbios);
3201 ctx->krbtgt_trust_netbios = NULL;
3204 if (ctx->krbtgt_trust_netbios_creds != NULL) {
3205 krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3206 ctx->krbtgt_trust_netbios_creds);
3207 ctx->krbtgt_trust_netbios_creds = NULL;
3210 if (ctx->cifs_trust_dns != NULL) {
3211 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3212 ctx->cifs_trust_dns);
3213 ctx->cifs_trust_dns = NULL;
3216 if (ctx->cifs_trust_dns_creds != NULL) {
3217 krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3218 ctx->cifs_trust_dns_creds);
3219 ctx->cifs_trust_dns_creds = NULL;
3222 if (ctx->cifs_trust_netbios != NULL) {
3223 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3224 ctx->cifs_trust_netbios);
3225 ctx->cifs_trust_netbios = NULL;
3228 if (ctx->cifs_trust_netbios_creds != NULL) {
3229 krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3230 ctx->cifs_trust_netbios_creds);
3231 ctx->cifs_trust_netbios_creds = NULL;
3234 if (ctx->drs_trust_dns != NULL) {
3235 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3236 ctx->drs_trust_dns);
3237 ctx->drs_trust_dns = NULL;
3240 if (ctx->drs_trust_dns_creds != NULL) {
3241 krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3242 ctx->drs_trust_dns_creds);
3243 ctx->drs_trust_dns_creds = NULL;
3246 if (ctx->drs_trust_netbios != NULL) {
3247 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3248 ctx->drs_trust_netbios);
3249 ctx->drs_trust_netbios = NULL;
3252 if (ctx->drs_trust_netbios_creds != NULL) {
3253 krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3254 ctx->drs_trust_netbios_creds);
3255 ctx->drs_trust_netbios_creds = NULL;
3258 if (ctx->four_trust_dns != NULL) {
3259 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3260 ctx->four_trust_dns);
3261 ctx->four_trust_dns = NULL;
3264 if (ctx->four_trust_dns_creds != NULL) {
3265 krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3266 ctx->four_trust_dns_creds);
3267 ctx->four_trust_dns_creds = NULL;
3270 krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3271 &ctx->krbtgt_referral_creds);
3273 free_Ticket(&ctx->krbtgt_referral_ticket);
3275 krb5_free_keyblock_contents(ctx->smb_krb5_context->krb5_context,
3276 &ctx->krbtgt_referral_keyblock);
3278 free_EncTicketPart(&ctx->krbtgt_referral_enc_part);
3280 krb5_free_error_contents(ctx->smb_krb5_context->krb5_context,
3281 &ctx->error);
3283 talloc_unlink(ctx, ctx->smb_krb5_context);
3284 ctx->smb_krb5_context = NULL;
3285 return 0;
3288 static bool check_pw_with_krb5(struct torture_context *tctx,
3289 struct cli_credentials *credentials,
3290 const struct lsa_TrustDomainInfoInfoEx *trusted)
3292 const char *trusted_dns_name = trusted->domain_name.string;
3293 const char *trusted_netbios_name = trusted->netbios_name.string;
3294 char *trusted_realm_name = NULL;
3295 krb5_principal principal = NULL;
3296 enum credentials_obtained obtained;
3297 const char *error_string = NULL;
3298 const char *workstation = cli_credentials_get_workstation(credentials);
3299 const char *password = cli_credentials_get_password(credentials);
3300 #ifndef USING_EMBEDDED_HEIMDAL
3301 const struct samr_Password *nthash = NULL;
3302 const struct samr_Password *old_nthash = NULL;
3303 #endif
3304 const char *old_password = cli_credentials_get_old_password(credentials);
3305 #ifndef USING_EMBEDDED_HEIMDAL
3306 int kvno = cli_credentials_get_kvno(credentials);
3307 int expected_kvno = 0;
3308 krb5uint32 t_kvno = 0;
3309 #endif
3310 const char *host = torture_setting_string(tctx, "host", NULL);
3311 krb5_error_code k5ret;
3312 krb5_boolean k5ok;
3313 int type;
3314 bool ok;
3315 struct check_pw_with_krb5_ctx *ctx = NULL;
3316 char *assertion_message = NULL;
3317 const char *realm = NULL;
3318 char *upn_realm_string = NULL;
3319 char *upn_dns_string = NULL;
3320 char *upn_netbios_string = NULL;
3321 char *krbtgt_cc_name = NULL;
3322 char *krbtgt_trust_realm_string = NULL;
3323 char *krbtgt_trust_dns_string = NULL;
3324 char *krbtgt_trust_netbios_string = NULL;
3325 char *cifs_trust_dns_string = NULL;
3326 char *cifs_trust_netbios_string = NULL;
3327 char *drs_trust_dns_string = NULL;
3328 char *drs_trust_netbios_string = NULL;
3329 char *four_trust_dns_string = NULL;
3331 ctx = talloc_zero(tctx, struct check_pw_with_krb5_ctx);
3332 torture_assert(tctx, ctx != NULL, "Failed to allocate");
3334 realm = cli_credentials_get_realm(credentials);
3335 trusted_realm_name = strupper_talloc(tctx, trusted_dns_name);
3337 #ifndef USING_EMBEDDED_HEIMDAL
3338 nthash = cli_credentials_get_nt_hash(credentials, ctx);
3339 old_nthash = cli_credentials_get_old_nt_hash(credentials, ctx);
3340 #endif
3342 k5ret = smb_krb5_init_context(ctx, tctx->lp_ctx, &ctx->smb_krb5_context);
3343 torture_assert_int_equal(tctx, k5ret, 0, "smb_krb5_init_context failed");
3345 ctx->server_nb_domain = cli_credentials_get_domain(credentials);
3346 ctx->server_dns_domain = cli_credentials_get_realm(credentials);
3348 ok = interpret_string_addr_internal(&ctx->server, host, 0);
3349 torture_assert(tctx, ok, "Failed to parse target server");
3350 talloc_set_destructor(ctx, check_pw_with_krb5_ctx_destructor);
3352 set_sockaddr_port(ctx->server->ai_addr, 88);
3354 k5ret = smb_krb5_set_send_to_kdc_func(ctx->smb_krb5_context,
3355 check_pw_with_krb5_send_to_realm,
3356 NULL, /* send_to_kdc */
3357 ctx);
3358 torture_assert_int_equal(tctx, k5ret, 0, "krb5_set_send_to_kdc_func failed");
3360 torture_assert_int_equal(tctx,
3361 krb5_get_init_creds_opt_alloc(ctx->smb_krb5_context->krb5_context,
3362 &ctx->krb_options),
3363 0, "krb5_get_init_creds_opt_alloc failed");
3364 torture_assert_int_equal(tctx,
3365 krb5_get_init_creds_opt_set_pac_request(
3366 ctx->smb_krb5_context->krb5_context,
3367 ctx->krb_options, true),
3368 0, "krb5_get_init_creds_opt_set_pac_request failed");
3370 upn_realm_string = talloc_asprintf(ctx, "user@%s",
3371 trusted_realm_name);
3372 torture_assert_int_equal(tctx,
3373 smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3374 &ctx->upn_realm,
3375 realm, upn_realm_string, NULL),
3376 0, "smb_krb5_make_principal failed");
3377 smb_krb5_principal_set_type(ctx->smb_krb5_context->krb5_context,
3378 ctx->upn_realm, KRB5_NT_ENTERPRISE_PRINCIPAL);
3380 upn_dns_string = talloc_asprintf(ctx, "user@%s",
3381 trusted_dns_name);
3382 torture_assert_int_equal(tctx,
3383 smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3384 &ctx->upn_dns,
3385 realm, upn_dns_string, NULL),
3386 0, "smb_krb5_make_principal failed");
3387 smb_krb5_principal_set_type(ctx->smb_krb5_context->krb5_context,
3388 ctx->upn_dns, KRB5_NT_ENTERPRISE_PRINCIPAL);
3390 upn_netbios_string = talloc_asprintf(ctx, "user@%s",
3391 trusted_netbios_name);
3392 torture_assert_int_equal(tctx,
3393 smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3394 &ctx->upn_netbios,
3395 realm, upn_netbios_string, NULL),
3396 0, "smb_krb5_make_principal failed");
3397 smb_krb5_principal_set_type(ctx->smb_krb5_context->krb5_context,
3398 ctx->upn_netbios, KRB5_NT_ENTERPRISE_PRINCIPAL);
3400 k5ret = principal_from_credentials(ctx, credentials, ctx->smb_krb5_context,
3401 &principal, &obtained, &error_string);
3402 torture_assert_int_equal(tctx, k5ret, 0, error_string);
3404 ZERO_STRUCT(ctx->counts);
3405 k5ret = krb5_get_init_creds_password(ctx->smb_krb5_context->krb5_context,
3406 &ctx->my_creds, ctx->upn_realm,
3407 "_none_", NULL, NULL, 0,
3408 NULL, ctx->krb_options);
3409 assertion_message = talloc_asprintf(ctx,
3410 "krb5_get_init_creds_password(%s, canon) for failed: "
3411 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u/%u,ok=%u]",
3412 upn_realm_string,
3413 k5ret,
3414 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3415 k5ret, ctx),
3416 trusted->trust_direction,
3417 trusted->trust_type,
3418 trusted->trust_attributes,
3419 ctx->counts.io, ctx->counts.error_io, ctx->counts.errors, ctx->counts.ok);
3420 torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3421 torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3422 torture_assert_int_equal(tctx, ctx->counts.error_io, 1, assertion_message);
3423 torture_assert_int_equal(tctx, KRB5_ERROR_CODE(&ctx->error), 68, assertion_message);
3424 torture_assert(tctx, ctx->error.crealm != NULL, assertion_message);
3425 torture_assert_str_equal(tctx, *ctx->error.crealm, trusted_realm_name, assertion_message);
3426 #ifdef USING_EMBEDDED_HEIMDAL
3427 torture_assert(tctx, ctx->error.cname != NULL, assertion_message);
3428 torture_assert_int_equal(tctx, ctx->error.cname->name_type, KRB5_NT_ENTERPRISE_PRINCIPAL, assertion_message);
3429 torture_assert_int_equal(tctx, ctx->error.cname->name_string.len, 1, assertion_message);
3430 torture_assert_str_equal(tctx, ctx->error.cname->name_string.val[0], upn_realm_string, assertion_message);
3431 #else
3432 torture_assert(tctx, ctx->error.cname == NULL, assertion_message);
3433 #endif
3434 torture_assert_str_equal(tctx, ctx->error.realm, realm, assertion_message);
3436 ZERO_STRUCT(ctx->counts);
3437 k5ret = krb5_get_init_creds_password(ctx->smb_krb5_context->krb5_context,
3438 &ctx->my_creds, ctx->upn_dns,
3439 "_none_", NULL, NULL, 0,
3440 NULL, ctx->krb_options);
3441 assertion_message = talloc_asprintf(ctx,
3442 "krb5_get_init_creds_password(%s, canon) for failed: "
3443 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u/%u,ok=%u]",
3444 upn_dns_string,
3445 k5ret,
3446 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3447 k5ret, ctx),
3448 trusted->trust_direction,
3449 trusted->trust_type,
3450 trusted->trust_attributes,
3451 ctx->counts.io, ctx->counts.error_io, ctx->counts.errors, ctx->counts.ok);
3452 torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3453 torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3454 torture_assert_int_equal(tctx, ctx->counts.error_io, 1, assertion_message);
3455 torture_assert_int_equal(tctx, KRB5_ERROR_CODE(&ctx->error), 68, assertion_message);
3456 torture_assert(tctx, ctx->error.crealm != NULL, assertion_message);
3457 torture_assert_str_equal(tctx, *ctx->error.crealm, trusted_realm_name, assertion_message);
3458 #ifdef USING_EMBEDDED_HEIMDAL
3459 torture_assert(tctx, ctx->error.cname != NULL, assertion_message);
3460 torture_assert_int_equal(tctx, ctx->error.cname->name_type, KRB5_NT_ENTERPRISE_PRINCIPAL, assertion_message);
3461 torture_assert_int_equal(tctx, ctx->error.cname->name_string.len, 1, assertion_message);
3462 torture_assert_str_equal(tctx, ctx->error.cname->name_string.val[0], upn_dns_string, assertion_message);
3463 #else
3464 torture_assert(tctx, ctx->error.cname == NULL, assertion_message);
3465 #endif
3466 torture_assert_str_equal(tctx, ctx->error.realm, realm, assertion_message);
3468 ZERO_STRUCT(ctx->counts);
3469 k5ret = krb5_get_init_creds_password(ctx->smb_krb5_context->krb5_context,
3470 &ctx->my_creds, ctx->upn_netbios,
3471 "_none_", NULL, NULL, 0,
3472 NULL, ctx->krb_options);
3473 assertion_message = talloc_asprintf(ctx,
3474 "krb5_get_init_creds_password(%s, canon) for failed: "
3475 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u/%u,ok=%u]",
3476 upn_netbios_string,
3477 k5ret,
3478 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3479 k5ret, ctx),
3480 trusted->trust_direction,
3481 trusted->trust_type,
3482 trusted->trust_attributes,
3483 ctx->counts.io, ctx->counts.error_io, ctx->counts.errors, ctx->counts.ok);
3484 torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3485 torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3486 torture_assert_int_equal(tctx, ctx->counts.error_io, 1, assertion_message);
3487 torture_assert_int_equal(tctx, KRB5_ERROR_CODE(&ctx->error), 68, assertion_message);
3488 torture_assert(tctx, ctx->error.crealm != NULL, assertion_message);
3489 torture_assert_str_equal(tctx, *ctx->error.crealm, trusted_realm_name, assertion_message);
3490 #ifdef USING_EMBEDDED_HEIMDAL
3491 torture_assert(tctx, ctx->error.cname != NULL, assertion_message);
3492 torture_assert_int_equal(tctx, ctx->error.cname->name_type, KRB5_NT_ENTERPRISE_PRINCIPAL, assertion_message);
3493 torture_assert_int_equal(tctx, ctx->error.cname->name_string.len, 1, assertion_message);
3494 torture_assert_str_equal(tctx, ctx->error.cname->name_string.val[0], upn_netbios_string, assertion_message);
3495 #else
3496 torture_assert(tctx, ctx->error.cname == NULL, assertion_message);
3497 #endif
3498 torture_assert_str_equal(tctx, ctx->error.realm, realm, assertion_message);
3500 torture_comment(tctx, "(%s:%s) password[%s] old_password[%s]\n",
3501 __location__, __FUNCTION__,
3502 password, old_password);
3503 if (old_password != NULL) {
3504 k5ret = krb5_get_init_creds_password(ctx->smb_krb5_context->krb5_context,
3505 &ctx->my_creds, principal,
3506 old_password, NULL, NULL, 0,
3507 NULL, ctx->krb_options);
3508 torture_assert_int_equal(tctx, k5ret, KRB5KDC_ERR_PREAUTH_FAILED,
3509 "preauth should fail with old password");
3512 k5ret = krb5_get_init_creds_password(ctx->smb_krb5_context->krb5_context,
3513 &ctx->my_creds, principal,
3514 password, NULL, NULL, 0,
3515 NULL, ctx->krb_options);
3516 if (k5ret == KRB5KDC_ERR_PREAUTH_FAILED) {
3517 TALLOC_FREE(ctx);
3518 return false;
3521 assertion_message = talloc_asprintf(ctx,
3522 "krb5_get_init_creds_password for failed: %s",
3523 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3524 k5ret, ctx));
3525 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3527 torture_assert_int_equal(tctx,
3528 krb5_get_creds_opt_alloc(ctx->smb_krb5_context->krb5_context,
3529 &ctx->opt_canon),
3530 0, "krb5_get_creds_opt_alloc");
3532 krb5_get_creds_opt_add_options(ctx->smb_krb5_context->krb5_context,
3533 ctx->opt_canon,
3534 KRB5_GC_CANONICALIZE);
3536 krb5_get_creds_opt_add_options(ctx->smb_krb5_context->krb5_context,
3537 ctx->opt_canon,
3538 KRB5_GC_NO_STORE);
3540 torture_assert_int_equal(tctx,
3541 krb5_get_creds_opt_alloc(ctx->smb_krb5_context->krb5_context,
3542 &ctx->opt_nocanon),
3543 0, "krb5_get_creds_opt_alloc");
3545 krb5_get_creds_opt_add_options(ctx->smb_krb5_context->krb5_context,
3546 ctx->opt_nocanon,
3547 KRB5_GC_NO_STORE);
3549 krbtgt_cc_name = talloc_asprintf(ctx, "MEMORY:%p.krbtgt", ctx->smb_krb5_context);
3550 torture_assert_int_equal(tctx,
3551 krb5_cc_resolve(ctx->smb_krb5_context->krb5_context,
3552 krbtgt_cc_name,
3553 &ctx->krbtgt_ccache),
3554 0, "krb5_cc_resolve failed");
3556 torture_assert_int_equal(tctx,
3557 krb5_cc_initialize(ctx->smb_krb5_context->krb5_context,
3558 ctx->krbtgt_ccache,
3559 ctx->my_creds.client),
3560 0, "krb5_cc_initialize failed");
3562 torture_assert_int_equal(tctx,
3563 krb5_cc_store_cred(ctx->smb_krb5_context->krb5_context,
3564 ctx->krbtgt_ccache,
3565 &ctx->my_creds),
3566 0, "krb5_cc_store_cred failed");
3568 krbtgt_trust_realm_string = talloc_asprintf(ctx, "krbtgt/%s@%s",
3569 trusted_realm_name, realm);
3570 torture_assert_int_equal(tctx,
3571 smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3572 &ctx->krbtgt_trust_realm,
3573 realm, "krbtgt",
3574 trusted_realm_name, NULL),
3575 0, "smb_krb5_make_principal failed");
3577 krbtgt_trust_dns_string = talloc_asprintf(ctx, "krbtgt/%s@%s",
3578 trusted_dns_name, realm);
3579 torture_assert_int_equal(tctx,
3580 smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3581 &ctx->krbtgt_trust_dns,
3582 realm, "krbtgt",
3583 trusted_dns_name, NULL),
3584 0, "smb_krb5_make_principal failed");
3586 krbtgt_trust_netbios_string = talloc_asprintf(ctx, "krbtgt/%s@%s",
3587 trusted_netbios_name, realm);
3588 torture_assert_int_equal(tctx,
3589 smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3590 &ctx->krbtgt_trust_netbios,
3591 realm, "krbtgt",
3592 trusted_netbios_name, NULL),
3593 0, "smb_krb5_make_principal failed");
3595 /* Confirm if we can do a TGS for krbtgt/trusted_realm */
3596 ZERO_STRUCT(ctx->counts);
3597 k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3598 ctx->opt_nocanon,
3599 ctx->krbtgt_ccache,
3600 ctx->krbtgt_trust_realm,
3601 &ctx->krbtgt_trust_realm_creds);
3602 assertion_message = talloc_asprintf(ctx,
3603 "krb5_get_creds(%s, canon) for failed: "
3604 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3605 krbtgt_trust_realm_string,
3606 k5ret,
3607 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3608 k5ret, ctx),
3609 trusted->trust_direction,
3610 trusted->trust_type,
3611 trusted->trust_attributes,
3612 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3613 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3614 torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3615 torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
3617 k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3618 ctx->krbtgt_trust_realm_creds->server,
3619 ctx->krbtgt_trust_realm);
3620 torture_assert(tctx, k5ok, assertion_message);
3621 type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3622 ctx->krbtgt_trust_realm_creds->server);
3623 torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3625 /* Confirm if we have no referral ticket in the cache */
3626 krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3627 &ctx->krbtgt_referral_creds);
3628 k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3629 ctx->krbtgt_ccache,
3631 ctx->krbtgt_trust_realm_creds,
3632 &ctx->krbtgt_referral_creds);
3633 assertion_message = talloc_asprintf(ctx,
3634 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3635 krbtgt_trust_realm_string,
3636 k5ret,
3637 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3638 k5ret, ctx));
3639 torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
3641 /* Confirm if we can do a TGS for krbtgt/trusted_dns with CANON */
3642 ZERO_STRUCT(ctx->counts);
3643 k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3644 ctx->opt_canon,
3645 ctx->krbtgt_ccache,
3646 ctx->krbtgt_trust_dns,
3647 &ctx->krbtgt_trust_dns_creds);
3648 assertion_message = talloc_asprintf(ctx,
3649 "krb5_get_creds(%s, canon) for failed: "
3650 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3651 krbtgt_trust_dns_string,
3652 k5ret,
3653 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3654 k5ret, ctx),
3655 trusted->trust_direction,
3656 trusted->trust_type,
3657 trusted->trust_attributes,
3658 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3659 #ifdef USING_EMBEDDED_HEIMDAL
3660 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3661 #else
3662 torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3663 #endif
3664 torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3665 torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
3667 /* Confirm if we have the referral ticket in the cache */
3668 krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3669 &ctx->krbtgt_referral_creds);
3670 k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3671 ctx->krbtgt_ccache,
3673 ctx->krbtgt_trust_realm_creds,
3674 &ctx->krbtgt_referral_creds);
3675 assertion_message = talloc_asprintf(ctx,
3676 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3677 krbtgt_trust_realm_string,
3678 k5ret,
3679 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3680 k5ret, ctx));
3681 #ifdef USING_EMBEDDED_HEIMDAL
3682 torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
3683 #else
3684 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3686 k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3687 ctx->krbtgt_referral_creds.server,
3688 ctx->krbtgt_trust_realm);
3689 torture_assert(tctx, k5ok, assertion_message);
3690 type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3691 ctx->krbtgt_referral_creds.server);
3692 torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3693 k5ret = decode_Ticket(ctx->krbtgt_referral_creds.ticket.data,
3694 ctx->krbtgt_referral_creds.ticket.length,
3695 &ctx->krbtgt_referral_ticket, NULL);
3696 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3697 if (kvno > 0) {
3698 expected_kvno = kvno - 1;
3700 if (ctx->krbtgt_referral_ticket.enc_part.kvno != NULL) {
3701 t_kvno = *ctx->krbtgt_referral_ticket.enc_part.kvno;
3702 assertion_message = talloc_asprintf(ctx,
3703 "krbtgt_referral_ticket(%s) kvno(%u) expected(%u) current(%u)",
3704 krbtgt_trust_realm_string,
3705 (unsigned)t_kvno, (unsigned)expected_kvno,(unsigned)kvno);
3706 torture_comment(tctx, "%s\n", assertion_message);
3707 torture_assert_int_not_equal(tctx, t_kvno, 0, assertion_message);
3708 } else {
3709 assertion_message = talloc_asprintf(ctx,
3710 "krbtgt_referral_ticket(%s) kvno(NULL) expected(%u) current(%u)",
3711 krbtgt_trust_realm_string,
3712 (unsigned)expected_kvno,(unsigned)kvno);
3713 torture_comment(tctx, "%s\n", assertion_message);
3715 torture_assert_int_equal(tctx, t_kvno, expected_kvno, assertion_message);
3717 if (old_nthash != NULL && expected_kvno != kvno) {
3718 torture_comment(tctx, "old_nthash: %s\n", assertion_message);
3719 k5ret = smb_krb5_keyblock_init_contents(ctx->smb_krb5_context->krb5_context,
3720 ENCTYPE_ARCFOUR_HMAC,
3721 old_nthash->hash,
3722 sizeof(old_nthash->hash),
3723 &ctx->krbtgt_referral_keyblock);
3724 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3725 } else {
3726 torture_comment(tctx, "nthash: %s\n", assertion_message);
3727 k5ret = smb_krb5_keyblock_init_contents(ctx->smb_krb5_context->krb5_context,
3728 ENCTYPE_ARCFOUR_HMAC,
3729 nthash->hash,
3730 sizeof(nthash->hash),
3731 &ctx->krbtgt_referral_keyblock);
3732 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3734 k5ret = krb5_decrypt_ticket(ctx->smb_krb5_context->krb5_context,
3735 &ctx->krbtgt_referral_ticket,
3736 &ctx->krbtgt_referral_keyblock,
3737 &ctx->krbtgt_referral_enc_part,
3739 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3741 /* Delete the referral ticket from the cache */
3742 k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
3743 ctx->krbtgt_ccache,
3745 &ctx->krbtgt_referral_creds);
3746 assertion_message = talloc_asprintf(ctx,
3747 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
3748 krbtgt_trust_realm_string,
3749 k5ret,
3750 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3751 k5ret, ctx));
3752 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3753 #endif
3755 /* Confirm if we can do a TGS for krbtgt/trusted_dns no CANON */
3756 ZERO_STRUCT(ctx->counts);
3757 k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3758 ctx->opt_nocanon,
3759 ctx->krbtgt_ccache,
3760 ctx->krbtgt_trust_dns,
3761 &ctx->krbtgt_trust_dns_creds);
3762 assertion_message = talloc_asprintf(ctx,
3763 "krb5_get_creds(%s, nocanon) for failed: "
3764 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3765 krbtgt_trust_dns_string,
3766 k5ret,
3767 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3768 k5ret, ctx),
3769 trusted->trust_direction,
3770 trusted->trust_type,
3771 trusted->trust_attributes,
3772 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3773 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3774 #ifdef USING_EMBEDDED_HEIMDAL
3775 torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3776 torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
3777 #else
3778 torture_assert_int_equal(tctx, ctx->counts.io, 2, assertion_message);
3779 torture_assert_int_equal(tctx, ctx->counts.ok, 2, assertion_message);
3780 #endif
3782 k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3783 ctx->krbtgt_trust_dns_creds->server,
3784 #ifdef USING_EMBEDDED_HEIMDAL
3785 ctx->krbtgt_trust_dns);
3786 #else
3787 ctx->krbtgt_trust_realm);
3788 #endif
3789 torture_assert(tctx, k5ok, assertion_message);
3790 type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3791 ctx->krbtgt_trust_dns_creds->server);
3792 torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3794 /* Confirm if we have the referral ticket in the cache */
3795 krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3796 &ctx->krbtgt_referral_creds);
3797 k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3798 ctx->krbtgt_ccache,
3800 ctx->krbtgt_trust_realm_creds,
3801 &ctx->krbtgt_referral_creds);
3802 assertion_message = talloc_asprintf(ctx,
3803 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3804 krbtgt_trust_realm_string,
3805 k5ret,
3806 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3807 k5ret, ctx));
3808 #ifdef USING_EMBEDDED_HEIMDAL
3809 torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
3810 #else
3811 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3813 k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3814 ctx->krbtgt_referral_creds.server,
3815 ctx->krbtgt_trust_realm);
3816 torture_assert(tctx, k5ok, assertion_message);
3817 type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3818 ctx->krbtgt_referral_creds.server);
3819 torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3821 /* Delete the referral ticket from the cache */
3822 k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
3823 ctx->krbtgt_ccache,
3825 &ctx->krbtgt_referral_creds);
3826 assertion_message = talloc_asprintf(ctx,
3827 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
3828 krbtgt_trust_realm_string,
3829 k5ret,
3830 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3831 k5ret, ctx));
3832 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3833 #endif
3835 /* Confirm if we can do a TGS for krbtgt/NETBIOS with CANON */
3836 ZERO_STRUCT(ctx->counts);
3837 k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3838 ctx->opt_canon,
3839 ctx->krbtgt_ccache,
3840 ctx->krbtgt_trust_netbios,
3841 &ctx->krbtgt_trust_netbios_creds);
3842 assertion_message = talloc_asprintf(ctx,
3843 "krb5_get_creds(%s, canon) for failed: "
3844 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3845 krbtgt_trust_netbios_string,
3846 k5ret,
3847 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3848 k5ret, ctx),
3849 trusted->trust_direction,
3850 trusted->trust_type,
3851 trusted->trust_attributes,
3852 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3853 #ifdef USING_EMBEDDED_HEIMDAL
3854 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3855 #else
3856 torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3857 #endif
3858 torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3859 torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
3861 /* Confirm if we have the referral ticket in the cache */
3862 krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3863 &ctx->krbtgt_referral_creds);
3864 k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3865 ctx->krbtgt_ccache,
3867 ctx->krbtgt_trust_realm_creds,
3868 &ctx->krbtgt_referral_creds);
3869 assertion_message = talloc_asprintf(ctx,
3870 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3871 krbtgt_trust_netbios_string,
3872 k5ret,
3873 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3874 k5ret, ctx));
3875 #ifdef USING_EMBEDDED_HEIMDAL
3876 torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
3877 #else
3878 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3880 k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3881 ctx->krbtgt_referral_creds.server,
3882 ctx->krbtgt_trust_realm);
3883 torture_assert(tctx, k5ok, assertion_message);
3884 type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3885 ctx->krbtgt_referral_creds.server);
3886 torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3888 /* Delete the referral ticket from the cache */
3889 k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
3890 ctx->krbtgt_ccache,
3892 &ctx->krbtgt_referral_creds);
3893 assertion_message = talloc_asprintf(ctx,
3894 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
3895 krbtgt_trust_realm_string,
3896 k5ret,
3897 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3898 k5ret, ctx));
3899 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3900 #endif
3902 /* Confirm if we can do a TGS for krbtgt/NETBIOS no CANON */
3903 ZERO_STRUCT(ctx->counts);
3904 k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3905 ctx->opt_nocanon,
3906 ctx->krbtgt_ccache,
3907 ctx->krbtgt_trust_netbios,
3908 &ctx->krbtgt_trust_netbios_creds);
3909 assertion_message = talloc_asprintf(ctx,
3910 "krb5_get_creds(%s, nocanon) for failed: "
3911 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3912 krbtgt_trust_netbios_string,
3913 k5ret,
3914 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3915 k5ret, ctx),
3916 trusted->trust_direction,
3917 trusted->trust_type,
3918 trusted->trust_attributes,
3919 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3920 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3921 #ifdef USING_EMBEDDED_HEIMDAL
3922 torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3923 torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
3924 #else
3925 torture_assert_int_equal(tctx, ctx->counts.io, 2, assertion_message);
3926 torture_assert_int_equal(tctx, ctx->counts.ok, 2, assertion_message);
3927 #endif
3929 k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3930 ctx->krbtgt_trust_netbios_creds->server,
3931 #ifdef USING_EMBEDDED_HEIMDAL
3932 ctx->krbtgt_trust_netbios);
3933 #else
3934 ctx->krbtgt_trust_realm);
3935 #endif
3936 torture_assert(tctx, k5ok, assertion_message);
3937 type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3938 ctx->krbtgt_trust_netbios_creds->server);
3939 torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3941 /* Confirm if we have the referral ticket in the cache */
3942 krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3943 &ctx->krbtgt_referral_creds);
3944 k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3945 ctx->krbtgt_ccache,
3947 ctx->krbtgt_trust_realm_creds,
3948 &ctx->krbtgt_referral_creds);
3949 assertion_message = talloc_asprintf(ctx,
3950 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3951 krbtgt_trust_realm_string,
3952 k5ret,
3953 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3954 k5ret, ctx));
3955 #ifdef USING_EMBEDDED_HEIMDAL
3956 torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
3957 #else
3958 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3960 k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3961 ctx->krbtgt_referral_creds.server,
3962 ctx->krbtgt_trust_realm);
3963 torture_assert(tctx, k5ok, assertion_message);
3964 type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3965 ctx->krbtgt_referral_creds.server);
3966 torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3968 /* Delete the referral ticket from the cache */
3969 k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
3970 ctx->krbtgt_ccache,
3972 &ctx->krbtgt_referral_creds);
3973 assertion_message = talloc_asprintf(ctx,
3974 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
3975 krbtgt_trust_realm_string,
3976 k5ret,
3977 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3978 k5ret, ctx));
3979 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3980 #endif
3982 cifs_trust_dns_string = talloc_asprintf(ctx, "cifs/%s@%s",
3983 trusted_dns_name, realm);
3984 torture_assert_int_equal(tctx,
3985 smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3986 &ctx->cifs_trust_dns,
3987 realm, "cifs",
3988 trusted_dns_name, NULL),
3989 0, "smb_krb5_make_principal failed");
3991 /* Confirm if we get krbtgt/trusted_realm back when asking for cifs/trusted_realm */
3992 ZERO_STRUCT(ctx->counts);
3993 k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3994 ctx->opt_canon,
3995 ctx->krbtgt_ccache,
3996 ctx->cifs_trust_dns,
3997 &ctx->cifs_trust_dns_creds);
3998 assertion_message = talloc_asprintf(ctx,
3999 "krb5_get_creds(%s) for failed: (%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
4000 cifs_trust_dns_string,
4001 k5ret,
4002 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4003 k5ret, ctx),
4004 trusted->trust_direction,
4005 trusted->trust_type,
4006 trusted->trust_attributes,
4007 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
4008 torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
4009 #ifdef USING_EMBEDDED_HEIMDAL
4010 torture_assert_int_equal(tctx, ctx->counts.io, 2, assertion_message);
4011 torture_assert_int_equal(tctx, ctx->counts.ok, 2, assertion_message);
4012 #else
4013 torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
4014 torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
4015 #endif
4017 /* Confirm if we have the referral ticket in the cache */
4018 krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
4019 &ctx->krbtgt_referral_creds);
4020 k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
4021 ctx->krbtgt_ccache,
4023 ctx->krbtgt_trust_realm_creds,
4024 &ctx->krbtgt_referral_creds);
4025 assertion_message = talloc_asprintf(ctx,
4026 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
4027 krbtgt_trust_realm_string,
4028 k5ret,
4029 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4030 k5ret, ctx));
4031 #ifdef USING_EMBEDDED_HEIMDAL
4032 torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
4033 #else
4034 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
4036 k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
4037 ctx->krbtgt_referral_creds.server,
4038 ctx->krbtgt_trust_realm);
4039 torture_assert(tctx, k5ok, assertion_message);
4040 type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
4041 ctx->krbtgt_referral_creds.server);
4042 torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
4044 /* Delete the referral ticket from the cache */
4045 k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
4046 ctx->krbtgt_ccache,
4048 &ctx->krbtgt_referral_creds);
4049 assertion_message = talloc_asprintf(ctx,
4050 "krb5_cc_remove_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 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
4056 #endif
4058 cifs_trust_netbios_string = talloc_asprintf(ctx, "cifs/%s@%s",
4059 trusted_netbios_name, realm);
4060 torture_assert_int_equal(tctx,
4061 smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
4062 &ctx->cifs_trust_netbios,
4063 realm, "cifs",
4064 trusted_netbios_name, NULL),
4065 0, "smb_krb5_make_principal failed");
4067 /* Confirm if we get krbtgt/trusted_realm back when asking for cifs/trusted_realm */
4068 ZERO_STRUCT(ctx->counts);
4069 k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
4070 ctx->opt_canon,
4071 ctx->krbtgt_ccache,
4072 ctx->cifs_trust_netbios,
4073 &ctx->cifs_trust_netbios_creds);
4074 assertion_message = talloc_asprintf(ctx,
4075 "krb5_get_creds(%s) for failed: (%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
4076 cifs_trust_netbios_string,
4077 k5ret,
4078 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4079 k5ret, ctx),
4080 trusted->trust_direction,
4081 trusted->trust_type,
4082 trusted->trust_attributes,
4083 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
4084 torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
4085 #ifdef USING_EMBEDDED_HEIMDAL
4086 torture_assert_int_equal(tctx, ctx->counts.io, 2, assertion_message);
4087 torture_assert_int_equal(tctx, ctx->counts.ok, 2, assertion_message);
4088 #else
4089 torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
4090 torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
4091 #endif
4093 /* Confirm if we have the referral ticket in the cache */
4094 krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
4095 &ctx->krbtgt_referral_creds);
4096 k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
4097 ctx->krbtgt_ccache,
4099 ctx->krbtgt_trust_realm_creds,
4100 &ctx->krbtgt_referral_creds);
4101 assertion_message = talloc_asprintf(ctx,
4102 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
4103 krbtgt_trust_realm_string,
4104 k5ret,
4105 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4106 k5ret, ctx));
4107 #ifdef USING_EMBEDDED_HEIMDAL
4108 torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
4109 #else
4110 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
4112 k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
4113 ctx->krbtgt_referral_creds.server,
4114 ctx->krbtgt_trust_realm);
4115 torture_assert(tctx, k5ok, assertion_message);
4116 type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
4117 ctx->krbtgt_referral_creds.server);
4118 torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
4120 /* Delete the referral ticket from the cache */
4121 k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
4122 ctx->krbtgt_ccache,
4124 &ctx->krbtgt_referral_creds);
4125 assertion_message = talloc_asprintf(ctx,
4126 "krb5_cc_remove_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 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
4132 #endif
4134 drs_trust_dns_string = talloc_asprintf(ctx,
4135 "E3514235-4B06-11D1-AB04-00C04FC2DCD2/%s/%s@%s",
4136 workstation, trusted_dns_name, realm);
4137 torture_assert_int_equal(tctx,
4138 smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
4139 &ctx->drs_trust_dns,
4140 realm, "E3514235-4B06-11D1-AB04-00C04FC2DCD2",
4141 workstation, trusted_dns_name, NULL),
4142 0, "smb_krb5_make_principal failed");
4144 /* Confirm if we get krbtgt/trusted_realm back when asking for a 3 part principal */
4145 ZERO_STRUCT(ctx->counts);
4146 k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
4147 ctx->opt_canon,
4148 ctx->krbtgt_ccache,
4149 ctx->drs_trust_dns,
4150 &ctx->drs_trust_dns_creds);
4151 assertion_message = talloc_asprintf(ctx,
4152 "krb5_get_creds(%s) for failed: (%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
4153 drs_trust_dns_string,
4154 k5ret,
4155 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4156 k5ret, ctx),
4157 trusted->trust_direction,
4158 trusted->trust_type,
4159 trusted->trust_attributes,
4160 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
4161 torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
4162 #ifdef USING_EMBEDDED_HEIMDAL
4163 torture_assert_int_equal(tctx, ctx->counts.io, 2, assertion_message);
4164 torture_assert_int_equal(tctx, ctx->counts.ok, 2, assertion_message);
4165 #else
4166 torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
4167 torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
4168 #endif
4170 /* Confirm if we have the referral ticket in the cache */
4171 krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
4172 &ctx->krbtgt_referral_creds);
4173 k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
4174 ctx->krbtgt_ccache,
4176 ctx->krbtgt_trust_realm_creds,
4177 &ctx->krbtgt_referral_creds);
4178 assertion_message = talloc_asprintf(ctx,
4179 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
4180 krbtgt_trust_realm_string,
4181 k5ret,
4182 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4183 k5ret, ctx));
4184 #ifdef USING_EMBEDDED_HEIMDAL
4185 torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
4186 #else
4187 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
4189 k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
4190 ctx->krbtgt_referral_creds.server,
4191 ctx->krbtgt_trust_realm);
4192 torture_assert(tctx, k5ok, assertion_message);
4193 type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
4194 ctx->krbtgt_referral_creds.server);
4195 torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
4197 /* Delete the referral ticket from the cache */
4198 k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
4199 ctx->krbtgt_ccache,
4201 &ctx->krbtgt_referral_creds);
4202 assertion_message = talloc_asprintf(ctx,
4203 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
4204 krbtgt_trust_realm_string,
4205 k5ret,
4206 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4207 k5ret, ctx));
4208 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
4209 #endif
4211 drs_trust_netbios_string = talloc_asprintf(ctx,
4212 "E3514235-4B06-11D1-AB04-00C04FC2DCD2/%s/%s@%s",
4213 workstation, trusted_netbios_name, realm);
4214 torture_assert_int_equal(tctx,
4215 smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
4216 &ctx->drs_trust_netbios,
4217 realm, "E3514235-4B06-11D1-AB04-00C04FC2DCD2",
4218 workstation, trusted_netbios_name, NULL),
4219 0, "smb_krb5_make_principal failed");
4221 /* Confirm if we get krbtgt/trusted_realm back when asking for a 3 part principal */
4222 ZERO_STRUCT(ctx->counts);
4223 k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
4224 ctx->opt_canon,
4225 ctx->krbtgt_ccache,
4226 ctx->drs_trust_netbios,
4227 &ctx->drs_trust_netbios_creds);
4228 assertion_message = talloc_asprintf(ctx,
4229 "krb5_get_creds(%s) for failed: (%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
4230 drs_trust_netbios_string,
4231 k5ret,
4232 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4233 k5ret, ctx),
4234 trusted->trust_direction,
4235 trusted->trust_type,
4236 trusted->trust_attributes,
4237 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
4238 torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
4239 #ifdef USING_EMBEDDED_HEIMDAL
4240 torture_assert_int_equal(tctx, ctx->counts.io, 2, assertion_message);
4241 torture_assert_int_equal(tctx, ctx->counts.ok, 2, assertion_message);
4242 #else
4243 torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
4244 torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
4245 #endif
4247 /* Confirm if we have the referral ticket in the cache */
4248 krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
4249 &ctx->krbtgt_referral_creds);
4250 k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
4251 ctx->krbtgt_ccache,
4253 ctx->krbtgt_trust_realm_creds,
4254 &ctx->krbtgt_referral_creds);
4255 assertion_message = talloc_asprintf(ctx,
4256 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
4257 krbtgt_trust_realm_string,
4258 k5ret,
4259 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4260 k5ret, ctx));
4261 #ifdef USING_EMBEDDED_HEIMDAL
4262 torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
4263 #else
4264 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
4266 k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
4267 ctx->krbtgt_referral_creds.server,
4268 ctx->krbtgt_trust_realm);
4269 torture_assert(tctx, k5ok, assertion_message);
4270 type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
4271 ctx->krbtgt_referral_creds.server);
4272 torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
4274 /* Delete the referral ticket from the cache */
4275 k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
4276 ctx->krbtgt_ccache,
4278 &ctx->krbtgt_referral_creds);
4279 assertion_message = talloc_asprintf(ctx,
4280 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
4281 krbtgt_trust_realm_string,
4282 k5ret,
4283 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4284 k5ret, ctx));
4285 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
4286 #endif
4288 four_trust_dns_string = talloc_asprintf(ctx, "four/tree/two/%s@%s",
4289 trusted_dns_name, realm);
4290 torture_assert_int_equal(tctx,
4291 smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
4292 &ctx->four_trust_dns,
4293 realm, "four", "tree", "two",
4294 trusted_dns_name, NULL),
4295 0, "smb_krb5_make_principal failed");
4297 /* Confirm if we get an error back for a 4 part principal */
4298 ZERO_STRUCT(ctx->counts);
4299 k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
4300 ctx->opt_canon,
4301 ctx->krbtgt_ccache,
4302 ctx->four_trust_dns,
4303 &ctx->four_trust_dns_creds);
4304 assertion_message = talloc_asprintf(ctx,
4305 "krb5_get_creds(%s) for failed: (%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
4306 four_trust_dns_string,
4307 k5ret,
4308 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4309 k5ret, ctx),
4310 trusted->trust_direction,
4311 trusted->trust_type,
4312 trusted->trust_attributes,
4313 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
4314 torture_assert_int_equal(tctx, k5ret, KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN, assertion_message);
4315 #ifdef USING_EMBEDDED_HEIMDAL
4316 torture_assert_int_equal(tctx, ctx->counts.io, 2, assertion_message);
4317 torture_assert_int_equal(tctx, ctx->counts.error_io, 2, assertion_message);
4318 #else
4319 torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
4320 torture_assert_int_equal(tctx, ctx->counts.error_io, 1, assertion_message);
4321 #endif
4322 torture_assert_int_equal(tctx, KRB5_ERROR_CODE(&ctx->error), 7, assertion_message);
4324 /* Confirm if we have no referral ticket in the cache */
4325 krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
4326 &ctx->krbtgt_referral_creds);
4327 k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
4328 ctx->krbtgt_ccache,
4330 ctx->krbtgt_trust_realm_creds,
4331 &ctx->krbtgt_referral_creds);
4332 assertion_message = talloc_asprintf(ctx,
4333 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
4334 krbtgt_trust_realm_string,
4335 k5ret,
4336 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4337 k5ret, ctx));
4338 torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
4340 TALLOC_FREE(ctx);
4341 return true;
4343 #endif
4345 static bool check_dom_trust_pw(struct dcerpc_pipe *p,
4346 struct torture_context *tctx,
4347 const char *our_netbios_name,
4348 const char *our_dns_name,
4349 enum netr_SchannelType secure_channel_type,
4350 const struct lsa_TrustDomainInfoInfoEx *trusted,
4351 const char *previous_password,
4352 const char *current_password,
4353 uint32_t current_version,
4354 const char *next_password,
4355 uint32_t next_version,
4356 bool expected_result)
4358 struct cli_credentials *incoming_creds;
4359 char *server_name = NULL;
4360 char *account = NULL;
4361 char *principal = NULL;
4362 char *workstation = NULL;
4363 const char *binding = torture_setting_string(tctx, "binding", NULL);
4364 const char *host = torture_setting_string(tctx, "host", NULL);
4365 const char *ip;
4366 struct nbt_name nbt_name;
4367 struct dcerpc_binding *b2;
4368 struct netlogon_creds_CredentialState *creds;
4369 struct samr_CryptPassword samr_crypt_password;
4370 struct netr_CryptPassword netr_crypt_password;
4371 struct netr_Authenticator req_auth;
4372 struct netr_Authenticator rep_auth;
4373 struct netr_ServerPasswordSet2 s;
4374 struct dcerpc_pipe *p1 = NULL;
4375 struct dcerpc_pipe *p2 = NULL;
4376 NTSTATUS status;
4377 bool ok;
4378 int rc;
4379 const char *trusted_netbios_name = trusted->netbios_name.string;
4380 const char *trusted_dns_name = trusted->domain_name.string;
4381 struct tsocket_address *dest_addr;
4382 struct netlogon_samlogon_response **responses = NULL;
4383 struct netlogon_samlogon_response *resp = NULL;
4384 enum dcerpc_AuthType auth_type;
4385 enum dcerpc_AuthLevel auth_level;
4387 incoming_creds = cli_credentials_init(tctx);
4388 torture_assert(tctx, incoming_creds, "cli_credentials_init");
4390 cli_credentials_set_domain(incoming_creds, our_netbios_name, CRED_SPECIFIED);
4391 cli_credentials_set_realm(incoming_creds, our_dns_name, CRED_SPECIFIED);
4393 if (secure_channel_type == SEC_CHAN_DNS_DOMAIN) {
4394 account = talloc_asprintf(tctx, "%s.", trusted_dns_name);
4395 torture_assert(tctx, account, __location__);
4397 principal = talloc_asprintf(tctx, "%s$@%s",
4398 trusted_netbios_name,
4399 cli_credentials_get_realm(incoming_creds));
4400 torture_assert(tctx, principal, __location__);
4402 workstation = talloc_asprintf(tctx, "%sUP",
4403 trusted_netbios_name);
4404 torture_assert(tctx, workstation, __location__);
4405 } else {
4406 account = talloc_asprintf(tctx, "%s$", trusted_netbios_name);
4407 torture_assert(tctx, account, __location__);
4409 workstation = talloc_asprintf(tctx, "%sDOWN",
4410 trusted_netbios_name);
4411 torture_assert(tctx, workstation, __location__);
4414 cli_credentials_set_username(incoming_creds, account, CRED_SPECIFIED);
4415 if (principal != NULL) {
4416 cli_credentials_set_principal(incoming_creds, principal,
4417 CRED_SPECIFIED);
4419 cli_credentials_set_kvno(incoming_creds, current_version);
4420 cli_credentials_set_password(incoming_creds, current_password, CRED_SPECIFIED);
4421 cli_credentials_set_old_password(incoming_creds, previous_password, CRED_SPECIFIED);
4422 cli_credentials_set_workstation(incoming_creds, workstation, CRED_SPECIFIED);
4423 cli_credentials_set_secure_channel_type(incoming_creds, secure_channel_type);
4425 make_nbt_name_server(&nbt_name, host);
4427 status = resolve_name_ex(lpcfg_resolve_context(tctx->lp_ctx),
4428 0, 0, &nbt_name, tctx, &ip, tctx->ev);
4429 torture_assert_ntstatus_ok(tctx, status,
4430 talloc_asprintf(tctx,"Failed to resolve %s: %s",
4431 nbt_name.name, nt_errstr(status)));
4433 rc = tsocket_address_inet_from_strings(
4434 tctx, "ip", ip, 389, &dest_addr);
4435 torture_assert_int_equal(
4436 tctx,
4439 talloc_asprintf(tctx,
4440 "tsocket_address_inet_from_strings failed "
4441 "parsing %s:%d",
4442 host,
4443 389));
4445 status = netlogon_pings(tctx, /* mem_ctx */
4446 lpcfg_client_netlogon_ping_protocol(
4447 tctx->lp_ctx), /* proto */
4448 &dest_addr, /* servers */
4449 1, /* num_servers */
4450 (struct netlogon_ping_filter){
4451 .ntversion = NETLOGON_NT_VERSION_5 |
4452 NETLOGON_NT_VERSION_5EX,
4453 .acct_ctrl = (secure_channel_type ==
4454 SEC_CHAN_DNS_DOMAIN)
4455 ? ACB_AUTOLOCK
4456 : ACB_DOMTRUST,
4457 .user = account,
4459 1, /* min_servers */
4460 tevent_timeval_current_ofs(2, 0), /* timeout */
4461 &responses);
4462 torture_assert_ntstatus_ok(tctx, status, "netlogon_pings");
4464 resp = responses[0];
4466 torture_assert_int_equal(tctx,
4467 resp->ntver,
4468 NETLOGON_NT_VERSION_5EX,
4469 "ntver");
4470 torture_assert_int_equal(tctx,
4471 resp->data.nt5_ex.nt_version,
4472 NETLOGON_NT_VERSION_1 |
4473 NETLOGON_NT_VERSION_5EX,
4474 "nt_version");
4475 torture_assert_int_equal(tctx,
4476 resp->data.nt5_ex.command,
4477 LOGON_SAM_LOGON_RESPONSE_EX,
4478 "command");
4479 torture_assert_str_equal(tctx,
4480 resp->data.nt5_ex.user_name,
4481 account,
4482 "user_name");
4483 server_name = talloc_asprintf(tctx,
4484 "\\\\%s",
4485 resp->data.nt5_ex.pdc_dns_name);
4486 torture_assert(tctx, server_name, __location__);
4488 status = dcerpc_parse_binding(tctx, binding, &b2);
4489 torture_assert_ntstatus_ok(tctx, status, "Bad binding string");
4491 status = dcerpc_pipe_connect_b(tctx, &p1, b2,
4492 &ndr_table_netlogon,
4493 cli_credentials_init_anon(tctx),
4494 tctx->ev, tctx->lp_ctx);
4495 torture_assert_ntstatus_ok(tctx, status, "dcerpc_pipe_connect_b");
4497 ok = check_pw_with_ServerAuthenticate3(p1, tctx,
4498 NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES,
4499 server_name,
4500 incoming_creds, &creds);
4501 torture_assert_int_equal(tctx, ok, expected_result,
4502 "check_pw_with_ServerAuthenticate3");
4503 if (expected_result == true) {
4504 ok = test_SetupCredentialsPipe(p1, tctx, incoming_creds, creds,
4505 DCERPC_SIGN | DCERPC_SEAL, &p2);
4506 torture_assert_int_equal(tctx, ok, true,
4507 "test_SetupCredentialsPipe");
4509 TALLOC_FREE(p1);
4511 if (trusted->trust_type != LSA_TRUST_TYPE_DOWNLEVEL) {
4512 #ifdef SAMBA4_USES_HEIMDAL
4513 ok = check_pw_with_krb5(tctx, incoming_creds, trusted);
4514 torture_assert_int_equal(tctx, ok, expected_result,
4515 "check_pw_with_krb5");
4516 #else
4517 torture_comment(tctx, "skipping check_pw_with_krb5 for MIT Kerberos build");
4518 #endif
4521 if (expected_result != true || next_password == NULL) {
4522 TALLOC_FREE(p2);
4523 return true;
4527 * netr_ServerPasswordSet2
4529 ok = encode_pw_buffer(samr_crypt_password.data,
4530 next_password, STR_UNICODE);
4531 torture_assert(tctx, ok, "encode_pw_buffer");
4533 if (next_version != 0) {
4534 struct NL_PASSWORD_VERSION version;
4535 uint32_t len = IVAL(samr_crypt_password.data, 512);
4536 uint32_t ofs = 512 - len;
4537 uint8_t *ptr;
4539 ofs -= 12;
4541 version.ReservedField = 0;
4542 version.PasswordVersionNumber = next_version;
4543 version.PasswordVersionPresent =
4544 NETLOGON_PASSWORD_VERSION_NUMBER_PRESENT;
4546 ptr = samr_crypt_password.data + ofs;
4547 SIVAL(ptr, 0, version.ReservedField);
4548 SIVAL(ptr, 4, version.PasswordVersionNumber);
4549 SIVAL(ptr, 8, version.PasswordVersionPresent);
4552 netlogon_creds_client_authenticator(creds, &req_auth);
4553 ZERO_STRUCT(rep_auth);
4555 dcerpc_binding_handle_auth_info(p2->binding_handle,
4556 &auth_type,
4557 &auth_level);
4558 status = netlogon_creds_encrypt_samr_CryptPassword(creds,
4559 &samr_crypt_password,
4560 auth_type,
4561 auth_level);
4562 torture_assert_ntstatus_ok(tctx, status, "encrypt_samr_CryptPassword");
4564 memcpy(netr_crypt_password.data,
4565 samr_crypt_password.data, 512);
4566 netr_crypt_password.length = IVAL(samr_crypt_password.data, 512);
4569 s.in.server_name = server_name;
4570 s.in.account_name = cli_credentials_get_username(incoming_creds);
4571 s.in.secure_channel_type = cli_credentials_get_secure_channel_type(incoming_creds);
4572 s.in.computer_name = cli_credentials_get_workstation(incoming_creds);
4573 s.in.credential = &req_auth;
4574 s.in.new_password = &netr_crypt_password;
4575 s.out.return_authenticator = &rep_auth;
4576 status = dcerpc_netr_ServerPasswordSet2_r(p2->binding_handle, tctx, &s);
4577 torture_assert_ntstatus_ok(tctx, status, "failed to set password");
4579 ok = netlogon_creds_client_check(creds, &rep_auth.cred);
4580 torture_assert(tctx, ok, "netlogon_creds_client_check");
4582 cli_credentials_set_kvno(incoming_creds, next_version);
4583 cli_credentials_set_password(incoming_creds, next_password, CRED_SPECIFIED);
4584 cli_credentials_set_old_password(incoming_creds, current_password, CRED_SPECIFIED);
4586 TALLOC_FREE(p2);
4587 status = dcerpc_pipe_connect_b(tctx, &p2, b2,
4588 &ndr_table_netlogon,
4589 cli_credentials_init_anon(tctx),
4590 tctx->ev, tctx->lp_ctx);
4591 torture_assert_ntstatus_ok(tctx, status, "dcerpc_pipe_connect_b");
4593 ok = check_pw_with_ServerAuthenticate3(p2, tctx,
4594 NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES,
4595 server_name,
4596 incoming_creds, &creds);
4597 torture_assert(tctx, ok, "check_pw_with_ServerAuthenticate3 with changed password");
4599 if (trusted->trust_type != LSA_TRUST_TYPE_DOWNLEVEL) {
4600 #if SAMBA4_USES_HEIMDAL
4601 ok = check_pw_with_krb5(tctx, incoming_creds, trusted);
4602 torture_assert(tctx, ok, "check_pw_with_krb5 with changed password");
4603 #else
4604 torture_comment(tctx, "skipping check_pw_with_krb5 for MIT Kerberos build");
4605 #endif
4608 TALLOC_FREE(p2);
4609 return true;
4612 enum ex_call {
4613 CREATE_TRUSTED_DOMAIN_EX1 = 1,
4614 CREATE_TRUSTED_DOMAIN_EX2 = 2,
4615 CREATE_TRUSTED_DOMAIN_EX3 = 3,
4618 static bool test_CreateTrustedDomainEx_common(struct dcerpc_pipe *p,
4619 struct torture_context *tctx,
4620 struct policy_handle *handle,
4621 uint32_t num_trusts,
4622 enum ex_call ex_call)
4624 NTSTATUS status;
4625 bool ret = true;
4626 struct lsa_QueryInfoPolicy2 p2;
4627 union lsa_PolicyInformation *our_info = NULL;
4628 struct lsa_CreateTrustedDomainEx r;
4629 struct lsa_CreateTrustedDomainEx2 r2;
4630 struct lsa_CreateTrustedDomainEx3 r3 = {
4631 .in = {
4632 .access_mask = 0,
4635 struct lsa_TrustDomainInfoInfoEx trustinfo;
4636 struct lsa_TrustDomainInfoAuthInfoInternal *authinfo_internal = NULL;
4637 struct lsa_TrustDomainInfoAuthInfoInternalAES
4638 *authinfo_internal_aes = NULL;
4639 struct lsa_TrustDomainInfoAuthInfo *authinfo = NULL;
4640 struct dom_sid **domsid;
4641 struct policy_handle *trustdom_handle;
4642 struct lsa_QueryTrustedDomainInfo q;
4643 union lsa_TrustedDomainInfo *info = NULL;
4644 DATA_BLOB session_key;
4645 int i;
4646 struct dcerpc_binding_handle *b = p->binding_handle;
4647 const char *id = "0";
4648 const char *incoming_v00 = TRUSTPW "InV00";
4649 const char *incoming_v0 = TRUSTPW "InV0";
4650 const char *incoming_v1 = TRUSTPW "InV1";
4651 const char *incoming_v2 = TRUSTPW "InV2";
4652 const char *incoming_v40 = TRUSTPW "InV40";
4653 const char *outgoing_v00 = TRUSTPW "OutV00";
4654 const char *outgoing_v0 = TRUSTPW "OutV0";
4656 switch (ex_call) {
4657 case CREATE_TRUSTED_DOMAIN_EX3:
4658 torture_comment(
4659 tctx,
4660 "\nTesting CreateTrustedDomainEx3 for %d domains\n",
4661 num_trusts
4663 id = "4";
4664 break;
4665 case CREATE_TRUSTED_DOMAIN_EX2:
4666 torture_comment(
4667 tctx,
4668 "\nTesting CreateTrustedDomainEx2 for %d domains\n",
4669 num_trusts
4671 id = "3";
4672 break;
4673 case CREATE_TRUSTED_DOMAIN_EX1:
4674 torture_comment(
4675 tctx,
4676 "\nTesting CreateTrustedDomainEx for %d domains\n",
4677 num_trusts
4679 id = "2";
4680 break;
4683 domsid = talloc_array(tctx, struct dom_sid *, num_trusts);
4684 trustdom_handle = talloc_array(tctx, struct policy_handle, num_trusts);
4686 status = dcerpc_binding_handle_transport_session_key(b, tctx, &session_key);
4687 if (!NT_STATUS_IS_OK(status)) {
4688 torture_comment(tctx, "transport_session_key failed - %s\n", nt_errstr(status));
4689 return false;
4692 ZERO_STRUCT(p2);
4693 p2.in.handle = handle;
4694 p2.in.level = LSA_POLICY_INFO_DNS;
4695 p2.out.info = &our_info;
4697 torture_assert_ntstatus_ok(tctx,
4698 dcerpc_lsa_QueryInfoPolicy2_r(b, tctx, &p2),
4699 "lsa_QueryInfoPolicy2 failed");
4700 torture_assert_ntstatus_ok(tctx, p2.out.result,
4701 "lsa_QueryInfoPolicy2 failed");
4702 torture_assert(tctx, our_info != NULL, "lsa_QueryInfoPolicy2 our_info");
4704 for (i=0; i< num_trusts; i++) {
4705 char *trust_name = talloc_asprintf(tctx, "TORTURE%s%02d", id, i);
4706 char *trust_name_dns = talloc_asprintf(tctx, "torturedom%s%02d.samba._none_.example.com", id, i);
4707 char *trust_sid = talloc_asprintf(tctx, "S-1-5-21-97398-379795-%s%02d", id, i);
4708 bool ok;
4710 domsid[i] = dom_sid_parse_talloc(tctx, trust_sid);
4712 trustinfo.sid = domsid[i];
4713 trustinfo.netbios_name.string = trust_name;
4714 trustinfo.domain_name.string = trust_name_dns;
4716 /* Create inbound, some outbound, and some
4717 * bi-directional trusts in a repeating pattern based
4718 * on i */
4720 /* 1 == inbound, 2 == outbound, 3 == both */
4721 trustinfo.trust_direction = (i % 3) + 1;
4723 /* Try different trust types too */
4725 /* 1 == downlevel (NT4), 2 == uplevel (ADS), 3 == MIT (kerberos but not AD) */
4726 trustinfo.trust_type = (((i / 3) + 1) % 3) + 1;
4728 trustinfo.trust_attributes = LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION;
4730 switch(ex_call) {
4731 case CREATE_TRUSTED_DOMAIN_EX3:
4732 ok = rpc_lsa_encrypt_trustdom_info_aes(
4733 tctx,
4734 incoming_v00,
4735 incoming_v0,
4736 outgoing_v00,
4737 outgoing_v0,
4738 session_key,
4739 &authinfo_internal_aes);
4740 if (!ok) {
4741 torture_comment(tctx,
4742 "gen_authinfo_internal failed");
4743 ret = false;
4746 r3.in.policy_handle = handle;
4747 r3.in.info = &trustinfo;
4748 r3.in.auth_info_internal = authinfo_internal_aes;
4749 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4750 r3.out.trustdom_handle = &trustdom_handle[i];
4752 torture_assert_ntstatus_ok(
4753 tctx,
4754 dcerpc_lsa_CreateTrustedDomainEx3_r(b,
4755 tctx,
4756 &r3),
4757 "CreateTrustedDomainEx3 failed");
4759 status = r3.out.result;
4760 break;
4761 case CREATE_TRUSTED_DOMAIN_EX2:
4762 ok = rpc_lsa_encrypt_trustdom_info(tctx,
4763 incoming_v00,
4764 incoming_v0,
4765 outgoing_v00,
4766 outgoing_v0,
4767 session_key,
4768 &authinfo_internal);
4769 if (!ok) {
4770 torture_comment(
4771 tctx,
4772 "rpc_lsa_encrypt_trustdom_info failed");
4773 ret = false;
4776 r2.in.policy_handle = handle;
4777 r2.in.info = &trustinfo;
4778 r2.in.auth_info_internal = authinfo_internal;
4779 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4780 r2.out.trustdom_handle = &trustdom_handle[i];
4782 torture_assert_ntstatus_ok(tctx,
4783 dcerpc_lsa_CreateTrustedDomainEx2_r(b, tctx, &r2),
4784 "CreateTrustedDomainEx2 failed");
4786 status = r2.out.result;
4787 break;
4788 case CREATE_TRUSTED_DOMAIN_EX1:
4789 ok = gen_authinfo(tctx,
4790 incoming_v00,
4791 incoming_v0,
4792 outgoing_v00,
4793 outgoing_v0,
4794 &authinfo);
4795 if (!ok) {
4796 torture_comment(tctx, "gen_authinfonfo failed");
4797 ret = false;
4800 r.in.policy_handle = handle;
4801 r.in.info = &trustinfo;
4802 r.in.auth_info = authinfo;
4803 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4804 r.out.trustdom_handle = &trustdom_handle[i];
4806 torture_assert_ntstatus_ok(tctx,
4807 dcerpc_lsa_CreateTrustedDomainEx_r(b, tctx, &r),
4808 "CreateTrustedDomainEx failed");
4810 status = r.out.result;
4811 break;
4814 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
4815 test_DeleteTrustedDomain(b, tctx, handle, trustinfo.netbios_name);
4817 switch (ex_call) {
4818 case CREATE_TRUSTED_DOMAIN_EX3:
4819 torture_assert_ntstatus_ok(
4820 tctx,
4821 dcerpc_lsa_CreateTrustedDomainEx3_r(
4822 b, tctx, &r3),
4823 "CreateTrustedDomainEx3 failed");
4824 status = r3.out.result;
4825 break;
4826 case CREATE_TRUSTED_DOMAIN_EX2:
4827 torture_assert_ntstatus_ok(
4828 tctx,
4829 dcerpc_lsa_CreateTrustedDomainEx2_r(
4830 b, tctx, &r2),
4831 "CreateTrustedDomainEx2 failed");
4832 status = r2.out.result;
4833 break;
4834 case CREATE_TRUSTED_DOMAIN_EX1:
4835 torture_assert_ntstatus_ok(
4836 tctx,
4837 dcerpc_lsa_CreateTrustedDomainEx_r(b,
4838 tctx,
4839 &r),
4840 "CreateTrustedDomainEx failed");
4841 status = r.out.result;
4842 break;
4845 if (!NT_STATUS_IS_OK(status)) {
4846 torture_comment(tctx,
4847 "CreateTrustedDomainEx(2|3) failed "
4848 "with status: %s\n",
4849 nt_errstr(status));
4850 ret = false;
4851 } else { /* For outbound and MIT trusts there is no trust account */
4852 if (trustinfo.trust_direction != 2 &&
4853 trustinfo.trust_type != 3) {
4855 if (torture_setting_bool(tctx, "samba3", false)) {
4856 torture_comment(tctx, "skipping trusted domain auth tests against samba3\n");
4857 } else if (ex_call == CREATE_TRUSTED_DOMAIN_EX1 &&
4858 torture_setting_bool(tctx, "samba4", false)) {
4859 torture_comment(tctx, "skipping CreateTrustedDomainEx trusted domain auth tests against samba4\n");
4861 } else {
4862 ok = check_dom_trust_pw(p, tctx,
4863 our_info->dns.name.string,
4864 our_info->dns.dns_domain.string,
4865 SEC_CHAN_DOMAIN,
4866 &trustinfo,
4867 NULL,
4868 "x" TRUSTPW "x", 0,
4869 NULL, 0,
4870 false);
4871 if (!ok) {
4872 torture_comment(tctx, "Password check passed unexpectedly\n");
4873 ret = false;
4875 ok = check_dom_trust_pw(p, tctx,
4876 our_info->dns.name.string,
4877 our_info->dns.dns_domain.string,
4878 SEC_CHAN_DOMAIN,
4879 &trustinfo,
4880 incoming_v00,
4881 incoming_v0, 0,
4882 incoming_v1, 1,
4883 true);
4884 if (!ok) {
4885 torture_comment(tctx, "Password check failed (SEC_CHAN_DOMAIN)\n");
4886 ret = false;
4888 ok = check_dom_trust_pw(p, tctx,
4889 our_info->dns.name.string,
4890 our_info->dns.dns_domain.string,
4891 SEC_CHAN_DNS_DOMAIN,
4892 &trustinfo,
4893 incoming_v0,
4894 incoming_v1, 1,
4895 incoming_v2, 2,
4896 true);
4897 if (!ok) {
4898 torture_comment(tctx, "Password check failed v2 (SEC_CHAN_DNS_DOMAIN)\n");
4899 ret = false;
4901 ok = check_dom_trust_pw(p, tctx,
4902 our_info->dns.name.string,
4903 our_info->dns.dns_domain.string,
4904 SEC_CHAN_DNS_DOMAIN,
4905 &trustinfo,
4906 incoming_v1,
4907 incoming_v2, 2,
4908 incoming_v40, 40,
4909 true);
4910 if (!ok) {
4911 torture_comment(tctx, "Password check failed v4 (SEC_CHAN_DNS_DOMAIN)\n");
4912 ret = false;
4917 q.in.trustdom_handle = &trustdom_handle[i];
4918 q.in.level = LSA_TRUSTED_DOMAIN_INFO_INFO_EX;
4919 q.out.info = &info;
4920 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfo_r(b, tctx, &q),
4921 "QueryTrustedDomainInfo failed");
4922 if (!NT_STATUS_IS_OK(q.out.result)) {
4923 torture_comment(tctx, "QueryTrustedDomainInfo level 1 failed - %s\n", nt_errstr(q.out.result));
4924 ret = false;
4925 } else if (!q.out.info) {
4926 torture_comment(tctx, "QueryTrustedDomainInfo level 1 failed to return an info pointer\n");
4927 ret = false;
4928 } else {
4929 if (strcmp(info->info_ex.domain_name.string, trustinfo.domain_name.string) != 0) {
4930 torture_comment(tctx, "QueryTrustedDomainInfo returned inconsistent long name: %s != %s\n",
4931 info->info_ex.domain_name.string, trustinfo.domain_name.string);
4932 ret = false;
4934 if (strcmp(info->info_ex.netbios_name.string, trustinfo.netbios_name.string) != 0) {
4935 torture_comment(tctx, "QueryTrustedDomainInfo returned inconsistent short name: %s != %s\n",
4936 info->info_ex.netbios_name.string, trustinfo.netbios_name.string);
4937 ret = false;
4939 if (info->info_ex.trust_type != trustinfo.trust_type) {
4940 torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n",
4941 trust_name, info->info_ex.trust_type, trustinfo.trust_type);
4942 ret = false;
4944 if (info->info_ex.trust_attributes != LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION) {
4945 torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n",
4946 trust_name, info->info_ex.trust_attributes, LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION);
4947 ret = false;
4949 if (info->info_ex.trust_direction != trustinfo.trust_direction) {
4950 torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n",
4951 trust_name, info->info_ex.trust_direction, trustinfo.trust_direction);
4952 ret = false;
4958 /* now that we have some domains to look over, we can test the enum calls */
4959 if (!test_EnumTrustDom(b, tctx, handle)) {
4960 torture_comment(tctx, "test_EnumTrustDom failed\n");
4961 ret = false;
4964 if (!test_EnumTrustDomEx(b, tctx, handle)) {
4965 torture_comment(tctx, "test_EnumTrustDomEx failed\n");
4966 ret = false;
4969 for (i=0; i<num_trusts; i++) {
4970 if (!test_DeleteTrustedDomainBySid(b, tctx, handle, domsid[i])) {
4971 torture_comment(tctx, "test_DeleteTrustedDomainBySid failed\n");
4972 ret = false;
4976 return ret;
4979 static bool test_CreateTrustedDomainEx3(struct dcerpc_pipe *p,
4980 struct torture_context *tctx,
4981 struct policy_handle *handle,
4982 uint32_t num_trusts)
4984 return test_CreateTrustedDomainEx_common(
4986 tctx,
4987 handle,
4988 num_trusts,
4989 CREATE_TRUSTED_DOMAIN_EX3
4993 static bool test_CreateTrustedDomainEx2(struct dcerpc_pipe *p,
4994 struct torture_context *tctx,
4995 struct policy_handle *handle,
4996 uint32_t num_trusts)
4998 return test_CreateTrustedDomainEx_common(
5000 tctx,
5001 handle,
5002 num_trusts,
5003 CREATE_TRUSTED_DOMAIN_EX2
5007 static bool test_CreateTrustedDomainEx(struct dcerpc_pipe *p,
5008 struct torture_context *tctx,
5009 struct policy_handle *handle,
5010 uint32_t num_trusts)
5012 return test_CreateTrustedDomainEx_common(
5014 tctx,
5015 handle,
5016 num_trusts,
5017 CREATE_TRUSTED_DOMAIN_EX1
5021 static bool test_QueryDomainInfoPolicy(struct dcerpc_binding_handle *b,
5022 struct torture_context *tctx,
5023 struct policy_handle *handle)
5025 struct lsa_QueryDomainInformationPolicy r;
5026 union lsa_DomainInformationPolicy *info = NULL;
5027 int i;
5028 bool ret = true;
5030 if (torture_setting_bool(tctx, "samba3", false)) {
5031 torture_skip(tctx, "skipping QueryDomainInformationPolicy test\n");
5034 torture_comment(tctx, "\nTesting QueryDomainInformationPolicy\n");
5036 for (i=2;i<4;i++) {
5037 r.in.handle = handle;
5038 r.in.level = i;
5039 r.out.info = &info;
5041 torture_comment(tctx, "\nTrying QueryDomainInformationPolicy level %d\n", i);
5043 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryDomainInformationPolicy_r(b, tctx, &r),
5044 "QueryDomainInformationPolicy failed");
5046 /* If the server does not support EFS, then this is the correct return */
5047 if (i == LSA_DOMAIN_INFO_POLICY_EFS && NT_STATUS_EQUAL(r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
5048 continue;
5049 } else if (!NT_STATUS_IS_OK(r.out.result)) {
5050 torture_comment(tctx, "QueryDomainInformationPolicy failed - %s\n", nt_errstr(r.out.result));
5051 ret = false;
5052 continue;
5056 return ret;
5060 static bool test_QueryInfoPolicyCalls( bool version2,
5061 struct dcerpc_binding_handle *b,
5062 struct torture_context *tctx,
5063 struct policy_handle *handle)
5065 struct lsa_QueryInfoPolicy r;
5066 union lsa_PolicyInformation *info = NULL;
5067 int i;
5068 bool ret = true;
5069 const char *call = talloc_asprintf(tctx, "QueryInfoPolicy%s", version2 ? "2":"");
5071 torture_comment(tctx, "\nTesting %s\n", call);
5073 if (version2 && torture_setting_bool(tctx, "samba3", false)) {
5074 torture_skip(tctx, "skipping QueryInfoPolicy2 tests\n");
5077 for (i=1;i<=14;i++) {
5078 r.in.handle = handle;
5079 r.in.level = i;
5080 r.out.info = &info;
5082 torture_comment(tctx, "\nTrying %s level %d\n", call, i);
5084 if (version2)
5085 /* We can perform the cast, because both types are
5086 structurally equal */
5087 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryInfoPolicy2_r(b, tctx,
5088 (struct lsa_QueryInfoPolicy2*) &r),
5089 "QueryInfoPolicy2 failed");
5090 else
5091 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryInfoPolicy_r(b, tctx, &r),
5092 "QueryInfoPolicy2 failed");
5094 switch (i) {
5095 case LSA_POLICY_INFO_MOD:
5096 case LSA_POLICY_INFO_AUDIT_FULL_SET:
5097 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
5098 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
5099 torture_comment(tctx, "Server should have failed level %u: %s\n", i, nt_errstr(r.out.result));
5100 ret = false;
5102 break;
5103 case LSA_POLICY_INFO_DOMAIN:
5104 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
5105 case LSA_POLICY_INFO_REPLICA:
5106 case LSA_POLICY_INFO_QUOTA:
5107 case LSA_POLICY_INFO_ROLE:
5108 case LSA_POLICY_INFO_AUDIT_LOG:
5109 case LSA_POLICY_INFO_AUDIT_EVENTS:
5110 case LSA_POLICY_INFO_PD:
5111 if (!NT_STATUS_IS_OK(r.out.result)) {
5112 torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
5113 ret = false;
5115 break;
5116 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
5117 case LSA_POLICY_INFO_DNS_INT:
5118 case LSA_POLICY_INFO_DNS:
5119 if (torture_setting_bool(tctx, "samba3", false)) {
5120 /* Other levels not implemented yet */
5121 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_INFO_CLASS)) {
5122 torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
5123 ret = false;
5125 } else if (!NT_STATUS_IS_OK(r.out.result)) {
5126 torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
5127 ret = false;
5129 break;
5130 default:
5131 if (torture_setting_bool(tctx, "samba4", false)) {
5132 /* Other levels not implemented yet */
5133 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_INFO_CLASS)) {
5134 torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
5135 ret = false;
5137 } else if (!NT_STATUS_IS_OK(r.out.result)) {
5138 torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
5139 ret = false;
5141 break;
5144 if (NT_STATUS_IS_OK(r.out.result) && (i == LSA_POLICY_INFO_DNS
5145 || i == LSA_POLICY_INFO_DNS_INT)) {
5146 /* Let's look up some of these names */
5148 struct lsa_TransNameArray tnames, dnames;
5149 tnames.count = 14;
5150 tnames.names = talloc_zero_array(tctx, struct lsa_TranslatedName, tnames.count);
5151 tnames.names[0].name.string = info->dns.name.string;
5152 tnames.names[0].sid_type = SID_NAME_DOMAIN;
5153 tnames.names[1].name.string = info->dns.dns_domain.string;
5154 tnames.names[1].sid_type = SID_NAME_DOMAIN;
5155 tnames.names[2].name.string = talloc_asprintf(tctx, "%s\\", info->dns.name.string);
5156 tnames.names[2].sid_type = SID_NAME_DOMAIN;
5157 tnames.names[3].name.string = talloc_asprintf(tctx, "%s\\", info->dns.dns_domain.string);
5158 tnames.names[3].sid_type = SID_NAME_DOMAIN;
5159 tnames.names[4].name.string = talloc_asprintf(tctx, "%s\\guest", info->dns.name.string);
5160 tnames.names[4].sid_type = SID_NAME_USER;
5161 tnames.names[5].name.string = talloc_asprintf(tctx, "%s\\krbtgt", info->dns.name.string);
5162 tnames.names[5].sid_type = SID_NAME_USER;
5163 tnames.names[6].name.string = talloc_asprintf(tctx, "%s\\guest", info->dns.dns_domain.string);
5164 tnames.names[6].sid_type = SID_NAME_USER;
5165 tnames.names[7].name.string = talloc_asprintf(tctx, "%s\\krbtgt", info->dns.dns_domain.string);
5166 tnames.names[7].sid_type = SID_NAME_USER;
5167 tnames.names[8].name.string = talloc_asprintf(tctx, "krbtgt@%s", info->dns.name.string);
5168 tnames.names[8].sid_type = SID_NAME_USER;
5169 tnames.names[9].name.string = talloc_asprintf(tctx, "krbtgt@%s", info->dns.dns_domain.string);
5170 tnames.names[9].sid_type = SID_NAME_USER;
5171 tnames.names[10].name.string = talloc_asprintf(tctx, "%s\\"TEST_MACHINENAME "$", info->dns.name.string);
5172 tnames.names[10].sid_type = SID_NAME_USER;
5173 tnames.names[11].name.string = talloc_asprintf(tctx, "%s\\"TEST_MACHINENAME "$", info->dns.dns_domain.string);
5174 tnames.names[11].sid_type = SID_NAME_USER;
5175 tnames.names[12].name.string = talloc_asprintf(tctx, TEST_MACHINENAME "$@%s", info->dns.name.string);
5176 tnames.names[12].sid_type = SID_NAME_USER;
5177 tnames.names[13].name.string = talloc_asprintf(tctx, TEST_MACHINENAME "$@%s", info->dns.dns_domain.string);
5178 tnames.names[13].sid_type = SID_NAME_USER;
5179 ret &= test_LookupNames(b, tctx, handle, LSA_LOOKUP_NAMES_ALL, &tnames);
5181 /* Try to use in-forest search for the test machine */
5182 dnames.count = 1;
5183 dnames.names = talloc_zero_array(tctx, struct lsa_TranslatedName, dnames.count);
5184 dnames.names[0].name.string = talloc_asprintf(tctx, "%s\\"TEST_MACHINENAME "$", info->dns.name.string);
5185 dnames.names[0].sid_type = SID_NAME_USER;
5186 ret &= test_LookupNames(b, tctx, handle, LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2, &dnames);
5190 return ret;
5193 static bool test_QueryInfoPolicy(struct dcerpc_binding_handle *b,
5194 struct torture_context *tctx,
5195 struct policy_handle *handle)
5197 return test_QueryInfoPolicyCalls(false, b, tctx, handle);
5200 static bool test_QueryInfoPolicy2(struct dcerpc_binding_handle *b,
5201 struct torture_context *tctx,
5202 struct policy_handle *handle)
5204 return test_QueryInfoPolicyCalls(true, b, tctx, handle);
5207 static bool test_GetUserName(struct dcerpc_binding_handle *b,
5208 struct torture_context *tctx)
5210 struct lsa_GetUserName r;
5211 struct lsa_String *authority_name_p = NULL;
5212 struct lsa_String *account_name_p = NULL;
5214 torture_comment(tctx, "\nTesting GetUserName\n");
5216 r.in.system_name = "\\";
5217 r.in.account_name = &account_name_p;
5218 r.in.authority_name = NULL;
5219 r.out.account_name = &account_name_p;
5221 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetUserName_r(b, tctx, &r),
5222 "GetUserName failed");
5223 torture_assert_ntstatus_ok(tctx, r.out.result,
5224 "GetUserName result failed");
5225 torture_assert_not_null(tctx, r.out.account_name, "r.out.account_name");
5226 torture_assert_not_null(tctx, *r.out.account_name, "*r.out.account_name");
5227 torture_assert(tctx, r.out.authority_name == NULL, "r.out.authority_name");
5229 account_name_p = NULL;
5230 r.in.account_name = &account_name_p;
5231 r.in.authority_name = &authority_name_p;
5232 r.out.account_name = &account_name_p;
5234 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetUserName_r(b, tctx, &r),
5235 "GetUserName failed");
5236 torture_assert_ntstatus_ok(tctx, r.out.result,
5237 "GetUserName result failed");
5238 torture_assert_not_null(tctx, r.out.account_name, "r.out.account_name");
5239 torture_assert_not_null(tctx, *r.out.account_name, "*r.out.account_name");
5240 torture_assert_not_null(tctx, r.out.authority_name, "r.out.authority_name");
5241 torture_assert_not_null(tctx, *r.out.authority_name, "*r.out.authority_name");
5243 torture_comment(tctx,
5244 "Account Name: %s, Authority Name: %s\n",
5245 (*r.out.account_name)->string,
5246 (*r.out.authority_name)->string);
5248 return true;
5251 static bool test_GetUserName_fail(struct dcerpc_binding_handle *b,
5252 struct torture_context *tctx)
5254 struct lsa_GetUserName r;
5255 struct lsa_String *account_name_p = NULL;
5256 NTSTATUS status;
5258 torture_comment(tctx, "\nTesting GetUserName_fail\n");
5260 r.in.system_name = "\\";
5261 r.in.account_name = &account_name_p;
5262 r.in.authority_name = NULL;
5263 r.out.account_name = &account_name_p;
5265 status = dcerpc_lsa_GetUserName_r(b, tctx, &r);
5266 if (!NT_STATUS_IS_OK(status)) {
5267 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5268 torture_comment(tctx,
5269 "GetUserName correctly returned with "
5270 "status: %s\n",
5271 nt_errstr(status));
5272 return true;
5275 torture_assert_ntstatus_equal(tctx,
5276 status,
5277 NT_STATUS_ACCESS_DENIED,
5278 "GetUserName return value should "
5279 "be ACCESS_DENIED");
5280 return true;
5283 if (!NT_STATUS_IS_OK(r.out.result)) {
5284 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) ||
5285 NT_STATUS_EQUAL(r.out.result, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
5286 torture_comment(tctx,
5287 "GetUserName correctly returned with "
5288 "result: %s\n",
5289 nt_errstr(r.out.result));
5290 return true;
5294 torture_assert_ntstatus_equal(tctx,
5295 r.out.result,
5296 NT_STATUS_OK,
5297 "GetUserName return value should be "
5298 "ACCESS_DENIED");
5300 return false;
5303 bool test_lsa_Close(struct dcerpc_binding_handle *b,
5304 struct torture_context *tctx,
5305 struct policy_handle *handle)
5307 struct lsa_Close r;
5308 struct policy_handle handle2;
5310 torture_comment(tctx, "\nTesting Close\n");
5312 r.in.handle = handle;
5313 r.out.handle = &handle2;
5315 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Close_r(b, tctx, &r),
5316 "Close failed");
5317 torture_assert_ntstatus_ok(tctx, r.out.result,
5318 "Close failed");
5320 torture_assert_ntstatus_equal(tctx, dcerpc_lsa_Close_r(b, tctx, &r),
5321 NT_STATUS_RPC_SS_CONTEXT_MISMATCH, "Close should failed");
5323 torture_comment(tctx, "\n");
5325 return true;
5328 bool torture_rpc_lsa(struct torture_context *tctx)
5330 NTSTATUS status;
5331 struct dcerpc_pipe *p;
5332 bool ret = true;
5333 struct policy_handle *handle = NULL;
5334 struct test_join *join = NULL;
5335 struct cli_credentials *machine_creds;
5336 struct dcerpc_binding_handle *b;
5337 enum dcerpc_transport_t transport;
5339 status = torture_rpc_connection(tctx, &p, &ndr_table_lsarpc);
5340 torture_assert_ntstatus_ok(tctx, status, "Error connecting to server");
5342 b = p->binding_handle;
5343 transport = dcerpc_binding_handle_get_transport(b);
5345 /* Test lsaLookupSids3 and lsaLookupNames4 over tcpip */
5346 if (transport == NCACN_IP_TCP) {
5347 if (!test_OpenPolicy_fail(b, tctx)) {
5348 ret = false;
5351 if (!test_OpenPolicy2_fail(b, tctx)) {
5352 ret = false;
5355 if (!test_OpenPolicy3_fail(b, tctx)) {
5356 ret = false;
5359 if (!test_many_LookupSids(p, tctx, handle, LSA_LOOKUP_NAMES_ALL)) {
5360 ret = false;
5363 return ret;
5366 if (!test_OpenPolicy(b, tctx)) {
5367 ret = false;
5370 if (!test_lsa_OpenPolicy2(b, tctx, &handle)) {
5371 ret = false;
5374 if (!test_lsa_OpenPolicy3(b, tctx, &handle)) {
5375 ret = false;
5378 if (handle) {
5379 join = torture_join_domain(tctx, TEST_MACHINENAME, ACB_WSTRUST, &machine_creds);
5380 if (!join) {
5381 ret = false;
5384 if (!test_LookupSids_async(b, tctx, handle, LSA_LOOKUP_NAMES_ALL)) {
5385 ret = false;
5388 if (!test_QueryDomainInfoPolicy(b, tctx, handle)) {
5389 ret = false;
5392 if (!test_CreateSecret(p, tctx, handle)) {
5393 ret = false;
5396 if (!test_QueryInfoPolicy(b, tctx, handle)) {
5397 ret = false;
5400 if (!test_QueryInfoPolicy2(b, tctx, handle)) {
5401 ret = false;
5404 if (!test_Delete(b, tctx, handle)) {
5405 ret = false;
5408 if (!test_many_LookupSids(p, tctx, handle, LSA_LOOKUP_NAMES_ALL)) {
5409 ret = false;
5412 if (!test_lsa_Close(b, tctx, handle)) {
5413 ret = false;
5416 torture_leave_domain(tctx, join);
5418 } else {
5419 if (!test_many_LookupSids(p, tctx, handle, LSA_LOOKUP_NAMES_ALL)) {
5420 ret = false;
5424 if (!test_GetUserName(b, tctx)) {
5425 ret = false;
5428 return ret;
5431 bool torture_rpc_lsa_get_user(struct torture_context *tctx)
5433 NTSTATUS status;
5434 struct dcerpc_pipe *p;
5435 bool ret = true;
5436 struct dcerpc_binding_handle *b;
5437 enum dcerpc_transport_t transport;
5439 status = torture_rpc_connection(tctx, &p, &ndr_table_lsarpc);
5440 torture_assert_ntstatus_ok(tctx, status, "Error connecting to server");
5442 b = p->binding_handle;
5443 transport = dcerpc_binding_handle_get_transport(b);
5445 if (transport == NCACN_IP_TCP) {
5446 if (!test_GetUserName_fail(b, tctx)) {
5447 ret = false;
5449 return ret;
5452 if (!test_GetUserName(b, tctx)) {
5453 ret = false;
5456 return ret;
5459 static bool testcase_LookupNames(struct torture_context *tctx,
5460 struct dcerpc_pipe *p)
5462 bool ret = true;
5463 struct policy_handle *handle;
5464 struct lsa_TransNameArray tnames;
5465 struct lsa_TransNameArray2 tnames2;
5466 struct dcerpc_binding_handle *b = p->binding_handle;
5467 enum dcerpc_transport_t transport = dcerpc_binding_handle_get_transport(b);
5469 if (transport != NCACN_NP && transport != NCALRPC) {
5470 torture_comment(tctx, "testcase_LookupNames is only available "
5471 "over NCACN_NP or NCALRPC");
5472 return true;
5475 if (!test_OpenPolicy(b, tctx)) {
5476 ret = false;
5479 if (!test_lsa_OpenPolicy2(b, tctx, &handle)) {
5480 ret = false;
5483 if (!handle) {
5484 ret = false;
5487 tnames.count = 1;
5488 tnames.names = talloc_array(tctx, struct lsa_TranslatedName, tnames.count);
5489 ZERO_STRUCT(tnames.names[0]);
5490 tnames.names[0].name.string = "BUILTIN";
5491 tnames.names[0].sid_type = SID_NAME_DOMAIN;
5493 if (!test_LookupNames(b, tctx, handle, LSA_LOOKUP_NAMES_ALL, &tnames)) {
5494 ret = false;
5497 tnames2.count = 1;
5498 tnames2.names = talloc_array(tctx, struct lsa_TranslatedName2, tnames2.count);
5499 ZERO_STRUCT(tnames2.names[0]);
5500 tnames2.names[0].name.string = "BUILTIN";
5501 tnames2.names[0].sid_type = SID_NAME_DOMAIN;
5503 if (!test_LookupNames2(b, tctx, handle, LSA_LOOKUP_NAMES_ALL, &tnames2, true)) {
5504 ret = false;
5507 if (!test_LookupNames3(b, tctx, handle, LSA_LOOKUP_NAMES_ALL, &tnames2, true)) {
5508 ret = false;
5511 if (!test_LookupNames_wellknown(b, tctx, handle, LSA_LOOKUP_NAMES_ALL)) {
5512 ret = false;
5515 if (!test_LookupNames_NULL(b, tctx, handle, LSA_LOOKUP_NAMES_ALL)) {
5516 ret = false;
5519 if (!test_LookupNames_bogus(b, tctx, handle, LSA_LOOKUP_NAMES_ALL)) {
5520 ret = false;
5523 if (!test_lsa_Close(b, tctx, handle)) {
5524 ret = false;
5527 return ret;
5530 struct torture_suite *torture_rpc_lsa_lookup_names(TALLOC_CTX *mem_ctx)
5532 struct torture_suite *suite;
5533 struct torture_rpc_tcase *tcase;
5535 suite = torture_suite_create(mem_ctx, "lsa.lookupnames");
5537 tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa",
5538 &ndr_table_lsarpc);
5539 torture_rpc_tcase_add_test(tcase, "LookupNames",
5540 testcase_LookupNames);
5542 return suite;
5545 struct lsa_trustdom_state {
5546 uint32_t num_trusts;
5549 static bool testcase_TrustedDomains(struct torture_context *tctx,
5550 struct dcerpc_pipe *p,
5551 void *data)
5553 bool ret = true;
5554 struct policy_handle *handle;
5555 struct lsa_trustdom_state *state =
5556 talloc_get_type_abort(data, struct lsa_trustdom_state);
5557 struct dcerpc_binding_handle *b = p->binding_handle;
5558 enum dcerpc_transport_t transport = dcerpc_binding_handle_get_transport(b);
5560 if (transport != NCACN_NP && transport != NCALRPC) {
5561 torture_comment(tctx, "testcase_TrustedDomains is only available "
5562 "over NCACN_NP or NCALRPC");
5563 return true;
5566 torture_comment(tctx, "Testing %d domains\n", state->num_trusts);
5568 if (!test_OpenPolicy(b, tctx)) {
5569 ret = false;
5572 if (!test_lsa_OpenPolicy2(b, tctx, &handle)) {
5573 ret = false;
5576 if (!test_lsa_OpenPolicy3(b, tctx, &handle)) {
5577 ret = false;
5580 if (!handle) {
5581 ret = false;
5584 if (!test_CreateTrustedDomain(b, tctx, handle, state->num_trusts)) {
5585 ret = false;
5588 if (!test_CreateTrustedDomainEx(p, tctx, handle, state->num_trusts)) {
5589 ret = false;
5592 if (!test_CreateTrustedDomainEx2(p, tctx, handle, state->num_trusts)) {
5593 ret = false;
5596 if (!test_CreateTrustedDomainEx3(p, tctx, handle, state->num_trusts)) {
5597 ret = false;
5600 if (!test_lsa_Close(b, tctx, handle)) {
5601 ret = false;
5604 return ret;
5607 struct torture_suite *torture_rpc_lsa_trusted_domains(TALLOC_CTX *mem_ctx)
5609 struct torture_suite *suite;
5610 struct torture_rpc_tcase *tcase;
5611 struct lsa_trustdom_state *state;
5613 state = talloc(mem_ctx, struct lsa_trustdom_state);
5615 state->num_trusts = 12;
5617 suite = torture_suite_create(mem_ctx, "lsa.trusted.domains");
5619 tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa",
5620 &ndr_table_lsarpc);
5621 torture_rpc_tcase_add_test_ex(tcase, "TrustedDomains",
5622 testcase_TrustedDomains,
5623 state);
5625 return suite;
5628 static bool testcase_Privileges(struct torture_context *tctx,
5629 struct dcerpc_pipe *p)
5631 struct policy_handle *handle;
5632 struct dcerpc_binding_handle *b = p->binding_handle;
5633 enum dcerpc_transport_t transport = dcerpc_binding_handle_get_transport(b);
5635 if (transport != NCACN_NP && transport != NCALRPC) {
5636 torture_skip(tctx, "testcase_Privileges is only available "
5637 "over NCACN_NP or NCALRPC");
5640 if (!test_OpenPolicy(b, tctx)) {
5641 return false;
5644 if (!test_lsa_OpenPolicy2(b, tctx, &handle)) {
5645 return false;
5648 if (!handle) {
5649 return false;
5652 if (!test_CreateAccount(b, tctx, handle)) {
5653 return false;
5656 if (!test_EnumAccounts(b, tctx, handle)) {
5657 return false;
5660 if (!test_EnumPrivs(b, tctx, handle)) {
5661 return false;
5664 if (!test_lsa_Close(b, tctx, handle)) {
5665 return false;
5668 return true;
5672 struct torture_suite *torture_rpc_lsa_privileges(TALLOC_CTX *mem_ctx)
5674 struct torture_suite *suite;
5675 struct torture_rpc_tcase *tcase;
5677 suite = torture_suite_create(mem_ctx, "lsa.privileges");
5679 tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa",
5680 &ndr_table_lsarpc);
5681 torture_rpc_tcase_add_test(tcase, "Privileges",
5682 testcase_Privileges);
5684 return suite;