ctdb-scripts: Support storing statd-callout state in cluster filesystem
[samba4-gss.git] / source4 / torture / rpc / lsa.c
blobab672f41d542838ae562126db527465e294f3e49
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 "LookupNames4 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 {
1223 * If we don't have a secure channel these tests must
1224 * fail with ACCESS_DENIED.
1226 if (!test_LookupSids3_fail(b, tctx, level, &sids)) {
1227 return false;
1229 if (!test_LookupNames4_fail(b, tctx, level)) {
1230 return false;
1235 torture_comment(tctx, "\n");
1239 return true;
1242 static void lookupsids_cb(struct tevent_req *subreq)
1244 int *replies = (int *)tevent_req_callback_data_void(subreq);
1245 NTSTATUS status;
1247 status = dcerpc_lsa_LookupSids_r_recv(subreq, subreq);
1248 TALLOC_FREE(subreq);
1249 if (!NT_STATUS_IS_OK(status)) {
1250 printf("lookupsids returned %s\n", nt_errstr(status));
1251 *replies = -1;
1254 if (*replies >= 0) {
1255 *replies += 1;
1259 static bool test_LookupSids_async(struct dcerpc_binding_handle *b,
1260 struct torture_context *tctx,
1261 struct policy_handle *handle,
1262 enum lsa_LookupNamesLevel level)
1264 struct lsa_SidArray sids;
1265 struct lsa_SidPtr sidptr;
1266 uint32_t *count;
1267 struct lsa_TransNameArray *names;
1268 struct lsa_LookupSids *r;
1269 struct lsa_RefDomainList *domains = NULL;
1270 struct tevent_req **req;
1271 int i, replies;
1272 bool ret = true;
1273 const int num_async_requests = 50;
1275 count = talloc_array(tctx, uint32_t, num_async_requests);
1276 names = talloc_array(tctx, struct lsa_TransNameArray, num_async_requests);
1277 r = talloc_array(tctx, struct lsa_LookupSids, num_async_requests);
1279 torture_comment(tctx, "\nTesting %d async lookupsids request\n", num_async_requests);
1281 req = talloc_array(tctx, struct tevent_req *, num_async_requests);
1283 sids.num_sids = 1;
1284 sids.sids = &sidptr;
1285 sidptr.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-545");
1287 replies = 0;
1289 for (i=0; i<num_async_requests; i++) {
1290 count[i] = 0;
1291 names[i].count = 0;
1292 names[i].names = NULL;
1294 r[i].in.handle = handle;
1295 r[i].in.sids = &sids;
1296 r[i].in.names = &names[i];
1297 r[i].in.level = level;
1298 r[i].in.count = &names[i].count;
1299 r[i].out.count = &count[i];
1300 r[i].out.names = &names[i];
1301 r[i].out.domains = &domains;
1303 req[i] = dcerpc_lsa_LookupSids_r_send(tctx, tctx->ev, b, &r[i]);
1304 if (req[i] == NULL) {
1305 ret = false;
1306 break;
1309 tevent_req_set_callback(req[i], lookupsids_cb, &replies);
1312 while (replies >= 0 && replies < num_async_requests) {
1313 tevent_loop_once(tctx->ev);
1316 talloc_free(req);
1318 if (replies < 0) {
1319 ret = false;
1322 return ret;
1325 static bool test_LookupPrivValue(struct dcerpc_binding_handle *b,
1326 struct torture_context *tctx,
1327 struct policy_handle *handle,
1328 struct lsa_String *name)
1330 struct lsa_LookupPrivValue r;
1331 struct lsa_LUID luid;
1333 r.in.handle = handle;
1334 r.in.name = name;
1335 r.out.luid = &luid;
1337 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupPrivValue_r(b, tctx, &r),
1338 "LookupPrivValue failed");
1339 torture_assert_ntstatus_ok(tctx, r.out.result,
1340 "LookupPrivValue failed");
1342 return true;
1345 static bool test_LookupPrivName(struct dcerpc_binding_handle *b,
1346 struct torture_context *tctx,
1347 struct policy_handle *handle,
1348 struct lsa_LUID *luid)
1350 struct lsa_LookupPrivName r;
1351 struct lsa_StringLarge *name = NULL;
1353 r.in.handle = handle;
1354 r.in.luid = luid;
1355 r.out.name = &name;
1357 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupPrivName_r(b, tctx, &r),
1358 "LookupPrivName failed");
1359 torture_assert_ntstatus_ok(tctx, r.out.result, "LookupPrivName failed");
1361 return true;
1364 static bool test_RemovePrivilegesFromAccount(struct dcerpc_binding_handle *b,
1365 struct torture_context *tctx,
1366 struct policy_handle *handle,
1367 struct policy_handle *acct_handle,
1368 struct lsa_LUID *luid)
1370 struct lsa_RemovePrivilegesFromAccount r;
1371 struct lsa_PrivilegeSet privs;
1372 bool ret = true;
1374 torture_comment(tctx, "\nTesting RemovePrivilegesFromAccount\n");
1376 r.in.handle = acct_handle;
1377 r.in.remove_all = 0;
1378 r.in.privs = &privs;
1380 privs.count = 1;
1381 privs.unknown = 0;
1382 privs.set = talloc_array(tctx, struct lsa_LUIDAttribute, 1);
1383 privs.set[0].luid = *luid;
1384 privs.set[0].attribute = 0;
1386 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_RemovePrivilegesFromAccount_r(b, tctx, &r),
1387 "RemovePrivilegesFromAccount failed");
1388 if (!NT_STATUS_IS_OK(r.out.result)) {
1390 struct lsa_LookupPrivName r_name;
1391 struct lsa_StringLarge *name = NULL;
1393 r_name.in.handle = handle;
1394 r_name.in.luid = luid;
1395 r_name.out.name = &name;
1397 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupPrivName_r(b, tctx, &r_name),
1398 "LookupPrivName failed");
1399 if (!NT_STATUS_IS_OK(r_name.out.result)) {
1400 torture_comment(tctx, "\nLookupPrivName failed - %s\n",
1401 nt_errstr(r_name.out.result));
1402 return false;
1404 /* Windows 2008 does not allow this to be removed */
1405 if (strcmp("SeAuditPrivilege", name->string) == 0) {
1406 return ret;
1409 torture_comment(tctx, "RemovePrivilegesFromAccount failed to remove %s - %s\n",
1410 name->string,
1411 nt_errstr(r.out.result));
1412 return false;
1415 return ret;
1418 static bool test_AddPrivilegesToAccount(struct dcerpc_binding_handle *b,
1419 struct torture_context *tctx,
1420 struct policy_handle *acct_handle,
1421 struct lsa_LUID *luid)
1423 struct lsa_AddPrivilegesToAccount r;
1424 struct lsa_PrivilegeSet privs;
1425 bool ret = true;
1427 torture_comment(tctx, "\nTesting AddPrivilegesToAccount\n");
1429 r.in.handle = acct_handle;
1430 r.in.privs = &privs;
1432 privs.count = 1;
1433 privs.unknown = 0;
1434 privs.set = talloc_array(tctx, struct lsa_LUIDAttribute, 1);
1435 privs.set[0].luid = *luid;
1436 privs.set[0].attribute = 0;
1438 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_AddPrivilegesToAccount_r(b, tctx, &r),
1439 "AddPrivilegesToAccount failed");
1440 torture_assert_ntstatus_ok(tctx, r.out.result,
1441 "AddPrivilegesToAccount failed");
1442 return ret;
1445 static bool test_EnumPrivsAccount(struct dcerpc_binding_handle *b,
1446 struct torture_context *tctx,
1447 struct policy_handle *handle,
1448 struct policy_handle *acct_handle)
1450 struct lsa_EnumPrivsAccount r;
1451 struct lsa_PrivilegeSet *privs = NULL;
1452 bool ret = true;
1454 torture_comment(tctx, "\nTesting EnumPrivsAccount\n");
1456 r.in.handle = acct_handle;
1457 r.out.privs = &privs;
1459 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumPrivsAccount_r(b, tctx, &r),
1460 "EnumPrivsAccount failed");
1461 torture_assert_ntstatus_ok(tctx, r.out.result,
1462 "EnumPrivsAccount failed");
1464 if (privs && privs->count > 0) {
1465 int i;
1466 for (i=0;i<privs->count;i++) {
1467 test_LookupPrivName(b, tctx, handle,
1468 &privs->set[i].luid);
1471 ret &= test_RemovePrivilegesFromAccount(b, tctx, handle, acct_handle,
1472 &privs->set[0].luid);
1473 ret &= test_AddPrivilegesToAccount(b, tctx, acct_handle,
1474 &privs->set[0].luid);
1477 return ret;
1480 static bool test_GetSystemAccessAccount(struct dcerpc_binding_handle *b,
1481 struct torture_context *tctx,
1482 struct policy_handle *handle,
1483 struct policy_handle *acct_handle)
1485 uint32_t access_mask;
1486 struct lsa_GetSystemAccessAccount r;
1488 torture_comment(tctx, "\nTesting GetSystemAccessAccount\n");
1490 r.in.handle = acct_handle;
1491 r.out.access_mask = &access_mask;
1493 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetSystemAccessAccount_r(b, tctx, &r),
1494 "GetSystemAccessAccount failed");
1495 torture_assert_ntstatus_ok(tctx, r.out.result,
1496 "GetSystemAccessAccount failed");
1498 if (r.out.access_mask != NULL) {
1499 torture_comment(tctx, "Rights:");
1500 if (*(r.out.access_mask) & LSA_POLICY_MODE_INTERACTIVE)
1501 torture_comment(tctx, " LSA_POLICY_MODE_INTERACTIVE");
1502 if (*(r.out.access_mask) & LSA_POLICY_MODE_NETWORK)
1503 torture_comment(tctx, " LSA_POLICY_MODE_NETWORK");
1504 if (*(r.out.access_mask) & LSA_POLICY_MODE_BATCH)
1505 torture_comment(tctx, " LSA_POLICY_MODE_BATCH");
1506 if (*(r.out.access_mask) & LSA_POLICY_MODE_SERVICE)
1507 torture_comment(tctx, " LSA_POLICY_MODE_SERVICE");
1508 if (*(r.out.access_mask) & LSA_POLICY_MODE_PROXY)
1509 torture_comment(tctx, " LSA_POLICY_MODE_PROXY");
1510 if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_INTERACTIVE)
1511 torture_comment(tctx, " LSA_POLICY_MODE_DENY_INTERACTIVE");
1512 if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_NETWORK)
1513 torture_comment(tctx, " LSA_POLICY_MODE_DENY_NETWORK");
1514 if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_BATCH)
1515 torture_comment(tctx, " LSA_POLICY_MODE_DENY_BATCH");
1516 if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_SERVICE)
1517 torture_comment(tctx, " LSA_POLICY_MODE_DENY_SERVICE");
1518 if (*(r.out.access_mask) & LSA_POLICY_MODE_REMOTE_INTERACTIVE)
1519 torture_comment(tctx, " LSA_POLICY_MODE_REMOTE_INTERACTIVE");
1520 if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_REMOTE_INTERACTIVE)
1521 torture_comment(tctx, " LSA_POLICY_MODE_DENY_REMOTE_INTERACTIVE");
1522 if (*(r.out.access_mask) & LSA_POLICY_MODE_ALL)
1523 torture_comment(tctx, " LSA_POLICY_MODE_ALL");
1524 if (*(r.out.access_mask) & LSA_POLICY_MODE_ALL_NT4)
1525 torture_comment(tctx, " LSA_POLICY_MODE_ALL_NT4");
1526 torture_comment(tctx, "\n");
1529 return true;
1532 static bool test_Delete(struct dcerpc_binding_handle *b,
1533 struct torture_context *tctx,
1534 struct policy_handle *handle)
1536 struct lsa_Delete r;
1538 torture_comment(tctx, "\nTesting Delete\n");
1540 r.in.handle = handle;
1541 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Delete_r(b, tctx, &r),
1542 "Delete failed");
1543 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_SUPPORTED,
1544 "Delete should have failed NT_STATUS_NOT_SUPPORTED");
1546 return true;
1549 static bool test_DeleteObject(struct dcerpc_binding_handle *b,
1550 struct torture_context *tctx,
1551 struct policy_handle *handle)
1553 struct lsa_DeleteObject r;
1555 torture_comment(tctx, "\nTesting DeleteObject\n");
1557 r.in.handle = handle;
1558 r.out.handle = handle;
1559 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_DeleteObject_r(b, tctx, &r),
1560 "DeleteObject failed");
1561 torture_assert_ntstatus_ok(tctx, r.out.result,
1562 "DeleteObject failed");
1564 return true;
1568 static bool test_CreateAccount(struct dcerpc_binding_handle *b,
1569 struct torture_context *tctx,
1570 struct policy_handle *handle)
1572 struct lsa_CreateAccount r;
1573 struct dom_sid2 *newsid;
1574 struct policy_handle acct_handle;
1576 newsid = dom_sid_parse_talloc(tctx, "S-1-5-12349876-4321-2854");
1578 torture_comment(tctx, "\nTesting CreateAccount\n");
1580 r.in.handle = handle;
1581 r.in.sid = newsid;
1582 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1583 r.out.acct_handle = &acct_handle;
1585 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CreateAccount_r(b, tctx, &r),
1586 "CreateAccount failed");
1587 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_OBJECT_NAME_COLLISION)) {
1588 struct lsa_OpenAccount r_o;
1589 r_o.in.handle = handle;
1590 r_o.in.sid = newsid;
1591 r_o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1592 r_o.out.acct_handle = &acct_handle;
1594 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(b, tctx, &r_o),
1595 "OpenAccount failed");
1596 torture_assert_ntstatus_ok(tctx, r_o.out.result,
1597 "OpenAccount failed");
1598 } else {
1599 torture_assert_ntstatus_ok(tctx, r.out.result,
1600 "CreateAccount failed");
1603 if (!test_Delete(b, tctx, &acct_handle)) {
1604 return false;
1607 if (!test_DeleteObject(b, tctx, &acct_handle)) {
1608 return false;
1611 return true;
1614 static bool test_DeleteTrustedDomain(struct dcerpc_binding_handle *b,
1615 struct torture_context *tctx,
1616 struct policy_handle *handle,
1617 struct lsa_StringLarge name)
1619 struct lsa_OpenTrustedDomainByName r;
1620 struct policy_handle trustdom_handle;
1622 r.in.handle = handle;
1623 r.in.name.string = name.string;
1624 r.in.access_mask = SEC_STD_DELETE;
1625 r.out.trustdom_handle = &trustdom_handle;
1627 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenTrustedDomainByName_r(b, tctx, &r),
1628 "OpenTrustedDomainByName failed");
1629 torture_assert_ntstatus_ok(tctx, r.out.result,
1630 "OpenTrustedDomainByName failed");
1632 if (!test_Delete(b, tctx, &trustdom_handle)) {
1633 return false;
1636 if (!test_DeleteObject(b, tctx, &trustdom_handle)) {
1637 return false;
1640 return true;
1643 static bool test_DeleteTrustedDomainBySid(struct dcerpc_binding_handle *b,
1644 struct torture_context *tctx,
1645 struct policy_handle *handle,
1646 struct dom_sid *sid)
1648 struct lsa_DeleteTrustedDomain r;
1650 r.in.handle = handle;
1651 r.in.dom_sid = sid;
1653 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_DeleteTrustedDomain_r(b, tctx, &r),
1654 "DeleteTrustedDomain failed");
1655 torture_assert_ntstatus_ok(tctx, r.out.result,
1656 "DeleteTrustedDomain failed");
1658 return true;
1662 static bool test_CreateSecret(struct dcerpc_pipe *p,
1663 struct torture_context *tctx,
1664 struct policy_handle *handle)
1666 struct lsa_CreateSecret r;
1667 struct lsa_OpenSecret r2;
1668 struct lsa_SetSecret r3;
1669 struct lsa_QuerySecret r4;
1670 struct lsa_SetSecret r5;
1671 struct lsa_QuerySecret r6;
1672 struct lsa_SetSecret r7;
1673 struct lsa_QuerySecret r8;
1674 struct policy_handle sec_handle, sec_handle2, sec_handle3;
1675 struct lsa_DeleteObject d_o;
1676 struct lsa_DATA_BUF buf1;
1677 struct lsa_DATA_BUF_PTR bufp1;
1678 struct lsa_DATA_BUF_PTR bufp2;
1679 DATA_BLOB enc_key;
1680 bool ret = true;
1681 DATA_BLOB session_key;
1682 NTTIME old_mtime, new_mtime;
1683 DATA_BLOB blob1;
1684 const char *secret1 = "abcdef12345699qwerty";
1685 char *secret2;
1686 const char *secret3 = "ABCDEF12345699QWERTY";
1687 char *secret4;
1688 const char *secret5 = "NEW-SAMBA4-SECRET";
1689 char *secret6;
1690 char *secname[2];
1691 int i;
1692 const int LOCAL = 0;
1693 const int GLOBAL = 1;
1694 struct dcerpc_binding_handle *b = p->binding_handle;
1696 secname[LOCAL] = talloc_asprintf(tctx, "torturesecret-%u", (unsigned int)random());
1697 secname[GLOBAL] = talloc_asprintf(tctx, "G$torturesecret-%u", (unsigned int)random());
1699 for (i=0; i< 2; i++) {
1700 torture_comment(tctx, "\nTesting CreateSecret of %s\n", secname[i]);
1702 init_lsa_String(&r.in.name, secname[i]);
1704 r.in.handle = handle;
1705 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1706 r.out.sec_handle = &sec_handle;
1708 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CreateSecret_r(b, tctx, &r),
1709 "CreateSecret failed");
1710 torture_assert_ntstatus_ok(tctx, r.out.result,
1711 "CreateSecret failed");
1713 r.in.handle = handle;
1714 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1715 r.out.sec_handle = &sec_handle3;
1717 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CreateSecret_r(b, tctx, &r),
1718 "CreateSecret failed");
1719 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_OBJECT_NAME_COLLISION,
1720 "CreateSecret should have failed OBJECT_NAME_COLLISION");
1722 r2.in.handle = handle;
1723 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1724 r2.in.name = r.in.name;
1725 r2.out.sec_handle = &sec_handle2;
1727 torture_comment(tctx, "Testing OpenSecret\n");
1729 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenSecret_r(b, tctx, &r2),
1730 "OpenSecret failed");
1731 torture_assert_ntstatus_ok(tctx, r2.out.result,
1732 "OpenSecret failed");
1734 torture_assert_ntstatus_ok(tctx,
1735 dcerpc_binding_handle_transport_session_key(b, tctx, &session_key),
1736 "transport_session_key failed");
1738 enc_key = sess_encrypt_string(secret1, &session_key);
1740 r3.in.sec_handle = &sec_handle;
1741 r3.in.new_val = &buf1;
1742 r3.in.old_val = NULL;
1743 r3.in.new_val->data = enc_key.data;
1744 r3.in.new_val->length = enc_key.length;
1745 r3.in.new_val->size = enc_key.length;
1747 torture_comment(tctx, "Testing SetSecret\n");
1749 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_SetSecret_r(b, tctx, &r3),
1750 "SetSecret failed");
1751 torture_assert_ntstatus_ok(tctx, r3.out.result,
1752 "SetSecret failed");
1754 r3.in.sec_handle = &sec_handle;
1755 r3.in.new_val = &buf1;
1756 r3.in.old_val = NULL;
1757 r3.in.new_val->data = enc_key.data;
1758 r3.in.new_val->length = enc_key.length;
1759 r3.in.new_val->size = enc_key.length;
1761 /* break the encrypted data */
1762 enc_key.data[0]++;
1764 torture_comment(tctx, "Testing SetSecret with broken key\n");
1766 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_SetSecret_r(b, tctx, &r3),
1767 "SetSecret failed");
1768 torture_assert_ntstatus_equal(tctx, r3.out.result, NT_STATUS_UNKNOWN_REVISION,
1769 "SetSecret should have failed UNKNOWN_REVISION");
1771 data_blob_free(&enc_key);
1773 ZERO_STRUCT(new_mtime);
1774 ZERO_STRUCT(old_mtime);
1776 /* fetch the secret back again */
1777 r4.in.sec_handle = &sec_handle;
1778 r4.in.new_val = &bufp1;
1779 r4.in.new_mtime = &new_mtime;
1780 r4.in.old_val = NULL;
1781 r4.in.old_mtime = NULL;
1783 bufp1.buf = NULL;
1785 torture_comment(tctx, "Testing QuerySecret\n");
1786 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QuerySecret_r(b, tctx, &r4),
1787 "QuerySecret failed");
1788 if (!NT_STATUS_IS_OK(r4.out.result)) {
1789 torture_comment(tctx, "QuerySecret failed - %s\n", nt_errstr(r4.out.result));
1790 ret = false;
1791 } else {
1792 if (r4.out.new_val == NULL || r4.out.new_val->buf == NULL) {
1793 torture_comment(tctx, "No secret buffer returned\n");
1794 ret = false;
1795 } else {
1796 blob1.data = r4.out.new_val->buf->data;
1797 blob1.length = r4.out.new_val->buf->size;
1799 secret2 = sess_decrypt_string(tctx,
1800 &blob1, &session_key);
1802 if (strcmp(secret1, secret2) != 0) {
1803 torture_comment(tctx, "Returned secret (r4) '%s' doesn't match '%s'\n",
1804 secret2, secret1);
1805 ret = false;
1810 enc_key = sess_encrypt_string(secret3, &session_key);
1812 r5.in.sec_handle = &sec_handle;
1813 r5.in.new_val = &buf1;
1814 r5.in.old_val = NULL;
1815 r5.in.new_val->data = enc_key.data;
1816 r5.in.new_val->length = enc_key.length;
1817 r5.in.new_val->size = enc_key.length;
1820 smb_msleep(200);
1821 torture_comment(tctx, "Testing SetSecret (existing value should move to old)\n");
1823 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_SetSecret_r(b, tctx, &r5),
1824 "SetSecret failed");
1825 if (!NT_STATUS_IS_OK(r5.out.result)) {
1826 torture_comment(tctx, "SetSecret failed - %s\n", nt_errstr(r5.out.result));
1827 ret = false;
1830 data_blob_free(&enc_key);
1832 ZERO_STRUCT(new_mtime);
1833 ZERO_STRUCT(old_mtime);
1835 /* fetch the secret back again */
1836 r6.in.sec_handle = &sec_handle;
1837 r6.in.new_val = &bufp1;
1838 r6.in.new_mtime = &new_mtime;
1839 r6.in.old_val = &bufp2;
1840 r6.in.old_mtime = &old_mtime;
1842 bufp1.buf = NULL;
1843 bufp2.buf = NULL;
1845 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QuerySecret_r(b, tctx, &r6),
1846 "QuerySecret failed");
1847 if (!NT_STATUS_IS_OK(r6.out.result)) {
1848 torture_comment(tctx, "QuerySecret failed - %s\n", nt_errstr(r6.out.result));
1849 ret = false;
1850 secret4 = NULL;
1851 } else {
1853 if (r6.out.new_val->buf == NULL || r6.out.old_val->buf == NULL
1854 || r6.out.new_mtime == NULL || r6.out.old_mtime == NULL) {
1855 torture_comment(tctx, "Both secret buffers and both times not returned\n");
1856 ret = false;
1857 secret4 = NULL;
1858 } else {
1859 blob1.data = r6.out.new_val->buf->data;
1860 blob1.length = r6.out.new_val->buf->size;
1862 secret4 = sess_decrypt_string(tctx,
1863 &blob1, &session_key);
1865 if (strcmp(secret3, secret4) != 0) {
1866 torture_comment(tctx, "Returned NEW secret %s doesn't match %s\n", secret4, secret3);
1867 ret = false;
1870 blob1.data = r6.out.old_val->buf->data;
1871 blob1.length = r6.out.old_val->buf->length;
1873 secret2 = sess_decrypt_string(tctx,
1874 &blob1, &session_key);
1876 if (strcmp(secret1, secret2) != 0) {
1877 torture_comment(tctx, "Returned OLD secret %s doesn't match %s\n", secret2, secret1);
1878 ret = false;
1881 if (*r6.out.new_mtime == *r6.out.old_mtime) {
1882 torture_comment(tctx, "Returned secret (r6-%d) %s must not have same mtime for both secrets: %s != %s\n",
1884 secname[i],
1885 nt_time_string(tctx, *r6.out.old_mtime),
1886 nt_time_string(tctx, *r6.out.new_mtime));
1887 ret = false;
1892 enc_key = sess_encrypt_string(secret5, &session_key);
1894 r7.in.sec_handle = &sec_handle;
1895 r7.in.old_val = &buf1;
1896 r7.in.old_val->data = enc_key.data;
1897 r7.in.old_val->length = enc_key.length;
1898 r7.in.old_val->size = enc_key.length;
1899 r7.in.new_val = NULL;
1901 torture_comment(tctx, "Testing SetSecret of old Secret only\n");
1903 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_SetSecret_r(b, tctx, &r7),
1904 "SetSecret failed");
1905 if (!NT_STATUS_IS_OK(r7.out.result)) {
1906 torture_comment(tctx, "SetSecret failed - %s\n", nt_errstr(r7.out.result));
1907 ret = false;
1910 data_blob_free(&enc_key);
1912 /* fetch the secret back again */
1913 r8.in.sec_handle = &sec_handle;
1914 r8.in.new_val = &bufp1;
1915 r8.in.new_mtime = &new_mtime;
1916 r8.in.old_val = &bufp2;
1917 r8.in.old_mtime = &old_mtime;
1919 bufp1.buf = NULL;
1920 bufp2.buf = NULL;
1922 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QuerySecret_r(b, tctx, &r8),
1923 "QuerySecret failed");
1924 if (!NT_STATUS_IS_OK(r8.out.result)) {
1925 torture_comment(tctx, "QuerySecret failed - %s\n", nt_errstr(r8.out.result));
1926 ret = false;
1927 } else {
1928 if (!r8.out.new_val || !r8.out.old_val) {
1929 torture_comment(tctx, "in/out pointers not returned, despite being set on in for QuerySecret\n");
1930 ret = false;
1931 } else if (r8.out.new_val->buf != NULL) {
1932 torture_comment(tctx, "NEW secret buffer must not be returned after OLD set\n");
1933 ret = false;
1934 } else if (r8.out.old_val->buf == NULL) {
1935 torture_comment(tctx, "OLD secret buffer was not returned after OLD set\n");
1936 ret = false;
1937 } else if (r8.out.new_mtime == NULL || r8.out.old_mtime == NULL) {
1938 torture_comment(tctx, "Both times not returned after OLD set\n");
1939 ret = false;
1940 } else {
1941 blob1.data = r8.out.old_val->buf->data;
1942 blob1.length = r8.out.old_val->buf->size;
1944 secret6 = sess_decrypt_string(tctx,
1945 &blob1, &session_key);
1947 if (strcmp(secret5, secret6) != 0) {
1948 torture_comment(tctx, "Returned OLD secret %s doesn't match %s\n", secret5, secret6);
1949 ret = false;
1952 if (*r8.out.new_mtime != *r8.out.old_mtime) {
1953 torture_comment(tctx, "Returned secret (r8) %s did not had same mtime for both secrets: %s != %s\n",
1954 secname[i],
1955 nt_time_string(tctx, *r8.out.old_mtime),
1956 nt_time_string(tctx, *r8.out.new_mtime));
1957 ret = false;
1962 if (!test_Delete(b, tctx, &sec_handle)) {
1963 ret = false;
1966 if (!test_DeleteObject(b, tctx, &sec_handle)) {
1967 return false;
1970 d_o.in.handle = &sec_handle2;
1971 d_o.out.handle = &sec_handle2;
1972 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_DeleteObject_r(b, tctx, &d_o),
1973 "DeleteObject failed");
1974 torture_assert_ntstatus_equal(tctx, d_o.out.result, NT_STATUS_INVALID_HANDLE,
1975 "OpenSecret expected INVALID_HANDLE");
1977 torture_comment(tctx, "Testing OpenSecret of just-deleted secret\n");
1979 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenSecret_r(b, tctx, &r2),
1980 "OpenSecret failed");
1981 torture_assert_ntstatus_equal(tctx, r2.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND,
1982 "OpenSecret expected OBJECT_NAME_NOT_FOUND");
1984 return ret;
1988 static bool test_EnumAccountRights(struct dcerpc_binding_handle *b,
1989 struct torture_context *tctx,
1990 struct policy_handle *acct_handle,
1991 struct dom_sid *sid)
1993 struct lsa_EnumAccountRights r;
1994 struct lsa_RightSet rights;
1996 torture_comment(tctx, "\nTesting EnumAccountRights\n");
1998 r.in.handle = acct_handle;
1999 r.in.sid = sid;
2000 r.out.rights = &rights;
2002 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountRights_r(b, tctx, &r),
2003 "EnumAccountRights failed");
2004 if (!NT_STATUS_IS_OK(r.out.result)) {
2005 torture_comment(tctx, "EnumAccountRights of %s failed - %s\n",
2006 dom_sid_string(tctx, sid), nt_errstr(r.out.result));
2008 torture_assert_ntstatus_ok(tctx, r.out.result,
2009 "EnumAccountRights failed");
2011 return true;
2015 static bool test_QuerySecurity(struct dcerpc_binding_handle *b,
2016 struct torture_context *tctx,
2017 struct policy_handle *handle,
2018 struct policy_handle *acct_handle)
2020 struct lsa_QuerySecurity r;
2021 struct sec_desc_buf *sdbuf = NULL;
2023 if (torture_setting_bool(tctx, "samba4", false)) {
2024 torture_comment(tctx, "\nskipping QuerySecurity test against Samba4\n");
2025 return true;
2028 torture_comment(tctx, "\nTesting QuerySecurity\n");
2030 r.in.handle = acct_handle;
2031 r.in.sec_info = SECINFO_OWNER |
2032 SECINFO_GROUP |
2033 SECINFO_DACL;
2034 r.out.sdbuf = &sdbuf;
2036 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QuerySecurity_r(b, tctx, &r),
2037 "QuerySecurity failed");
2038 if (!NT_STATUS_IS_OK(r.out.result)) {
2039 torture_comment(tctx, "QuerySecurity failed - %s\n", nt_errstr(r.out.result));
2040 return false;
2043 return true;
2046 static bool test_OpenAccount(struct dcerpc_binding_handle *b,
2047 struct torture_context *tctx,
2048 struct policy_handle *handle,
2049 struct dom_sid *sid)
2051 struct lsa_OpenAccount r;
2052 struct policy_handle acct_handle;
2054 torture_comment(tctx, "\nTesting OpenAccount\n");
2056 r.in.handle = handle;
2057 r.in.sid = sid;
2058 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2059 r.out.acct_handle = &acct_handle;
2061 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenAccount_r(b, tctx, &r),
2062 "OpenAccount failed");
2063 torture_assert_ntstatus_ok(tctx, r.out.result,
2064 "OpenAccount failed");
2066 if (!test_EnumPrivsAccount(b, tctx, handle, &acct_handle)) {
2067 return false;
2070 if (!test_GetSystemAccessAccount(b, tctx, handle, &acct_handle)) {
2071 return false;
2074 if (!test_QuerySecurity(b, tctx, handle, &acct_handle)) {
2075 return false;
2078 return true;
2081 static bool test_EnumAccounts(struct dcerpc_binding_handle *b,
2082 struct torture_context *tctx,
2083 struct policy_handle *handle)
2085 struct lsa_EnumAccounts r;
2086 struct lsa_SidArray sids1, sids2;
2087 uint32_t resume_handle = 0;
2088 int i;
2089 bool ret = true;
2091 torture_comment(tctx, "\nTesting EnumAccounts\n");
2093 r.in.handle = handle;
2094 r.in.resume_handle = &resume_handle;
2095 r.in.num_entries = 100;
2096 r.out.resume_handle = &resume_handle;
2097 r.out.sids = &sids1;
2099 resume_handle = 0;
2100 while (true) {
2101 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(b, tctx, &r),
2102 "EnumAccounts failed");
2103 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES)) {
2104 break;
2106 torture_assert_ntstatus_ok(tctx, r.out.result,
2107 "EnumAccounts failed");
2109 if (!test_LookupSids(b, tctx, handle, LSA_LOOKUP_NAMES_ALL, &sids1)) {
2110 return false;
2113 if (!test_LookupSids2(b, tctx, handle, LSA_LOOKUP_NAMES_ALL, &sids1)) {
2114 return false;
2117 /* Can't test lookupSids3 here, as clearly we must not
2118 * be on schannel, or we would not be able to do the
2119 * rest */
2121 torture_comment(tctx, "Testing all accounts\n");
2122 for (i=0;i<sids1.num_sids;i++) {
2123 ret &= test_OpenAccount(b, tctx, handle, sids1.sids[i].sid);
2124 ret &= test_EnumAccountRights(b, tctx, handle, sids1.sids[i].sid);
2126 torture_comment(tctx, "\n");
2129 if (sids1.num_sids < 3) {
2130 return ret;
2133 torture_comment(tctx, "Trying EnumAccounts partial listing (asking for 1 at 2)\n");
2134 resume_handle = 2;
2135 r.in.num_entries = 1;
2136 r.out.sids = &sids2;
2138 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccounts_r(b, tctx, &r),
2139 "EnumAccounts failed");
2140 torture_assert_ntstatus_ok(tctx, r.out.result,
2141 "EnumAccounts failed");
2143 if (sids2.num_sids != 1) {
2144 torture_comment(tctx, "Returned wrong number of entries (%d)\n", sids2.num_sids);
2145 return false;
2148 return true;
2151 static bool test_LookupPrivDisplayName(struct dcerpc_binding_handle *b,
2152 struct torture_context *tctx,
2153 struct policy_handle *handle,
2154 struct lsa_String *priv_name)
2156 struct lsa_LookupPrivDisplayName r;
2157 /* produce a reasonable range of language output without screwing up
2158 terminals */
2159 uint16_t language_id = (random() % 4) + 0x409;
2160 uint16_t returned_language_id = 0;
2161 struct lsa_StringLarge *disp_name = NULL;
2163 torture_comment(tctx, "\nTesting LookupPrivDisplayName(%s)\n", priv_name->string);
2165 r.in.handle = handle;
2166 r.in.name = priv_name;
2167 r.in.language_id = language_id;
2168 r.in.language_id_sys = 0;
2169 r.out.returned_language_id = &returned_language_id;
2170 r.out.disp_name = &disp_name;
2172 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupPrivDisplayName_r(b, tctx, &r),
2173 "LookupPrivDisplayName failed");
2174 if (!NT_STATUS_IS_OK(r.out.result)) {
2175 torture_comment(tctx, "LookupPrivDisplayName failed - %s\n", nt_errstr(r.out.result));
2176 return false;
2178 torture_comment(tctx, "%s -> \"%s\" (language 0x%x/0x%x)\n",
2179 priv_name->string, disp_name->string,
2180 r.in.language_id, *r.out.returned_language_id);
2182 return true;
2185 static bool test_EnumAccountsWithUserRight(struct dcerpc_binding_handle *b,
2186 struct torture_context *tctx,
2187 struct policy_handle *handle,
2188 struct lsa_String *priv_name)
2190 struct lsa_EnumAccountsWithUserRight r;
2191 struct lsa_SidArray sids;
2193 ZERO_STRUCT(sids);
2195 torture_comment(tctx, "\nTesting EnumAccountsWithUserRight(%s)\n", priv_name->string);
2197 r.in.handle = handle;
2198 r.in.name = priv_name;
2199 r.out.sids = &sids;
2201 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumAccountsWithUserRight_r(b, tctx, &r),
2202 "EnumAccountsWithUserRight failed");
2204 /* NT_STATUS_NO_MORE_ENTRIES means no one has this privilege */
2205 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES)) {
2206 return true;
2209 if (!NT_STATUS_IS_OK(r.out.result)) {
2210 torture_comment(tctx, "EnumAccountsWithUserRight failed - %s\n", nt_errstr(r.out.result));
2211 return false;
2214 return true;
2218 static bool test_EnumPrivs(struct dcerpc_binding_handle *b,
2219 struct torture_context *tctx,
2220 struct policy_handle *handle)
2222 struct lsa_EnumPrivs r;
2223 struct lsa_PrivArray privs1;
2224 uint32_t resume_handle = 0;
2225 int i;
2226 bool ret = true;
2228 torture_comment(tctx, "\nTesting EnumPrivs\n");
2230 r.in.handle = handle;
2231 r.in.resume_handle = &resume_handle;
2232 r.in.max_count = 100;
2233 r.out.resume_handle = &resume_handle;
2234 r.out.privs = &privs1;
2236 resume_handle = 0;
2237 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumPrivs_r(b, tctx, &r),
2238 "EnumPrivs failed");
2239 torture_assert_ntstatus_ok(tctx, r.out.result,
2240 "EnumPrivs failed");
2242 for (i = 0; i< privs1.count; i++) {
2243 test_LookupPrivDisplayName(b, tctx, handle, (struct lsa_String *)&privs1.privs[i].name);
2244 test_LookupPrivValue(b, tctx, handle, (struct lsa_String *)&privs1.privs[i].name);
2245 if (!test_EnumAccountsWithUserRight(b, tctx, handle, (struct lsa_String *)&privs1.privs[i].name)) {
2246 ret = false;
2250 return ret;
2253 static bool test_QueryForestTrustInformation(struct dcerpc_binding_handle *b,
2254 struct torture_context *tctx,
2255 struct policy_handle *handle,
2256 const char *trusted_domain_name)
2258 bool ret = true;
2259 struct lsa_lsaRQueryForestTrustInformation r;
2260 struct lsa_String string;
2261 struct lsa_ForestTrustInformation info, *info_ptr;
2263 torture_comment(tctx, "\nTesting lsaRQueryForestTrustInformation\n");
2265 if (torture_setting_bool(tctx, "samba4", false)) {
2266 torture_comment(tctx, "skipping QueryForestTrustInformation against Samba4\n");
2267 return true;
2270 ZERO_STRUCT(string);
2272 if (trusted_domain_name) {
2273 init_lsa_String(&string, trusted_domain_name);
2276 info_ptr = &info;
2278 r.in.handle = handle;
2279 r.in.trusted_domain_name = &string;
2280 r.in.highest_record_type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
2281 r.out.forest_trust_info = &info_ptr;
2283 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_lsaRQueryForestTrustInformation_r(b, tctx, &r),
2284 "lsaRQueryForestTrustInformation failed");
2286 if (!NT_STATUS_IS_OK(r.out.result)) {
2287 torture_comment(tctx, "lsaRQueryForestTrustInformation of %s failed - %s\n", trusted_domain_name, nt_errstr(r.out.result));
2288 ret = false;
2291 return ret;
2294 static bool test_query_each_TrustDomEx(struct dcerpc_binding_handle *b,
2295 struct torture_context *tctx,
2296 struct policy_handle *handle,
2297 struct lsa_DomainListEx *domains)
2299 int i;
2300 bool ret = true;
2302 for (i=0; i< domains->count; i++) {
2304 if (domains->domains[i].trust_attributes & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
2305 ret &= test_QueryForestTrustInformation(b, tctx, handle,
2306 domains->domains[i].domain_name.string);
2310 return ret;
2313 static bool test_query_each_TrustDom(struct dcerpc_binding_handle *b,
2314 struct torture_context *tctx,
2315 struct policy_handle *handle,
2316 struct lsa_DomainList *domains)
2318 int i,j;
2319 bool ret = true;
2321 torture_comment(tctx, "\nTesting OpenTrustedDomain, OpenTrustedDomainByName and QueryInfoTrustedDomain\n");
2322 for (i=0; i< domains->count; i++) {
2323 struct lsa_OpenTrustedDomain trust;
2324 struct lsa_OpenTrustedDomainByName trust_by_name;
2325 struct policy_handle trustdom_handle;
2326 struct policy_handle handle2;
2327 struct lsa_Close c;
2328 struct lsa_CloseTrustedDomainEx c_trust;
2329 int levels [] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
2330 int ok[] = {1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1};
2332 if (domains->domains[i].sid) {
2333 trust.in.handle = handle;
2334 trust.in.sid = domains->domains[i].sid;
2335 trust.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2336 trust.out.trustdom_handle = &trustdom_handle;
2338 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenTrustedDomain_r(b, tctx, &trust),
2339 "OpenTrustedDomain failed");
2341 if (NT_STATUS_EQUAL(trust.out.result, NT_STATUS_NO_SUCH_DOMAIN)) {
2342 torture_comment(tctx, "DOMAIN(%s, %s) not a direct trust?\n",
2343 domains->domains[i].name.string,
2344 dom_sid_string(tctx, domains->domains[i].sid));
2345 continue;
2347 if (!NT_STATUS_IS_OK(trust.out.result)) {
2348 torture_comment(tctx, "OpenTrustedDomain failed - %s\n", nt_errstr(trust.out.result));
2349 return false;
2352 c.in.handle = &trustdom_handle;
2353 c.out.handle = &handle2;
2355 c_trust.in.handle = &trustdom_handle;
2356 c_trust.out.handle = &handle2;
2358 for (j=0; j < ARRAY_SIZE(levels); j++) {
2359 struct lsa_QueryTrustedDomainInfo q;
2360 union lsa_TrustedDomainInfo *info = NULL;
2361 q.in.trustdom_handle = &trustdom_handle;
2362 q.in.level = levels[j];
2363 q.out.info = &info;
2364 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfo_r(b, tctx, &q),
2365 "QueryTrustedDomainInfo failed");
2366 if (!NT_STATUS_IS_OK(q.out.result) && ok[j]) {
2367 torture_comment(tctx, "QueryTrustedDomainInfo level %d failed - %s\n",
2368 levels[j], nt_errstr(q.out.result));
2369 ret = false;
2370 } else if (NT_STATUS_IS_OK(q.out.result) && !ok[j]) {
2371 torture_comment(tctx, "QueryTrustedDomainInfo level %d unexpectedly succeeded - %s\n",
2372 levels[j], nt_errstr(q.out.result));
2373 ret = false;
2377 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CloseTrustedDomainEx_r(b, tctx, &c_trust),
2378 "CloseTrustedDomainEx failed");
2379 if (!NT_STATUS_EQUAL(c_trust.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
2380 torture_comment(tctx, "Expected CloseTrustedDomainEx to return NT_STATUS_NOT_IMPLEMENTED, instead - %s\n", nt_errstr(c_trust.out.result));
2381 return false;
2384 c.in.handle = &trustdom_handle;
2385 c.out.handle = &handle2;
2387 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Close_r(b, tctx, &c),
2388 "Close failed");
2389 if (!NT_STATUS_IS_OK(c.out.result)) {
2390 torture_comment(tctx, "Close of trusted domain failed - %s\n", nt_errstr(c.out.result));
2391 return false;
2394 for (j=0; j < ARRAY_SIZE(levels); j++) {
2395 struct lsa_QueryTrustedDomainInfoBySid q;
2396 union lsa_TrustedDomainInfo *info = NULL;
2398 if (!domains->domains[i].sid) {
2399 continue;
2402 q.in.handle = handle;
2403 q.in.dom_sid = domains->domains[i].sid;
2404 q.in.level = levels[j];
2405 q.out.info = &info;
2407 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfoBySid_r(b, tctx, &q),
2408 "lsa_QueryTrustedDomainInfoBySid failed");
2409 if (!NT_STATUS_IS_OK(q.out.result) && ok[j]) {
2410 torture_comment(tctx, "QueryTrustedDomainInfoBySid level %d failed - %s\n",
2411 levels[j], nt_errstr(q.out.result));
2412 ret = false;
2413 } else if (NT_STATUS_IS_OK(q.out.result) && !ok[j]) {
2414 torture_comment(tctx, "QueryTrustedDomainInfoBySid level %d unexpectedly succeeded - %s\n",
2415 levels[j], nt_errstr(q.out.result));
2416 ret = false;
2421 trust_by_name.in.handle = handle;
2422 trust_by_name.in.name.string = domains->domains[i].name.string;
2423 trust_by_name.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2424 trust_by_name.out.trustdom_handle = &trustdom_handle;
2426 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenTrustedDomainByName_r(b, tctx, &trust_by_name),
2427 "OpenTrustedDomainByName failed");
2429 if (NT_STATUS_EQUAL(trust_by_name.out.result, NT_STATUS_NO_SUCH_DOMAIN)) {
2430 torture_comment(tctx, "DOMAIN(%s, %s) not a direct trust?\n",
2431 domains->domains[i].name.string,
2432 dom_sid_string(tctx, domains->domains[i].sid));
2433 continue;
2435 if (!NT_STATUS_IS_OK(trust_by_name.out.result)) {
2436 torture_comment(tctx, "OpenTrustedDomainByName failed - %s\n", nt_errstr(trust_by_name.out.result));
2437 return false;
2440 for (j=0; j < ARRAY_SIZE(levels); j++) {
2441 struct lsa_QueryTrustedDomainInfo q;
2442 union lsa_TrustedDomainInfo *info = NULL;
2443 q.in.trustdom_handle = &trustdom_handle;
2444 q.in.level = levels[j];
2445 q.out.info = &info;
2446 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfo_r(b, tctx, &q),
2447 "QueryTrustedDomainInfo failed");
2448 if (!NT_STATUS_IS_OK(q.out.result) && ok[j]) {
2449 torture_comment(tctx, "QueryTrustedDomainInfo level %d failed - %s\n",
2450 levels[j], nt_errstr(q.out.result));
2451 ret = false;
2452 } else if (NT_STATUS_IS_OK(q.out.result) && !ok[j]) {
2453 torture_comment(tctx, "QueryTrustedDomainInfo level %d unexpectedly succeeded - %s\n",
2454 levels[j], nt_errstr(q.out.result));
2455 ret = false;
2459 c.in.handle = &trustdom_handle;
2460 c.out.handle = &handle2;
2462 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Close_r(b, tctx, &c),
2463 "Close failed");
2464 if (!NT_STATUS_IS_OK(c.out.result)) {
2465 torture_comment(tctx, "Close of trusted domain failed - %s\n", nt_errstr(c.out.result));
2466 return false;
2469 for (j=0; j < ARRAY_SIZE(levels); j++) {
2470 struct lsa_QueryTrustedDomainInfoByName q;
2471 union lsa_TrustedDomainInfo *info = NULL;
2472 struct lsa_String name;
2474 name.string = domains->domains[i].name.string;
2476 q.in.handle = handle;
2477 q.in.trusted_domain = &name;
2478 q.in.level = levels[j];
2479 q.out.info = &info;
2480 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfoByName_r(b, tctx, &q),
2481 "QueryTrustedDomainInfoByName failed");
2482 if (!NT_STATUS_IS_OK(q.out.result) && ok[j]) {
2483 torture_comment(tctx, "QueryTrustedDomainInfoByName level %d failed - %s\n",
2484 levels[j], nt_errstr(q.out.result));
2485 ret = false;
2486 } else if (NT_STATUS_IS_OK(q.out.result) && !ok[j]) {
2487 torture_comment(tctx, "QueryTrustedDomainInfoByName level %d unexpectedly succeeded - %s\n",
2488 levels[j], nt_errstr(q.out.result));
2489 ret = false;
2493 return ret;
2496 static bool test_EnumTrustDom(struct dcerpc_binding_handle *b,
2497 struct torture_context *tctx,
2498 struct policy_handle *handle)
2500 struct lsa_EnumTrustDom r;
2501 uint32_t in_resume_handle = 0;
2502 uint32_t out_resume_handle;
2503 struct lsa_DomainList domains;
2504 bool ret = true;
2506 torture_comment(tctx, "\nTesting EnumTrustDom\n");
2508 r.in.handle = handle;
2509 r.in.resume_handle = &in_resume_handle;
2510 r.in.max_size = 0;
2511 r.out.domains = &domains;
2512 r.out.resume_handle = &out_resume_handle;
2514 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustDom_r(b, tctx, &r),
2515 "lsa_EnumTrustDom failed");
2517 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
2518 * always be larger than the previous input resume handle, in
2519 * particular when hitting the last query it is vital to set the
2520 * resume handle correctly to avoid infinite client loops, as
2521 * seen e.g. with Windows XP SP3 when resume handle is 0 and
2522 * status is NT_STATUS_OK - gd */
2524 if (NT_STATUS_IS_OK(r.out.result) ||
2525 NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES) ||
2526 NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
2528 if (out_resume_handle <= in_resume_handle) {
2529 torture_comment(tctx, "EnumTrustDom failed - should have returned output resume_handle (0x%08x) larger than input resume handle (0x%08x)\n",
2530 out_resume_handle, in_resume_handle);
2531 return false;
2535 if (NT_STATUS_IS_OK(r.out.result)) {
2536 if (domains.count == 0) {
2537 torture_comment(tctx, "EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
2538 return false;
2540 } else if (!(NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES) || NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES))) {
2541 torture_comment(tctx, "EnumTrustDom of zero size failed - %s\n", nt_errstr(r.out.result));
2542 return false;
2545 /* Start from the bottom again */
2546 in_resume_handle = 0;
2548 do {
2549 r.in.handle = handle;
2550 r.in.resume_handle = &in_resume_handle;
2551 r.in.max_size = LSA_ENUM_TRUST_DOMAIN_MULTIPLIER * 3;
2552 r.out.domains = &domains;
2553 r.out.resume_handle = &out_resume_handle;
2555 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustDom_r(b, tctx, &r),
2556 "EnumTrustDom failed");
2558 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
2559 * always be larger than the previous input resume handle, in
2560 * particular when hitting the last query it is vital to set the
2561 * resume handle correctly to avoid infinite client loops, as
2562 * seen e.g. with Windows XP SP3 when resume handle is 0 and
2563 * status is NT_STATUS_OK - gd */
2565 if (NT_STATUS_IS_OK(r.out.result) ||
2566 NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES) ||
2567 NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
2569 if (out_resume_handle <= in_resume_handle) {
2570 torture_comment(tctx, "EnumTrustDom failed - should have returned output resume_handle (0x%08x) larger than input resume handle (0x%08x)\n",
2571 out_resume_handle, in_resume_handle);
2572 return false;
2576 /* NO_MORE_ENTRIES is allowed */
2577 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NO_MORE_ENTRIES)) {
2578 if (domains.count == 0) {
2579 return true;
2581 torture_comment(tctx, "EnumTrustDom failed - should have returned 0 trusted domains with 'NT_STATUS_NO_MORE_ENTRIES'\n");
2582 return false;
2583 } else if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES)) {
2584 /* Windows 2003 gets this off by one on the first run */
2585 if (r.out.domains->count < 3 || r.out.domains->count > 4) {
2586 torture_comment(tctx, "EnumTrustDom didn't fill the buffer we "
2587 "asked it to (got %d, expected %d / %d == %d entries)\n",
2588 r.out.domains->count, LSA_ENUM_TRUST_DOMAIN_MULTIPLIER * 3,
2589 LSA_ENUM_TRUST_DOMAIN_MULTIPLIER, r.in.max_size);
2590 ret = false;
2592 } else if (!NT_STATUS_IS_OK(r.out.result)) {
2593 torture_comment(tctx, "EnumTrustDom failed - %s\n", nt_errstr(r.out.result));
2594 return false;
2597 if (domains.count == 0) {
2598 torture_comment(tctx, "EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
2599 return false;
2602 ret &= test_query_each_TrustDom(b, tctx, handle, &domains);
2604 in_resume_handle = out_resume_handle;
2606 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
2608 return ret;
2611 static bool test_EnumTrustDomEx(struct dcerpc_binding_handle *b,
2612 struct torture_context *tctx,
2613 struct policy_handle *handle)
2615 struct lsa_EnumTrustedDomainsEx r_ex;
2616 uint32_t in_resume_handle = 0;
2617 uint32_t out_resume_handle;
2618 struct lsa_DomainListEx domains_ex;
2619 bool ret = true;
2621 torture_comment(tctx, "\nTesting EnumTrustedDomainsEx\n");
2623 r_ex.in.handle = handle;
2624 r_ex.in.resume_handle = &in_resume_handle;
2625 r_ex.in.max_size = 0;
2626 r_ex.out.domains = &domains_ex;
2627 r_ex.out.resume_handle = &out_resume_handle;
2629 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustedDomainsEx_r(b, tctx, &r_ex),
2630 "EnumTrustedDomainsEx failed");
2632 /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
2633 * always be larger than the previous input resume handle, in
2634 * particular when hitting the last query it is vital to set the
2635 * resume handle correctly to avoid infinite client loops, as
2636 * seen e.g. with Windows XP SP3 when resume handle is 0 and
2637 * status is NT_STATUS_OK - gd */
2639 if (NT_STATUS_IS_OK(r_ex.out.result) ||
2640 NT_STATUS_EQUAL(r_ex.out.result, NT_STATUS_NO_MORE_ENTRIES) ||
2641 NT_STATUS_EQUAL(r_ex.out.result, STATUS_MORE_ENTRIES))
2643 if (out_resume_handle <= in_resume_handle) {
2644 torture_comment(tctx, "EnumTrustDomEx failed - should have returned output resume_handle (0x%08x) larger than input resume handle (0x%08x)\n",
2645 out_resume_handle, in_resume_handle);
2646 return false;
2650 if (NT_STATUS_IS_OK(r_ex.out.result)) {
2651 if (domains_ex.count == 0) {
2652 torture_comment(tctx, "EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
2653 return false;
2655 } else if (!(NT_STATUS_EQUAL(r_ex.out.result, STATUS_MORE_ENTRIES) ||
2656 NT_STATUS_EQUAL(r_ex.out.result, NT_STATUS_NO_MORE_ENTRIES))) {
2657 torture_comment(tctx, "EnumTrustDom of zero size failed - %s\n",
2658 nt_errstr(r_ex.out.result));
2659 return false;
2662 in_resume_handle = 0;
2663 do {
2664 r_ex.in.handle = handle;
2665 r_ex.in.resume_handle = &in_resume_handle;
2666 r_ex.in.max_size = LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER * 3;
2667 r_ex.out.domains = &domains_ex;
2668 r_ex.out.resume_handle = &out_resume_handle;
2670 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustedDomainsEx_r(b, tctx, &r_ex),
2671 "EnumTrustedDomainsEx failed");
2673 in_resume_handle = out_resume_handle;
2675 /* NO_MORE_ENTRIES is allowed */
2676 if (NT_STATUS_EQUAL(r_ex.out.result, NT_STATUS_NO_MORE_ENTRIES)) {
2677 if (domains_ex.count == 0) {
2678 return true;
2680 torture_comment(tctx, "EnumTrustDomainsEx failed - should have returned 0 trusted domains with 'NT_STATUS_NO_MORE_ENTRIES'\n");
2681 return false;
2682 } else if (NT_STATUS_EQUAL(r_ex.out.result, STATUS_MORE_ENTRIES)) {
2683 /* Windows 2003 gets this off by one on the first run */
2684 if (r_ex.out.domains->count < 3 || r_ex.out.domains->count > 4) {
2685 torture_comment(tctx, "EnumTrustDom didn't fill the buffer we "
2686 "asked it to (got %d, expected %d / %d == %d entries)\n",
2687 r_ex.out.domains->count,
2688 r_ex.in.max_size,
2689 LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER,
2690 r_ex.in.max_size / LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER);
2692 } else if (!NT_STATUS_IS_OK(r_ex.out.result)) {
2693 torture_comment(tctx, "EnumTrustedDomainEx failed - %s\n", nt_errstr(r_ex.out.result));
2694 return false;
2697 if (domains_ex.count == 0) {
2698 torture_comment(tctx, "EnumTrustDomainEx failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
2699 return false;
2702 ret &= test_query_each_TrustDomEx(b, tctx, handle, &domains_ex);
2704 } while (NT_STATUS_EQUAL(r_ex.out.result, STATUS_MORE_ENTRIES));
2706 return ret;
2710 static bool test_CreateTrustedDomain(struct dcerpc_binding_handle *b,
2711 struct torture_context *tctx,
2712 struct policy_handle *handle,
2713 uint32_t num_trusts)
2715 bool ret = true;
2716 struct lsa_CreateTrustedDomain r;
2717 struct lsa_DomainInfo trustinfo;
2718 struct dom_sid **domsid;
2719 struct policy_handle *trustdom_handle;
2720 struct lsa_QueryTrustedDomainInfo q;
2721 union lsa_TrustedDomainInfo *info = NULL;
2722 int i;
2724 torture_comment(tctx, "\nTesting CreateTrustedDomain for %d domains\n", num_trusts);
2726 if (!test_EnumTrustDom(b, tctx, handle)) {
2727 ret = false;
2730 if (!test_EnumTrustDomEx(b, tctx, handle)) {
2731 ret = false;
2734 domsid = talloc_array(tctx, struct dom_sid *, num_trusts);
2735 trustdom_handle = talloc_array(tctx, struct policy_handle, num_trusts);
2737 for (i=0; i< num_trusts; i++) {
2738 char *trust_name = talloc_asprintf(tctx, "TORTURE1%02d", i);
2739 char *trust_sid = talloc_asprintf(tctx, "S-1-5-21-97398-379795-1%02d", i);
2741 domsid[i] = dom_sid_parse_talloc(tctx, trust_sid);
2743 trustinfo.sid = domsid[i];
2744 init_lsa_String((struct lsa_String *)&trustinfo.name, trust_name);
2746 r.in.policy_handle = handle;
2747 r.in.info = &trustinfo;
2748 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2749 r.out.trustdom_handle = &trustdom_handle[i];
2751 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CreateTrustedDomain_r(b, tctx, &r),
2752 "CreateTrustedDomain failed");
2753 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_OBJECT_NAME_COLLISION)) {
2754 test_DeleteTrustedDomain(b, tctx, handle, trustinfo.name);
2755 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_CreateTrustedDomain_r(b, tctx, &r),
2756 "CreateTrustedDomain failed");
2758 if (!NT_STATUS_IS_OK(r.out.result)) {
2759 torture_comment(tctx, "CreateTrustedDomain failed - %s\n", nt_errstr(r.out.result));
2760 ret = false;
2761 } else {
2763 q.in.trustdom_handle = &trustdom_handle[i];
2764 q.in.level = LSA_TRUSTED_DOMAIN_INFO_INFO_EX;
2765 q.out.info = &info;
2766 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfo_r(b, tctx, &q),
2767 "QueryTrustedDomainInfo failed");
2768 if (!NT_STATUS_IS_OK(q.out.result)) {
2769 torture_comment(tctx, "QueryTrustedDomainInfo level %d failed - %s\n", q.in.level, nt_errstr(q.out.result));
2770 ret = false;
2771 } else if (!q.out.info) {
2772 ret = false;
2773 } else {
2774 if (strcmp(info->info_ex.domain_name.string, trustinfo.name.string) != 0) {
2775 torture_comment(tctx, "QueryTrustedDomainInfo returned inconsistent long name: %s != %s\n",
2776 info->info_ex.domain_name.string, trustinfo.name.string);
2777 ret = false;
2779 if (strcmp(info->info_ex.netbios_name.string, trustinfo.name.string) != 0) {
2780 torture_comment(tctx, "QueryTrustedDomainInfo returned inconsistent short name: %s != %s\n",
2781 info->info_ex.netbios_name.string, trustinfo.name.string);
2782 ret = false;
2784 if (info->info_ex.trust_type != LSA_TRUST_TYPE_DOWNLEVEL) {
2785 torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n",
2786 trust_name, info->info_ex.trust_type, LSA_TRUST_TYPE_DOWNLEVEL);
2787 ret = false;
2789 if (info->info_ex.trust_attributes != 0) {
2790 torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n",
2791 trust_name, info->info_ex.trust_attributes, 0);
2792 ret = false;
2794 if (info->info_ex.trust_direction != LSA_TRUST_DIRECTION_OUTBOUND) {
2795 torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n",
2796 trust_name, info->info_ex.trust_direction, LSA_TRUST_DIRECTION_OUTBOUND);
2797 ret = false;
2803 /* now that we have some domains to look over, we can test the enum calls */
2804 if (!test_EnumTrustDom(b, tctx, handle)) {
2805 ret = false;
2808 if (!test_EnumTrustDomEx(b, tctx, handle)) {
2809 ret = false;
2812 for (i=0; i<num_trusts; i++) {
2813 if (!test_DeleteTrustedDomainBySid(b, tctx, handle, domsid[i])) {
2814 ret = false;
2818 return ret;
2821 static bool gen_authinfo(TALLOC_CTX *mem_ctx,
2822 const char *incoming_old, const char *incoming_new,
2823 const char *outgoing_old, const char *outgoing_new,
2824 struct lsa_TrustDomainInfoAuthInfo **_authinfo)
2826 struct lsa_TrustDomainInfoAuthInfo *authinfo;
2827 struct lsa_TrustDomainInfoBuffer *in_buffer;
2828 struct lsa_TrustDomainInfoBuffer *io_buffer;
2829 struct lsa_TrustDomainInfoBuffer *on_buffer;
2830 struct lsa_TrustDomainInfoBuffer *oo_buffer;
2831 size_t converted_size;
2832 bool ok;
2834 authinfo = talloc_zero(mem_ctx, struct lsa_TrustDomainInfoAuthInfo);
2835 if (authinfo == NULL) {
2836 return false;
2839 in_buffer = talloc_zero(authinfo, struct lsa_TrustDomainInfoBuffer);
2840 if (in_buffer == NULL) {
2841 return false;
2843 in_buffer->AuthType = TRUST_AUTH_TYPE_CLEAR;
2844 ok = convert_string_talloc(in_buffer, CH_UNIX, CH_UTF16,
2845 incoming_new,
2846 strlen(incoming_new),
2847 &in_buffer->data.data,
2848 &converted_size);
2849 if (!ok) {
2850 return false;
2852 in_buffer->data.size = converted_size;
2854 io_buffer = talloc_zero(authinfo, struct lsa_TrustDomainInfoBuffer);
2855 if (io_buffer == NULL) {
2856 return false;
2858 io_buffer->AuthType = TRUST_AUTH_TYPE_CLEAR;
2859 ok = convert_string_talloc(io_buffer, CH_UNIX, CH_UTF16,
2860 incoming_old,
2861 strlen(incoming_old),
2862 &io_buffer->data.data,
2863 &converted_size);
2864 if (!ok) {
2865 return false;
2867 io_buffer->data.size = converted_size;
2869 on_buffer = talloc_zero(authinfo, struct lsa_TrustDomainInfoBuffer);
2870 if (on_buffer == NULL) {
2871 return false;
2873 on_buffer->AuthType = TRUST_AUTH_TYPE_CLEAR;
2874 ok = convert_string_talloc(on_buffer, CH_UNIX, CH_UTF16,
2875 outgoing_new,
2876 strlen(outgoing_new),
2877 &on_buffer->data.data,
2878 &converted_size);
2879 if (!ok) {
2880 return false;
2882 on_buffer->data.size = converted_size;
2884 oo_buffer = talloc_zero(authinfo, struct lsa_TrustDomainInfoBuffer);
2885 if (oo_buffer == NULL) {
2886 return false;
2888 oo_buffer->AuthType = TRUST_AUTH_TYPE_CLEAR;
2889 ok = convert_string_talloc(oo_buffer, CH_UNIX, CH_UTF16,
2890 outgoing_old,
2891 strlen(outgoing_old),
2892 &oo_buffer->data.data,
2893 &converted_size);
2894 if (!ok) {
2895 return false;
2897 oo_buffer->data.size = converted_size;
2899 authinfo->incoming_count = 1;
2900 authinfo->incoming_current_auth_info = in_buffer;
2901 authinfo->incoming_previous_auth_info = io_buffer;
2902 authinfo->outgoing_count = 1;
2903 authinfo->outgoing_current_auth_info = on_buffer;
2904 authinfo->outgoing_previous_auth_info = oo_buffer;
2906 *_authinfo = authinfo;
2908 return true;
2911 static bool check_pw_with_ServerAuthenticate3(struct dcerpc_pipe *p,
2912 struct torture_context *tctx,
2913 uint32_t negotiate_flags,
2914 const char *server_name,
2915 struct cli_credentials *machine_credentials,
2916 struct netlogon_creds_CredentialState **creds_out)
2918 struct netr_ServerReqChallenge r;
2919 struct netr_ServerAuthenticate3 a;
2920 struct netr_Credential credentials1, credentials2, credentials3;
2921 struct netlogon_creds_CredentialState *creds;
2922 const struct samr_Password *new_password = NULL;
2923 const struct samr_Password *old_password = NULL;
2924 uint32_t rid;
2925 struct dcerpc_binding_handle *b = p->binding_handle;
2927 new_password = cli_credentials_get_nt_hash(machine_credentials, tctx);
2928 old_password = cli_credentials_get_old_nt_hash(machine_credentials, tctx);
2930 r.in.server_name = server_name;
2931 r.in.computer_name = cli_credentials_get_workstation(machine_credentials);
2932 r.in.credentials = &credentials1;
2933 r.out.return_credentials = &credentials2;
2935 netlogon_creds_random_challenge(&credentials1);
2937 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
2938 "ServerReqChallenge failed");
2939 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
2941 a.in.server_name = server_name;
2942 a.in.account_name = cli_credentials_get_username(machine_credentials);
2943 a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
2944 a.in.computer_name = cli_credentials_get_workstation(machine_credentials);
2945 a.in.negotiate_flags = &negotiate_flags;
2946 a.in.credentials = &credentials3;
2947 a.out.return_credentials = &credentials3;
2948 a.out.negotiate_flags = &negotiate_flags;
2949 a.out.rid = &rid;
2951 creds = netlogon_creds_client_init(tctx, a.in.account_name,
2952 a.in.computer_name,
2953 a.in.secure_channel_type,
2954 &credentials1, &credentials2,
2955 new_password, &credentials3,
2956 negotiate_flags,
2957 negotiate_flags);
2959 torture_assert(tctx, creds != NULL, "memory allocation");
2961 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
2962 "ServerAuthenticate3 failed");
2963 if (!NT_STATUS_IS_OK(a.out.result)) {
2964 if (!NT_STATUS_EQUAL(a.out.result, NT_STATUS_ACCESS_DENIED)) {
2965 torture_assert_ntstatus_ok(tctx, a.out.result,
2966 "ServerAuthenticate3 failed");
2968 return false;
2970 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
2972 if (old_password != NULL) {
2973 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
2974 "ServerReqChallenge failed");
2975 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
2977 creds = netlogon_creds_client_init(tctx, a.in.account_name,
2978 a.in.computer_name,
2979 a.in.secure_channel_type,
2980 &credentials1, &credentials2,
2981 old_password, &credentials3,
2982 negotiate_flags,
2983 negotiate_flags);
2985 torture_assert(tctx, creds != NULL, "memory allocation");
2987 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
2988 "ServerAuthenticate3 failed");
2989 if (!NT_STATUS_IS_OK(a.out.result)) {
2990 if (!NT_STATUS_EQUAL(a.out.result, NT_STATUS_ACCESS_DENIED)) {
2991 torture_assert_ntstatus_ok(tctx, a.out.result,
2992 "ServerAuthenticate3 (old) failed");
2994 return false;
2996 torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential (old) chaining failed");
2999 /* Prove that requesting a challenge again won't break it */
3000 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
3001 "ServerReqChallenge failed");
3002 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
3004 *creds_out = creds;
3005 return true;
3008 #ifdef SAMBA4_USES_HEIMDAL
3011 * This function is set in torture_krb5_init_context as krb5
3012 * send_and_recv function. This allows us to override what server the
3013 * test is aimed at, and to inspect the packets just before they are
3014 * sent to the network, and before they are processed on the recv
3015 * side.
3017 * The torture_krb5_pre_send_test() and torture_krb5_post_recv_test()
3018 * functions are implement the actual tests.
3020 * When this asserts, the caller will get a spurious 'cannot contact
3021 * any KDC' message.
3024 struct check_pw_with_krb5_ctx {
3025 struct addrinfo *server;
3026 const char *server_nb_domain;
3027 const char *server_dns_domain;
3028 struct {
3029 unsigned io;
3030 unsigned fail;
3031 unsigned errors;
3032 unsigned error_io;
3033 unsigned ok;
3034 } counts;
3035 krb5_error error;
3036 struct smb_krb5_context *smb_krb5_context;
3037 krb5_get_init_creds_opt *krb_options;
3038 krb5_creds my_creds;
3039 krb5_get_creds_opt opt_canon;
3040 krb5_get_creds_opt opt_nocanon;
3041 krb5_principal upn_realm;
3042 krb5_principal upn_dns;
3043 krb5_principal upn_netbios;
3044 krb5_ccache krbtgt_ccache;
3045 krb5_principal krbtgt_trust_realm;
3046 krb5_creds *krbtgt_trust_realm_creds;
3047 krb5_principal krbtgt_trust_dns;
3048 krb5_creds *krbtgt_trust_dns_creds;
3049 krb5_principal krbtgt_trust_netbios;
3050 krb5_creds *krbtgt_trust_netbios_creds;
3051 krb5_principal cifs_trust_dns;
3052 krb5_creds *cifs_trust_dns_creds;
3053 krb5_principal cifs_trust_netbios;
3054 krb5_creds *cifs_trust_netbios_creds;
3055 krb5_principal drs_trust_dns;
3056 krb5_creds *drs_trust_dns_creds;
3057 krb5_principal drs_trust_netbios;
3058 krb5_creds *drs_trust_netbios_creds;
3059 krb5_principal four_trust_dns;
3060 krb5_creds *four_trust_dns_creds;
3061 krb5_creds krbtgt_referral_creds;
3062 Ticket krbtgt_referral_ticket;
3063 krb5_keyblock krbtgt_referral_keyblock;
3064 EncTicketPart krbtgt_referral_enc_part;
3067 static krb5_error_code check_pw_with_krb5_send_to_realm(
3068 struct smb_krb5_context *smb_krb5_context,
3069 void *data, /* struct check_pw_with_krb5_ctx */
3070 krb5_const_realm realm,
3071 time_t timeout,
3072 const krb5_data *send_buf,
3073 krb5_data *recv_buf)
3075 struct check_pw_with_krb5_ctx *ctx =
3076 talloc_get_type_abort(data, struct check_pw_with_krb5_ctx);
3077 krb5_error_code k5ret;
3078 size_t used;
3079 int ret;
3081 SMB_ASSERT(smb_krb5_context == ctx->smb_krb5_context);
3083 if (!strequal_m(realm, ctx->server_nb_domain) &&
3084 !strequal_m(realm, ctx->server_dns_domain))
3086 return KRB5_KDC_UNREACH;
3089 krb5_free_error_contents(ctx->smb_krb5_context->krb5_context,
3090 &ctx->error);
3091 ctx->counts.io++;
3093 k5ret = smb_krb5_send_and_recv_func_forced_tcp(ctx->smb_krb5_context,
3094 ctx->server,
3095 timeout, send_buf, recv_buf);
3096 if (k5ret != 0) {
3097 ctx->counts.fail++;
3098 return k5ret;
3101 ret = decode_KRB_ERROR(recv_buf->data, recv_buf->length,
3102 &ctx->error, &used);
3103 if (ret == 0) {
3104 ctx->counts.errors++;
3105 ctx->counts.error_io = ctx->counts.io;
3106 } else {
3107 ctx->counts.ok++;
3110 return k5ret;
3113 static int check_pw_with_krb5_ctx_destructor(struct check_pw_with_krb5_ctx *ctx)
3115 if (ctx->server != NULL) {
3116 freeaddrinfo(ctx->server);
3117 ctx->server = NULL;
3120 if (ctx->krb_options != NULL) {
3121 krb5_get_init_creds_opt_free(ctx->smb_krb5_context->krb5_context,
3122 ctx->krb_options);
3123 ctx->krb_options = NULL;
3126 krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3127 &ctx->my_creds);
3129 if (ctx->opt_canon != NULL) {
3130 krb5_get_creds_opt_free(ctx->smb_krb5_context->krb5_context,
3131 ctx->opt_canon);
3132 ctx->opt_canon = NULL;
3135 if (ctx->opt_nocanon != NULL) {
3136 krb5_get_creds_opt_free(ctx->smb_krb5_context->krb5_context,
3137 ctx->opt_nocanon);
3138 ctx->opt_nocanon = NULL;
3141 if (ctx->krbtgt_ccache != NULL) {
3142 krb5_cc_close(ctx->smb_krb5_context->krb5_context,
3143 ctx->krbtgt_ccache);
3144 ctx->krbtgt_ccache = NULL;
3147 if (ctx->upn_realm != NULL) {
3148 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3149 ctx->upn_realm);
3150 ctx->upn_realm = NULL;
3153 if (ctx->upn_dns != NULL) {
3154 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3155 ctx->upn_dns);
3156 ctx->upn_dns = NULL;
3159 if (ctx->upn_netbios != NULL) {
3160 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3161 ctx->upn_netbios);
3162 ctx->upn_netbios = NULL;
3165 if (ctx->krbtgt_trust_realm != NULL) {
3166 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3167 ctx->krbtgt_trust_realm);
3168 ctx->krbtgt_trust_realm = NULL;
3171 if (ctx->krbtgt_trust_realm_creds != NULL) {
3172 krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3173 ctx->krbtgt_trust_realm_creds);
3174 ctx->krbtgt_trust_realm_creds = NULL;
3177 if (ctx->krbtgt_trust_dns != NULL) {
3178 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3179 ctx->krbtgt_trust_dns);
3180 ctx->krbtgt_trust_dns = NULL;
3183 if (ctx->krbtgt_trust_dns_creds != NULL) {
3184 krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3185 ctx->krbtgt_trust_dns_creds);
3186 ctx->krbtgt_trust_dns_creds = NULL;
3189 if (ctx->krbtgt_trust_netbios != NULL) {
3190 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3191 ctx->krbtgt_trust_netbios);
3192 ctx->krbtgt_trust_netbios = NULL;
3195 if (ctx->krbtgt_trust_netbios_creds != NULL) {
3196 krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3197 ctx->krbtgt_trust_netbios_creds);
3198 ctx->krbtgt_trust_netbios_creds = NULL;
3201 if (ctx->cifs_trust_dns != NULL) {
3202 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3203 ctx->cifs_trust_dns);
3204 ctx->cifs_trust_dns = NULL;
3207 if (ctx->cifs_trust_dns_creds != NULL) {
3208 krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3209 ctx->cifs_trust_dns_creds);
3210 ctx->cifs_trust_dns_creds = NULL;
3213 if (ctx->cifs_trust_netbios != NULL) {
3214 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3215 ctx->cifs_trust_netbios);
3216 ctx->cifs_trust_netbios = NULL;
3219 if (ctx->cifs_trust_netbios_creds != NULL) {
3220 krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3221 ctx->cifs_trust_netbios_creds);
3222 ctx->cifs_trust_netbios_creds = NULL;
3225 if (ctx->drs_trust_dns != NULL) {
3226 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3227 ctx->drs_trust_dns);
3228 ctx->drs_trust_dns = NULL;
3231 if (ctx->drs_trust_dns_creds != NULL) {
3232 krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3233 ctx->drs_trust_dns_creds);
3234 ctx->drs_trust_dns_creds = NULL;
3237 if (ctx->drs_trust_netbios != NULL) {
3238 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3239 ctx->drs_trust_netbios);
3240 ctx->drs_trust_netbios = NULL;
3243 if (ctx->drs_trust_netbios_creds != NULL) {
3244 krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3245 ctx->drs_trust_netbios_creds);
3246 ctx->drs_trust_netbios_creds = NULL;
3249 if (ctx->four_trust_dns != NULL) {
3250 krb5_free_principal(ctx->smb_krb5_context->krb5_context,
3251 ctx->four_trust_dns);
3252 ctx->four_trust_dns = NULL;
3255 if (ctx->four_trust_dns_creds != NULL) {
3256 krb5_free_creds(ctx->smb_krb5_context->krb5_context,
3257 ctx->four_trust_dns_creds);
3258 ctx->four_trust_dns_creds = NULL;
3261 krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3262 &ctx->krbtgt_referral_creds);
3264 free_Ticket(&ctx->krbtgt_referral_ticket);
3266 krb5_free_keyblock_contents(ctx->smb_krb5_context->krb5_context,
3267 &ctx->krbtgt_referral_keyblock);
3269 free_EncTicketPart(&ctx->krbtgt_referral_enc_part);
3271 krb5_free_error_contents(ctx->smb_krb5_context->krb5_context,
3272 &ctx->error);
3274 talloc_unlink(ctx, ctx->smb_krb5_context);
3275 ctx->smb_krb5_context = NULL;
3276 return 0;
3279 static bool check_pw_with_krb5(struct torture_context *tctx,
3280 struct cli_credentials *credentials,
3281 const struct lsa_TrustDomainInfoInfoEx *trusted)
3283 const char *trusted_dns_name = trusted->domain_name.string;
3284 const char *trusted_netbios_name = trusted->netbios_name.string;
3285 char *trusted_realm_name = NULL;
3286 krb5_principal principal = NULL;
3287 enum credentials_obtained obtained;
3288 const char *error_string = NULL;
3289 const char *workstation = cli_credentials_get_workstation(credentials);
3290 const char *password = cli_credentials_get_password(credentials);
3291 #ifndef USING_EMBEDDED_HEIMDAL
3292 const struct samr_Password *nthash = NULL;
3293 const struct samr_Password *old_nthash = NULL;
3294 #endif
3295 const char *old_password = cli_credentials_get_old_password(credentials);
3296 #ifndef USING_EMBEDDED_HEIMDAL
3297 int kvno = cli_credentials_get_kvno(credentials);
3298 int expected_kvno = 0;
3299 krb5uint32 t_kvno = 0;
3300 #endif
3301 const char *host = torture_setting_string(tctx, "host", NULL);
3302 krb5_error_code k5ret;
3303 krb5_boolean k5ok;
3304 int type;
3305 bool ok;
3306 struct check_pw_with_krb5_ctx *ctx = NULL;
3307 char *assertion_message = NULL;
3308 const char *realm = NULL;
3309 char *upn_realm_string = NULL;
3310 char *upn_dns_string = NULL;
3311 char *upn_netbios_string = NULL;
3312 char *krbtgt_cc_name = NULL;
3313 char *krbtgt_trust_realm_string = NULL;
3314 char *krbtgt_trust_dns_string = NULL;
3315 char *krbtgt_trust_netbios_string = NULL;
3316 char *cifs_trust_dns_string = NULL;
3317 char *cifs_trust_netbios_string = NULL;
3318 char *drs_trust_dns_string = NULL;
3319 char *drs_trust_netbios_string = NULL;
3320 char *four_trust_dns_string = NULL;
3322 ctx = talloc_zero(tctx, struct check_pw_with_krb5_ctx);
3323 torture_assert(tctx, ctx != NULL, "Failed to allocate");
3325 realm = cli_credentials_get_realm(credentials);
3326 trusted_realm_name = strupper_talloc(tctx, trusted_dns_name);
3328 #ifndef USING_EMBEDDED_HEIMDAL
3329 nthash = cli_credentials_get_nt_hash(credentials, ctx);
3330 old_nthash = cli_credentials_get_old_nt_hash(credentials, ctx);
3331 #endif
3333 k5ret = smb_krb5_init_context(ctx, tctx->lp_ctx, &ctx->smb_krb5_context);
3334 torture_assert_int_equal(tctx, k5ret, 0, "smb_krb5_init_context failed");
3336 ctx->server_nb_domain = cli_credentials_get_domain(credentials);
3337 ctx->server_dns_domain = cli_credentials_get_realm(credentials);
3339 ok = interpret_string_addr_internal(&ctx->server, host, 0);
3340 torture_assert(tctx, ok, "Failed to parse target server");
3341 talloc_set_destructor(ctx, check_pw_with_krb5_ctx_destructor);
3343 set_sockaddr_port(ctx->server->ai_addr, 88);
3345 k5ret = smb_krb5_set_send_to_kdc_func(ctx->smb_krb5_context,
3346 check_pw_with_krb5_send_to_realm,
3347 NULL, /* send_to_kdc */
3348 ctx);
3349 torture_assert_int_equal(tctx, k5ret, 0, "krb5_set_send_to_kdc_func failed");
3351 torture_assert_int_equal(tctx,
3352 krb5_get_init_creds_opt_alloc(ctx->smb_krb5_context->krb5_context,
3353 &ctx->krb_options),
3354 0, "krb5_get_init_creds_opt_alloc failed");
3355 torture_assert_int_equal(tctx,
3356 krb5_get_init_creds_opt_set_pac_request(
3357 ctx->smb_krb5_context->krb5_context,
3358 ctx->krb_options, true),
3359 0, "krb5_get_init_creds_opt_set_pac_request failed");
3361 upn_realm_string = talloc_asprintf(ctx, "user@%s",
3362 trusted_realm_name);
3363 torture_assert_int_equal(tctx,
3364 smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3365 &ctx->upn_realm,
3366 realm, upn_realm_string, NULL),
3367 0, "smb_krb5_make_principal failed");
3368 smb_krb5_principal_set_type(ctx->smb_krb5_context->krb5_context,
3369 ctx->upn_realm, KRB5_NT_ENTERPRISE_PRINCIPAL);
3371 upn_dns_string = talloc_asprintf(ctx, "user@%s",
3372 trusted_dns_name);
3373 torture_assert_int_equal(tctx,
3374 smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3375 &ctx->upn_dns,
3376 realm, upn_dns_string, NULL),
3377 0, "smb_krb5_make_principal failed");
3378 smb_krb5_principal_set_type(ctx->smb_krb5_context->krb5_context,
3379 ctx->upn_dns, KRB5_NT_ENTERPRISE_PRINCIPAL);
3381 upn_netbios_string = talloc_asprintf(ctx, "user@%s",
3382 trusted_netbios_name);
3383 torture_assert_int_equal(tctx,
3384 smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3385 &ctx->upn_netbios,
3386 realm, upn_netbios_string, NULL),
3387 0, "smb_krb5_make_principal failed");
3388 smb_krb5_principal_set_type(ctx->smb_krb5_context->krb5_context,
3389 ctx->upn_netbios, KRB5_NT_ENTERPRISE_PRINCIPAL);
3391 k5ret = principal_from_credentials(ctx, credentials, ctx->smb_krb5_context,
3392 &principal, &obtained, &error_string);
3393 torture_assert_int_equal(tctx, k5ret, 0, error_string);
3395 ZERO_STRUCT(ctx->counts);
3396 k5ret = krb5_get_init_creds_password(ctx->smb_krb5_context->krb5_context,
3397 &ctx->my_creds, ctx->upn_realm,
3398 "_none_", NULL, NULL, 0,
3399 NULL, ctx->krb_options);
3400 assertion_message = talloc_asprintf(ctx,
3401 "krb5_get_init_creds_password(%s, canon) for failed: "
3402 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u/%u,ok=%u]",
3403 upn_realm_string,
3404 k5ret,
3405 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3406 k5ret, ctx),
3407 trusted->trust_direction,
3408 trusted->trust_type,
3409 trusted->trust_attributes,
3410 ctx->counts.io, ctx->counts.error_io, ctx->counts.errors, ctx->counts.ok);
3411 torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3412 torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3413 torture_assert_int_equal(tctx, ctx->counts.error_io, 1, assertion_message);
3414 torture_assert_int_equal(tctx, KRB5_ERROR_CODE(&ctx->error), 68, assertion_message);
3415 torture_assert(tctx, ctx->error.crealm != NULL, assertion_message);
3416 torture_assert_str_equal(tctx, *ctx->error.crealm, trusted_realm_name, assertion_message);
3417 #ifdef USING_EMBEDDED_HEIMDAL
3418 torture_assert(tctx, ctx->error.cname != NULL, assertion_message);
3419 torture_assert_int_equal(tctx, ctx->error.cname->name_type, KRB5_NT_ENTERPRISE_PRINCIPAL, assertion_message);
3420 torture_assert_int_equal(tctx, ctx->error.cname->name_string.len, 1, assertion_message);
3421 torture_assert_str_equal(tctx, ctx->error.cname->name_string.val[0], upn_realm_string, assertion_message);
3422 #else
3423 torture_assert(tctx, ctx->error.cname == NULL, assertion_message);
3424 #endif
3425 torture_assert_str_equal(tctx, ctx->error.realm, realm, assertion_message);
3427 ZERO_STRUCT(ctx->counts);
3428 k5ret = krb5_get_init_creds_password(ctx->smb_krb5_context->krb5_context,
3429 &ctx->my_creds, ctx->upn_dns,
3430 "_none_", NULL, NULL, 0,
3431 NULL, ctx->krb_options);
3432 assertion_message = talloc_asprintf(ctx,
3433 "krb5_get_init_creds_password(%s, canon) for failed: "
3434 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u/%u,ok=%u]",
3435 upn_dns_string,
3436 k5ret,
3437 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3438 k5ret, ctx),
3439 trusted->trust_direction,
3440 trusted->trust_type,
3441 trusted->trust_attributes,
3442 ctx->counts.io, ctx->counts.error_io, ctx->counts.errors, ctx->counts.ok);
3443 torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3444 torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3445 torture_assert_int_equal(tctx, ctx->counts.error_io, 1, assertion_message);
3446 torture_assert_int_equal(tctx, KRB5_ERROR_CODE(&ctx->error), 68, assertion_message);
3447 torture_assert(tctx, ctx->error.crealm != NULL, assertion_message);
3448 torture_assert_str_equal(tctx, *ctx->error.crealm, trusted_realm_name, assertion_message);
3449 #ifdef USING_EMBEDDED_HEIMDAL
3450 torture_assert(tctx, ctx->error.cname != NULL, assertion_message);
3451 torture_assert_int_equal(tctx, ctx->error.cname->name_type, KRB5_NT_ENTERPRISE_PRINCIPAL, assertion_message);
3452 torture_assert_int_equal(tctx, ctx->error.cname->name_string.len, 1, assertion_message);
3453 torture_assert_str_equal(tctx, ctx->error.cname->name_string.val[0], upn_dns_string, assertion_message);
3454 #else
3455 torture_assert(tctx, ctx->error.cname == NULL, assertion_message);
3456 #endif
3457 torture_assert_str_equal(tctx, ctx->error.realm, realm, assertion_message);
3459 ZERO_STRUCT(ctx->counts);
3460 k5ret = krb5_get_init_creds_password(ctx->smb_krb5_context->krb5_context,
3461 &ctx->my_creds, ctx->upn_netbios,
3462 "_none_", NULL, NULL, 0,
3463 NULL, ctx->krb_options);
3464 assertion_message = talloc_asprintf(ctx,
3465 "krb5_get_init_creds_password(%s, canon) for failed: "
3466 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u/%u,ok=%u]",
3467 upn_netbios_string,
3468 k5ret,
3469 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3470 k5ret, ctx),
3471 trusted->trust_direction,
3472 trusted->trust_type,
3473 trusted->trust_attributes,
3474 ctx->counts.io, ctx->counts.error_io, ctx->counts.errors, ctx->counts.ok);
3475 torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3476 torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3477 torture_assert_int_equal(tctx, ctx->counts.error_io, 1, assertion_message);
3478 torture_assert_int_equal(tctx, KRB5_ERROR_CODE(&ctx->error), 68, assertion_message);
3479 torture_assert(tctx, ctx->error.crealm != NULL, assertion_message);
3480 torture_assert_str_equal(tctx, *ctx->error.crealm, trusted_realm_name, assertion_message);
3481 #ifdef USING_EMBEDDED_HEIMDAL
3482 torture_assert(tctx, ctx->error.cname != NULL, assertion_message);
3483 torture_assert_int_equal(tctx, ctx->error.cname->name_type, KRB5_NT_ENTERPRISE_PRINCIPAL, assertion_message);
3484 torture_assert_int_equal(tctx, ctx->error.cname->name_string.len, 1, assertion_message);
3485 torture_assert_str_equal(tctx, ctx->error.cname->name_string.val[0], upn_netbios_string, assertion_message);
3486 #else
3487 torture_assert(tctx, ctx->error.cname == NULL, assertion_message);
3488 #endif
3489 torture_assert_str_equal(tctx, ctx->error.realm, realm, assertion_message);
3491 torture_comment(tctx, "(%s:%s) password[%s] old_password[%s]\n",
3492 __location__, __FUNCTION__,
3493 password, old_password);
3494 if (old_password != NULL) {
3495 k5ret = krb5_get_init_creds_password(ctx->smb_krb5_context->krb5_context,
3496 &ctx->my_creds, principal,
3497 old_password, NULL, NULL, 0,
3498 NULL, ctx->krb_options);
3499 torture_assert_int_equal(tctx, k5ret, KRB5KDC_ERR_PREAUTH_FAILED,
3500 "preauth should fail with old password");
3503 k5ret = krb5_get_init_creds_password(ctx->smb_krb5_context->krb5_context,
3504 &ctx->my_creds, principal,
3505 password, NULL, NULL, 0,
3506 NULL, ctx->krb_options);
3507 if (k5ret == KRB5KDC_ERR_PREAUTH_FAILED) {
3508 TALLOC_FREE(ctx);
3509 return false;
3512 assertion_message = talloc_asprintf(ctx,
3513 "krb5_get_init_creds_password for failed: %s",
3514 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3515 k5ret, ctx));
3516 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3518 torture_assert_int_equal(tctx,
3519 krb5_get_creds_opt_alloc(ctx->smb_krb5_context->krb5_context,
3520 &ctx->opt_canon),
3521 0, "krb5_get_creds_opt_alloc");
3523 krb5_get_creds_opt_add_options(ctx->smb_krb5_context->krb5_context,
3524 ctx->opt_canon,
3525 KRB5_GC_CANONICALIZE);
3527 krb5_get_creds_opt_add_options(ctx->smb_krb5_context->krb5_context,
3528 ctx->opt_canon,
3529 KRB5_GC_NO_STORE);
3531 torture_assert_int_equal(tctx,
3532 krb5_get_creds_opt_alloc(ctx->smb_krb5_context->krb5_context,
3533 &ctx->opt_nocanon),
3534 0, "krb5_get_creds_opt_alloc");
3536 krb5_get_creds_opt_add_options(ctx->smb_krb5_context->krb5_context,
3537 ctx->opt_nocanon,
3538 KRB5_GC_NO_STORE);
3540 krbtgt_cc_name = talloc_asprintf(ctx, "MEMORY:%p.krbtgt", ctx->smb_krb5_context);
3541 torture_assert_int_equal(tctx,
3542 krb5_cc_resolve(ctx->smb_krb5_context->krb5_context,
3543 krbtgt_cc_name,
3544 &ctx->krbtgt_ccache),
3545 0, "krb5_cc_resolve failed");
3547 torture_assert_int_equal(tctx,
3548 krb5_cc_initialize(ctx->smb_krb5_context->krb5_context,
3549 ctx->krbtgt_ccache,
3550 ctx->my_creds.client),
3551 0, "krb5_cc_initialize failed");
3553 torture_assert_int_equal(tctx,
3554 krb5_cc_store_cred(ctx->smb_krb5_context->krb5_context,
3555 ctx->krbtgt_ccache,
3556 &ctx->my_creds),
3557 0, "krb5_cc_store_cred failed");
3559 krbtgt_trust_realm_string = talloc_asprintf(ctx, "krbtgt/%s@%s",
3560 trusted_realm_name, realm);
3561 torture_assert_int_equal(tctx,
3562 smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3563 &ctx->krbtgt_trust_realm,
3564 realm, "krbtgt",
3565 trusted_realm_name, NULL),
3566 0, "smb_krb5_make_principal failed");
3568 krbtgt_trust_dns_string = talloc_asprintf(ctx, "krbtgt/%s@%s",
3569 trusted_dns_name, realm);
3570 torture_assert_int_equal(tctx,
3571 smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3572 &ctx->krbtgt_trust_dns,
3573 realm, "krbtgt",
3574 trusted_dns_name, NULL),
3575 0, "smb_krb5_make_principal failed");
3577 krbtgt_trust_netbios_string = talloc_asprintf(ctx, "krbtgt/%s@%s",
3578 trusted_netbios_name, realm);
3579 torture_assert_int_equal(tctx,
3580 smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3581 &ctx->krbtgt_trust_netbios,
3582 realm, "krbtgt",
3583 trusted_netbios_name, NULL),
3584 0, "smb_krb5_make_principal failed");
3586 /* Confirm if we can do a TGS for krbtgt/trusted_realm */
3587 ZERO_STRUCT(ctx->counts);
3588 k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3589 ctx->opt_nocanon,
3590 ctx->krbtgt_ccache,
3591 ctx->krbtgt_trust_realm,
3592 &ctx->krbtgt_trust_realm_creds);
3593 assertion_message = talloc_asprintf(ctx,
3594 "krb5_get_creds(%s, canon) for failed: "
3595 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3596 krbtgt_trust_realm_string,
3597 k5ret,
3598 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3599 k5ret, ctx),
3600 trusted->trust_direction,
3601 trusted->trust_type,
3602 trusted->trust_attributes,
3603 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3604 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3605 torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3606 torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
3608 k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3609 ctx->krbtgt_trust_realm_creds->server,
3610 ctx->krbtgt_trust_realm);
3611 torture_assert(tctx, k5ok, assertion_message);
3612 type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3613 ctx->krbtgt_trust_realm_creds->server);
3614 torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3616 /* Confirm if we have no referral ticket in the cache */
3617 krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3618 &ctx->krbtgt_referral_creds);
3619 k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3620 ctx->krbtgt_ccache,
3622 ctx->krbtgt_trust_realm_creds,
3623 &ctx->krbtgt_referral_creds);
3624 assertion_message = talloc_asprintf(ctx,
3625 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3626 krbtgt_trust_realm_string,
3627 k5ret,
3628 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3629 k5ret, ctx));
3630 torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
3632 /* Confirm if we can do a TGS for krbtgt/trusted_dns with CANON */
3633 ZERO_STRUCT(ctx->counts);
3634 k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3635 ctx->opt_canon,
3636 ctx->krbtgt_ccache,
3637 ctx->krbtgt_trust_dns,
3638 &ctx->krbtgt_trust_dns_creds);
3639 assertion_message = talloc_asprintf(ctx,
3640 "krb5_get_creds(%s, canon) for failed: "
3641 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3642 krbtgt_trust_dns_string,
3643 k5ret,
3644 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3645 k5ret, ctx),
3646 trusted->trust_direction,
3647 trusted->trust_type,
3648 trusted->trust_attributes,
3649 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3650 #ifdef USING_EMBEDDED_HEIMDAL
3651 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3652 #else
3653 torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3654 #endif
3655 torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3656 torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
3658 /* Confirm if we have the referral ticket in the cache */
3659 krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3660 &ctx->krbtgt_referral_creds);
3661 k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3662 ctx->krbtgt_ccache,
3664 ctx->krbtgt_trust_realm_creds,
3665 &ctx->krbtgt_referral_creds);
3666 assertion_message = talloc_asprintf(ctx,
3667 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3668 krbtgt_trust_realm_string,
3669 k5ret,
3670 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3671 k5ret, ctx));
3672 #ifdef USING_EMBEDDED_HEIMDAL
3673 torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
3674 #else
3675 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3677 k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3678 ctx->krbtgt_referral_creds.server,
3679 ctx->krbtgt_trust_realm);
3680 torture_assert(tctx, k5ok, assertion_message);
3681 type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3682 ctx->krbtgt_referral_creds.server);
3683 torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3684 k5ret = decode_Ticket(ctx->krbtgt_referral_creds.ticket.data,
3685 ctx->krbtgt_referral_creds.ticket.length,
3686 &ctx->krbtgt_referral_ticket, NULL);
3687 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3688 if (kvno > 0) {
3689 expected_kvno = kvno - 1;
3691 if (ctx->krbtgt_referral_ticket.enc_part.kvno != NULL) {
3692 t_kvno = *ctx->krbtgt_referral_ticket.enc_part.kvno;
3693 assertion_message = talloc_asprintf(ctx,
3694 "krbtgt_referral_ticket(%s) kvno(%u) expected(%u) current(%u)",
3695 krbtgt_trust_realm_string,
3696 (unsigned)t_kvno, (unsigned)expected_kvno,(unsigned)kvno);
3697 torture_comment(tctx, "%s\n", assertion_message);
3698 torture_assert_int_not_equal(tctx, t_kvno, 0, assertion_message);
3699 } else {
3700 assertion_message = talloc_asprintf(ctx,
3701 "krbtgt_referral_ticket(%s) kvno(NULL) expected(%u) current(%u)",
3702 krbtgt_trust_realm_string,
3703 (unsigned)expected_kvno,(unsigned)kvno);
3704 torture_comment(tctx, "%s\n", assertion_message);
3706 torture_assert_int_equal(tctx, t_kvno, expected_kvno, assertion_message);
3708 if (old_nthash != NULL && expected_kvno != kvno) {
3709 torture_comment(tctx, "old_nthash: %s\n", assertion_message);
3710 k5ret = smb_krb5_keyblock_init_contents(ctx->smb_krb5_context->krb5_context,
3711 ENCTYPE_ARCFOUR_HMAC,
3712 old_nthash->hash,
3713 sizeof(old_nthash->hash),
3714 &ctx->krbtgt_referral_keyblock);
3715 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3716 } else {
3717 torture_comment(tctx, "nthash: %s\n", assertion_message);
3718 k5ret = smb_krb5_keyblock_init_contents(ctx->smb_krb5_context->krb5_context,
3719 ENCTYPE_ARCFOUR_HMAC,
3720 nthash->hash,
3721 sizeof(nthash->hash),
3722 &ctx->krbtgt_referral_keyblock);
3723 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3725 k5ret = krb5_decrypt_ticket(ctx->smb_krb5_context->krb5_context,
3726 &ctx->krbtgt_referral_ticket,
3727 &ctx->krbtgt_referral_keyblock,
3728 &ctx->krbtgt_referral_enc_part,
3730 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3732 /* Delete the referral ticket from the cache */
3733 k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
3734 ctx->krbtgt_ccache,
3736 &ctx->krbtgt_referral_creds);
3737 assertion_message = talloc_asprintf(ctx,
3738 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
3739 krbtgt_trust_realm_string,
3740 k5ret,
3741 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3742 k5ret, ctx));
3743 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3744 #endif
3746 /* Confirm if we can do a TGS for krbtgt/trusted_dns no CANON */
3747 ZERO_STRUCT(ctx->counts);
3748 k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3749 ctx->opt_nocanon,
3750 ctx->krbtgt_ccache,
3751 ctx->krbtgt_trust_dns,
3752 &ctx->krbtgt_trust_dns_creds);
3753 assertion_message = talloc_asprintf(ctx,
3754 "krb5_get_creds(%s, nocanon) for failed: "
3755 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3756 krbtgt_trust_dns_string,
3757 k5ret,
3758 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3759 k5ret, ctx),
3760 trusted->trust_direction,
3761 trusted->trust_type,
3762 trusted->trust_attributes,
3763 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3764 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3765 #ifdef USING_EMBEDDED_HEIMDAL
3766 torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3767 torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
3768 #else
3769 torture_assert_int_equal(tctx, ctx->counts.io, 2, assertion_message);
3770 torture_assert_int_equal(tctx, ctx->counts.ok, 2, assertion_message);
3771 #endif
3773 k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3774 ctx->krbtgt_trust_dns_creds->server,
3775 #ifdef USING_EMBEDDED_HEIMDAL
3776 ctx->krbtgt_trust_dns);
3777 #else
3778 ctx->krbtgt_trust_realm);
3779 #endif
3780 torture_assert(tctx, k5ok, assertion_message);
3781 type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3782 ctx->krbtgt_trust_dns_creds->server);
3783 torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3785 /* Confirm if we have the referral ticket in the cache */
3786 krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3787 &ctx->krbtgt_referral_creds);
3788 k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3789 ctx->krbtgt_ccache,
3791 ctx->krbtgt_trust_realm_creds,
3792 &ctx->krbtgt_referral_creds);
3793 assertion_message = talloc_asprintf(ctx,
3794 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3795 krbtgt_trust_realm_string,
3796 k5ret,
3797 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3798 k5ret, ctx));
3799 #ifdef USING_EMBEDDED_HEIMDAL
3800 torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
3801 #else
3802 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3804 k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3805 ctx->krbtgt_referral_creds.server,
3806 ctx->krbtgt_trust_realm);
3807 torture_assert(tctx, k5ok, assertion_message);
3808 type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3809 ctx->krbtgt_referral_creds.server);
3810 torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3812 /* Delete the referral ticket from the cache */
3813 k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
3814 ctx->krbtgt_ccache,
3816 &ctx->krbtgt_referral_creds);
3817 assertion_message = talloc_asprintf(ctx,
3818 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
3819 krbtgt_trust_realm_string,
3820 k5ret,
3821 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3822 k5ret, ctx));
3823 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3824 #endif
3826 /* Confirm if we can do a TGS for krbtgt/NETBIOS with CANON */
3827 ZERO_STRUCT(ctx->counts);
3828 k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3829 ctx->opt_canon,
3830 ctx->krbtgt_ccache,
3831 ctx->krbtgt_trust_netbios,
3832 &ctx->krbtgt_trust_netbios_creds);
3833 assertion_message = talloc_asprintf(ctx,
3834 "krb5_get_creds(%s, canon) for failed: "
3835 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3836 krbtgt_trust_netbios_string,
3837 k5ret,
3838 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3839 k5ret, ctx),
3840 trusted->trust_direction,
3841 trusted->trust_type,
3842 trusted->trust_attributes,
3843 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3844 #ifdef USING_EMBEDDED_HEIMDAL
3845 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3846 #else
3847 torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
3848 #endif
3849 torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3850 torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
3852 /* Confirm if we have the referral ticket in the cache */
3853 krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3854 &ctx->krbtgt_referral_creds);
3855 k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3856 ctx->krbtgt_ccache,
3858 ctx->krbtgt_trust_realm_creds,
3859 &ctx->krbtgt_referral_creds);
3860 assertion_message = talloc_asprintf(ctx,
3861 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3862 krbtgt_trust_netbios_string,
3863 k5ret,
3864 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3865 k5ret, ctx));
3866 #ifdef USING_EMBEDDED_HEIMDAL
3867 torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
3868 #else
3869 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3871 k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3872 ctx->krbtgt_referral_creds.server,
3873 ctx->krbtgt_trust_realm);
3874 torture_assert(tctx, k5ok, assertion_message);
3875 type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3876 ctx->krbtgt_referral_creds.server);
3877 torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3879 /* Delete the referral ticket from the cache */
3880 k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
3881 ctx->krbtgt_ccache,
3883 &ctx->krbtgt_referral_creds);
3884 assertion_message = talloc_asprintf(ctx,
3885 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
3886 krbtgt_trust_realm_string,
3887 k5ret,
3888 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3889 k5ret, ctx));
3890 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3891 #endif
3893 /* Confirm if we can do a TGS for krbtgt/NETBIOS no CANON */
3894 ZERO_STRUCT(ctx->counts);
3895 k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3896 ctx->opt_nocanon,
3897 ctx->krbtgt_ccache,
3898 ctx->krbtgt_trust_netbios,
3899 &ctx->krbtgt_trust_netbios_creds);
3900 assertion_message = talloc_asprintf(ctx,
3901 "krb5_get_creds(%s, nocanon) for failed: "
3902 "(%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3903 krbtgt_trust_netbios_string,
3904 k5ret,
3905 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3906 k5ret, ctx),
3907 trusted->trust_direction,
3908 trusted->trust_type,
3909 trusted->trust_attributes,
3910 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3911 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3912 #ifdef USING_EMBEDDED_HEIMDAL
3913 torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
3914 torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
3915 #else
3916 torture_assert_int_equal(tctx, ctx->counts.io, 2, assertion_message);
3917 torture_assert_int_equal(tctx, ctx->counts.ok, 2, assertion_message);
3918 #endif
3920 k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3921 ctx->krbtgt_trust_netbios_creds->server,
3922 #ifdef USING_EMBEDDED_HEIMDAL
3923 ctx->krbtgt_trust_netbios);
3924 #else
3925 ctx->krbtgt_trust_realm);
3926 #endif
3927 torture_assert(tctx, k5ok, assertion_message);
3928 type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3929 ctx->krbtgt_trust_netbios_creds->server);
3930 torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3932 /* Confirm if we have the referral ticket in the cache */
3933 krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
3934 &ctx->krbtgt_referral_creds);
3935 k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
3936 ctx->krbtgt_ccache,
3938 ctx->krbtgt_trust_realm_creds,
3939 &ctx->krbtgt_referral_creds);
3940 assertion_message = talloc_asprintf(ctx,
3941 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
3942 krbtgt_trust_realm_string,
3943 k5ret,
3944 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3945 k5ret, ctx));
3946 #ifdef USING_EMBEDDED_HEIMDAL
3947 torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
3948 #else
3949 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3951 k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
3952 ctx->krbtgt_referral_creds.server,
3953 ctx->krbtgt_trust_realm);
3954 torture_assert(tctx, k5ok, assertion_message);
3955 type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
3956 ctx->krbtgt_referral_creds.server);
3957 torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
3959 /* Delete the referral ticket from the cache */
3960 k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
3961 ctx->krbtgt_ccache,
3963 &ctx->krbtgt_referral_creds);
3964 assertion_message = talloc_asprintf(ctx,
3965 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
3966 krbtgt_trust_realm_string,
3967 k5ret,
3968 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3969 k5ret, ctx));
3970 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
3971 #endif
3973 cifs_trust_dns_string = talloc_asprintf(ctx, "cifs/%s@%s",
3974 trusted_dns_name, realm);
3975 torture_assert_int_equal(tctx,
3976 smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
3977 &ctx->cifs_trust_dns,
3978 realm, "cifs",
3979 trusted_dns_name, NULL),
3980 0, "smb_krb5_make_principal failed");
3982 /* Confirm if we get krbtgt/trusted_realm back when asking for cifs/trusted_realm */
3983 ZERO_STRUCT(ctx->counts);
3984 k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
3985 ctx->opt_canon,
3986 ctx->krbtgt_ccache,
3987 ctx->cifs_trust_dns,
3988 &ctx->cifs_trust_dns_creds);
3989 assertion_message = talloc_asprintf(ctx,
3990 "krb5_get_creds(%s) for failed: (%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
3991 cifs_trust_dns_string,
3992 k5ret,
3993 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
3994 k5ret, ctx),
3995 trusted->trust_direction,
3996 trusted->trust_type,
3997 trusted->trust_attributes,
3998 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
3999 torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
4000 #ifdef USING_EMBEDDED_HEIMDAL
4001 torture_assert_int_equal(tctx, ctx->counts.io, 2, assertion_message);
4002 torture_assert_int_equal(tctx, ctx->counts.ok, 2, assertion_message);
4003 #else
4004 torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
4005 torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
4006 #endif
4008 /* Confirm if we have the referral ticket in the cache */
4009 krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
4010 &ctx->krbtgt_referral_creds);
4011 k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
4012 ctx->krbtgt_ccache,
4014 ctx->krbtgt_trust_realm_creds,
4015 &ctx->krbtgt_referral_creds);
4016 assertion_message = talloc_asprintf(ctx,
4017 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
4018 krbtgt_trust_realm_string,
4019 k5ret,
4020 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4021 k5ret, ctx));
4022 #ifdef USING_EMBEDDED_HEIMDAL
4023 torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
4024 #else
4025 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
4027 k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
4028 ctx->krbtgt_referral_creds.server,
4029 ctx->krbtgt_trust_realm);
4030 torture_assert(tctx, k5ok, assertion_message);
4031 type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
4032 ctx->krbtgt_referral_creds.server);
4033 torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
4035 /* Delete the referral ticket from the cache */
4036 k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
4037 ctx->krbtgt_ccache,
4039 &ctx->krbtgt_referral_creds);
4040 assertion_message = talloc_asprintf(ctx,
4041 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
4042 krbtgt_trust_realm_string,
4043 k5ret,
4044 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4045 k5ret, ctx));
4046 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
4047 #endif
4049 cifs_trust_netbios_string = talloc_asprintf(ctx, "cifs/%s@%s",
4050 trusted_netbios_name, realm);
4051 torture_assert_int_equal(tctx,
4052 smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
4053 &ctx->cifs_trust_netbios,
4054 realm, "cifs",
4055 trusted_netbios_name, NULL),
4056 0, "smb_krb5_make_principal failed");
4058 /* Confirm if we get krbtgt/trusted_realm back when asking for cifs/trusted_realm */
4059 ZERO_STRUCT(ctx->counts);
4060 k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
4061 ctx->opt_canon,
4062 ctx->krbtgt_ccache,
4063 ctx->cifs_trust_netbios,
4064 &ctx->cifs_trust_netbios_creds);
4065 assertion_message = talloc_asprintf(ctx,
4066 "krb5_get_creds(%s) for failed: (%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
4067 cifs_trust_netbios_string,
4068 k5ret,
4069 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4070 k5ret, ctx),
4071 trusted->trust_direction,
4072 trusted->trust_type,
4073 trusted->trust_attributes,
4074 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
4075 torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
4076 #ifdef USING_EMBEDDED_HEIMDAL
4077 torture_assert_int_equal(tctx, ctx->counts.io, 2, assertion_message);
4078 torture_assert_int_equal(tctx, ctx->counts.ok, 2, assertion_message);
4079 #else
4080 torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
4081 torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
4082 #endif
4084 /* Confirm if we have the referral ticket in the cache */
4085 krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
4086 &ctx->krbtgt_referral_creds);
4087 k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
4088 ctx->krbtgt_ccache,
4090 ctx->krbtgt_trust_realm_creds,
4091 &ctx->krbtgt_referral_creds);
4092 assertion_message = talloc_asprintf(ctx,
4093 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
4094 krbtgt_trust_realm_string,
4095 k5ret,
4096 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4097 k5ret, ctx));
4098 #ifdef USING_EMBEDDED_HEIMDAL
4099 torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
4100 #else
4101 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
4103 k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
4104 ctx->krbtgt_referral_creds.server,
4105 ctx->krbtgt_trust_realm);
4106 torture_assert(tctx, k5ok, assertion_message);
4107 type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
4108 ctx->krbtgt_referral_creds.server);
4109 torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
4111 /* Delete the referral ticket from the cache */
4112 k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
4113 ctx->krbtgt_ccache,
4115 &ctx->krbtgt_referral_creds);
4116 assertion_message = talloc_asprintf(ctx,
4117 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
4118 krbtgt_trust_realm_string,
4119 k5ret,
4120 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4121 k5ret, ctx));
4122 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
4123 #endif
4125 drs_trust_dns_string = talloc_asprintf(ctx,
4126 "E3514235-4B06-11D1-AB04-00C04FC2DCD2/%s/%s@%s",
4127 workstation, trusted_dns_name, realm);
4128 torture_assert_int_equal(tctx,
4129 smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
4130 &ctx->drs_trust_dns,
4131 realm, "E3514235-4B06-11D1-AB04-00C04FC2DCD2",
4132 workstation, trusted_dns_name, NULL),
4133 0, "smb_krb5_make_principal failed");
4135 /* Confirm if we get krbtgt/trusted_realm back when asking for a 3 part principal */
4136 ZERO_STRUCT(ctx->counts);
4137 k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
4138 ctx->opt_canon,
4139 ctx->krbtgt_ccache,
4140 ctx->drs_trust_dns,
4141 &ctx->drs_trust_dns_creds);
4142 assertion_message = talloc_asprintf(ctx,
4143 "krb5_get_creds(%s) for failed: (%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
4144 drs_trust_dns_string,
4145 k5ret,
4146 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4147 k5ret, ctx),
4148 trusted->trust_direction,
4149 trusted->trust_type,
4150 trusted->trust_attributes,
4151 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
4152 torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
4153 #ifdef USING_EMBEDDED_HEIMDAL
4154 torture_assert_int_equal(tctx, ctx->counts.io, 2, assertion_message);
4155 torture_assert_int_equal(tctx, ctx->counts.ok, 2, assertion_message);
4156 #else
4157 torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
4158 torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
4159 #endif
4161 /* Confirm if we have the referral ticket in the cache */
4162 krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
4163 &ctx->krbtgt_referral_creds);
4164 k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
4165 ctx->krbtgt_ccache,
4167 ctx->krbtgt_trust_realm_creds,
4168 &ctx->krbtgt_referral_creds);
4169 assertion_message = talloc_asprintf(ctx,
4170 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
4171 krbtgt_trust_realm_string,
4172 k5ret,
4173 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4174 k5ret, ctx));
4175 #ifdef USING_EMBEDDED_HEIMDAL
4176 torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
4177 #else
4178 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
4180 k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
4181 ctx->krbtgt_referral_creds.server,
4182 ctx->krbtgt_trust_realm);
4183 torture_assert(tctx, k5ok, assertion_message);
4184 type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
4185 ctx->krbtgt_referral_creds.server);
4186 torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
4188 /* Delete the referral ticket from the cache */
4189 k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
4190 ctx->krbtgt_ccache,
4192 &ctx->krbtgt_referral_creds);
4193 assertion_message = talloc_asprintf(ctx,
4194 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
4195 krbtgt_trust_realm_string,
4196 k5ret,
4197 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4198 k5ret, ctx));
4199 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
4200 #endif
4202 drs_trust_netbios_string = talloc_asprintf(ctx,
4203 "E3514235-4B06-11D1-AB04-00C04FC2DCD2/%s/%s@%s",
4204 workstation, trusted_netbios_name, realm);
4205 torture_assert_int_equal(tctx,
4206 smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
4207 &ctx->drs_trust_netbios,
4208 realm, "E3514235-4B06-11D1-AB04-00C04FC2DCD2",
4209 workstation, trusted_netbios_name, NULL),
4210 0, "smb_krb5_make_principal failed");
4212 /* Confirm if we get krbtgt/trusted_realm back when asking for a 3 part principal */
4213 ZERO_STRUCT(ctx->counts);
4214 k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
4215 ctx->opt_canon,
4216 ctx->krbtgt_ccache,
4217 ctx->drs_trust_netbios,
4218 &ctx->drs_trust_netbios_creds);
4219 assertion_message = talloc_asprintf(ctx,
4220 "krb5_get_creds(%s) for failed: (%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
4221 drs_trust_netbios_string,
4222 k5ret,
4223 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4224 k5ret, ctx),
4225 trusted->trust_direction,
4226 trusted->trust_type,
4227 trusted->trust_attributes,
4228 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
4229 torture_assert_int_equal(tctx, k5ret, KRB5_KDC_UNREACH, assertion_message);
4230 #ifdef USING_EMBEDDED_HEIMDAL
4231 torture_assert_int_equal(tctx, ctx->counts.io, 2, assertion_message);
4232 torture_assert_int_equal(tctx, ctx->counts.ok, 2, assertion_message);
4233 #else
4234 torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
4235 torture_assert_int_equal(tctx, ctx->counts.ok, 1, assertion_message);
4236 #endif
4238 /* Confirm if we have the referral ticket in the cache */
4239 krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
4240 &ctx->krbtgt_referral_creds);
4241 k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
4242 ctx->krbtgt_ccache,
4244 ctx->krbtgt_trust_realm_creds,
4245 &ctx->krbtgt_referral_creds);
4246 assertion_message = talloc_asprintf(ctx,
4247 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
4248 krbtgt_trust_realm_string,
4249 k5ret,
4250 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4251 k5ret, ctx));
4252 #ifdef USING_EMBEDDED_HEIMDAL
4253 torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
4254 #else
4255 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
4257 k5ok = krb5_principal_compare(ctx->smb_krb5_context->krb5_context,
4258 ctx->krbtgt_referral_creds.server,
4259 ctx->krbtgt_trust_realm);
4260 torture_assert(tctx, k5ok, assertion_message);
4261 type = smb_krb5_principal_get_type(ctx->smb_krb5_context->krb5_context,
4262 ctx->krbtgt_referral_creds.server);
4263 torture_assert_int_equal(tctx, type, KRB5_NT_SRV_INST, assertion_message);
4265 /* Delete the referral ticket from the cache */
4266 k5ret = krb5_cc_remove_cred(ctx->smb_krb5_context->krb5_context,
4267 ctx->krbtgt_ccache,
4269 &ctx->krbtgt_referral_creds);
4270 assertion_message = talloc_asprintf(ctx,
4271 "krb5_cc_remove_cred(%s) for failed: (%d) %s",
4272 krbtgt_trust_realm_string,
4273 k5ret,
4274 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4275 k5ret, ctx));
4276 torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
4277 #endif
4279 four_trust_dns_string = talloc_asprintf(ctx, "four/tree/two/%s@%s",
4280 trusted_dns_name, realm);
4281 torture_assert_int_equal(tctx,
4282 smb_krb5_make_principal(ctx->smb_krb5_context->krb5_context,
4283 &ctx->four_trust_dns,
4284 realm, "four", "tree", "two",
4285 trusted_dns_name, NULL),
4286 0, "smb_krb5_make_principal failed");
4288 /* Confirm if we get an error back for a 4 part principal */
4289 ZERO_STRUCT(ctx->counts);
4290 k5ret = krb5_get_creds(ctx->smb_krb5_context->krb5_context,
4291 ctx->opt_canon,
4292 ctx->krbtgt_ccache,
4293 ctx->four_trust_dns,
4294 &ctx->four_trust_dns_creds);
4295 assertion_message = talloc_asprintf(ctx,
4296 "krb5_get_creds(%s) for failed: (%d) %s; t[d=0x%x,t=0x%x,a=0x%x] [io=%u,error=%u,ok=%u]",
4297 four_trust_dns_string,
4298 k5ret,
4299 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4300 k5ret, ctx),
4301 trusted->trust_direction,
4302 trusted->trust_type,
4303 trusted->trust_attributes,
4304 ctx->counts.io, ctx->counts.errors, ctx->counts.ok);
4305 torture_assert_int_equal(tctx, k5ret, KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN, assertion_message);
4306 #ifdef USING_EMBEDDED_HEIMDAL
4307 torture_assert_int_equal(tctx, ctx->counts.io, 2, assertion_message);
4308 torture_assert_int_equal(tctx, ctx->counts.error_io, 2, assertion_message);
4309 #else
4310 torture_assert_int_equal(tctx, ctx->counts.io, 1, assertion_message);
4311 torture_assert_int_equal(tctx, ctx->counts.error_io, 1, assertion_message);
4312 #endif
4313 torture_assert_int_equal(tctx, KRB5_ERROR_CODE(&ctx->error), 7, assertion_message);
4315 /* Confirm if we have no referral ticket in the cache */
4316 krb5_free_cred_contents(ctx->smb_krb5_context->krb5_context,
4317 &ctx->krbtgt_referral_creds);
4318 k5ret = krb5_cc_retrieve_cred(ctx->smb_krb5_context->krb5_context,
4319 ctx->krbtgt_ccache,
4321 ctx->krbtgt_trust_realm_creds,
4322 &ctx->krbtgt_referral_creds);
4323 assertion_message = talloc_asprintf(ctx,
4324 "krb5_cc_retrieve_cred(%s) for failed: (%d) %s",
4325 krbtgt_trust_realm_string,
4326 k5ret,
4327 smb_get_krb5_error_message(ctx->smb_krb5_context->krb5_context,
4328 k5ret, ctx));
4329 torture_assert_int_equal(tctx, k5ret, KRB5_CC_END, assertion_message);
4331 TALLOC_FREE(ctx);
4332 return true;
4334 #endif
4336 static bool check_dom_trust_pw(struct dcerpc_pipe *p,
4337 struct torture_context *tctx,
4338 const char *our_netbios_name,
4339 const char *our_dns_name,
4340 enum netr_SchannelType secure_channel_type,
4341 const struct lsa_TrustDomainInfoInfoEx *trusted,
4342 const char *previous_password,
4343 const char *current_password,
4344 uint32_t current_version,
4345 const char *next_password,
4346 uint32_t next_version,
4347 bool expected_result)
4349 struct cli_credentials *incoming_creds;
4350 char *server_name = NULL;
4351 char *account = NULL;
4352 char *principal = NULL;
4353 char *workstation = NULL;
4354 const char *binding = torture_setting_string(tctx, "binding", NULL);
4355 const char *host = torture_setting_string(tctx, "host", NULL);
4356 const char *ip;
4357 struct nbt_name nbt_name;
4358 struct dcerpc_binding *b2;
4359 struct netlogon_creds_CredentialState *creds;
4360 struct samr_CryptPassword samr_crypt_password;
4361 struct netr_CryptPassword netr_crypt_password;
4362 struct netr_Authenticator req_auth;
4363 struct netr_Authenticator rep_auth;
4364 struct netr_ServerPasswordSet2 s;
4365 struct dcerpc_pipe *p1 = NULL;
4366 struct dcerpc_pipe *p2 = NULL;
4367 NTSTATUS status;
4368 bool ok;
4369 int rc;
4370 const char *trusted_netbios_name = trusted->netbios_name.string;
4371 const char *trusted_dns_name = trusted->domain_name.string;
4372 struct tsocket_address *dest_addr;
4373 struct netlogon_samlogon_response **responses = NULL;
4374 struct netlogon_samlogon_response *resp = NULL;
4375 enum dcerpc_AuthType auth_type;
4376 enum dcerpc_AuthLevel auth_level;
4378 incoming_creds = cli_credentials_init(tctx);
4379 torture_assert(tctx, incoming_creds, "cli_credentials_init");
4381 cli_credentials_set_domain(incoming_creds, our_netbios_name, CRED_SPECIFIED);
4382 cli_credentials_set_realm(incoming_creds, our_dns_name, CRED_SPECIFIED);
4384 if (secure_channel_type == SEC_CHAN_DNS_DOMAIN) {
4385 account = talloc_asprintf(tctx, "%s.", trusted_dns_name);
4386 torture_assert(tctx, account, __location__);
4388 principal = talloc_asprintf(tctx, "%s$@%s",
4389 trusted_netbios_name,
4390 cli_credentials_get_realm(incoming_creds));
4391 torture_assert(tctx, principal, __location__);
4393 workstation = talloc_asprintf(tctx, "%sUP",
4394 trusted_netbios_name);
4395 torture_assert(tctx, workstation, __location__);
4396 } else {
4397 account = talloc_asprintf(tctx, "%s$", trusted_netbios_name);
4398 torture_assert(tctx, account, __location__);
4400 workstation = talloc_asprintf(tctx, "%sDOWN",
4401 trusted_netbios_name);
4402 torture_assert(tctx, workstation, __location__);
4405 cli_credentials_set_username(incoming_creds, account, CRED_SPECIFIED);
4406 if (principal != NULL) {
4407 cli_credentials_set_principal(incoming_creds, principal,
4408 CRED_SPECIFIED);
4410 cli_credentials_set_kvno(incoming_creds, current_version);
4411 cli_credentials_set_password(incoming_creds, current_password, CRED_SPECIFIED);
4412 cli_credentials_set_old_password(incoming_creds, previous_password, CRED_SPECIFIED);
4413 cli_credentials_set_workstation(incoming_creds, workstation, CRED_SPECIFIED);
4414 cli_credentials_set_secure_channel_type(incoming_creds, secure_channel_type);
4416 make_nbt_name_server(&nbt_name, host);
4418 status = resolve_name_ex(lpcfg_resolve_context(tctx->lp_ctx),
4419 0, 0, &nbt_name, tctx, &ip, tctx->ev);
4420 torture_assert_ntstatus_ok(tctx, status,
4421 talloc_asprintf(tctx,"Failed to resolve %s: %s",
4422 nbt_name.name, nt_errstr(status)));
4424 rc = tsocket_address_inet_from_strings(
4425 tctx, "ip", ip, 389, &dest_addr);
4426 torture_assert_int_equal(
4427 tctx,
4430 talloc_asprintf(tctx,
4431 "tsocket_address_inet_from_strings failed "
4432 "parsing %s:%d",
4433 host,
4434 389));
4436 status = netlogon_pings(tctx, /* mem_ctx */
4437 lpcfg_client_netlogon_ping_protocol(
4438 tctx->lp_ctx), /* proto */
4439 &dest_addr, /* servers */
4440 1, /* num_servers */
4441 (struct netlogon_ping_filter){
4442 .ntversion = NETLOGON_NT_VERSION_5 |
4443 NETLOGON_NT_VERSION_5EX,
4444 .acct_ctrl = (secure_channel_type ==
4445 SEC_CHAN_DNS_DOMAIN)
4446 ? ACB_AUTOLOCK
4447 : ACB_DOMTRUST,
4448 .user = account,
4450 1, /* min_servers */
4451 tevent_timeval_current_ofs(2, 0), /* timeout */
4452 &responses);
4453 torture_assert_ntstatus_ok(tctx, status, "netlogon_pings");
4455 resp = responses[0];
4457 torture_assert_int_equal(tctx,
4458 resp->ntver,
4459 NETLOGON_NT_VERSION_5EX,
4460 "ntver");
4461 torture_assert_int_equal(tctx,
4462 resp->data.nt5_ex.nt_version,
4463 NETLOGON_NT_VERSION_1 |
4464 NETLOGON_NT_VERSION_5EX,
4465 "nt_version");
4466 torture_assert_int_equal(tctx,
4467 resp->data.nt5_ex.command,
4468 LOGON_SAM_LOGON_RESPONSE_EX,
4469 "command");
4470 torture_assert_str_equal(tctx,
4471 resp->data.nt5_ex.user_name,
4472 account,
4473 "user_name");
4474 server_name = talloc_asprintf(tctx,
4475 "\\\\%s",
4476 resp->data.nt5_ex.pdc_dns_name);
4477 torture_assert(tctx, server_name, __location__);
4479 status = dcerpc_parse_binding(tctx, binding, &b2);
4480 torture_assert_ntstatus_ok(tctx, status, "Bad binding string");
4482 status = dcerpc_pipe_connect_b(tctx, &p1, b2,
4483 &ndr_table_netlogon,
4484 cli_credentials_init_anon(tctx),
4485 tctx->ev, tctx->lp_ctx);
4486 torture_assert_ntstatus_ok(tctx, status, "dcerpc_pipe_connect_b");
4488 ok = check_pw_with_ServerAuthenticate3(p1, tctx,
4489 NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES,
4490 server_name,
4491 incoming_creds, &creds);
4492 torture_assert_int_equal(tctx, ok, expected_result,
4493 "check_pw_with_ServerAuthenticate3");
4494 if (expected_result == true) {
4495 ok = test_SetupCredentialsPipe(p1, tctx, incoming_creds, creds,
4496 DCERPC_SIGN | DCERPC_SEAL, &p2);
4497 torture_assert_int_equal(tctx, ok, true,
4498 "test_SetupCredentialsPipe");
4500 TALLOC_FREE(p1);
4502 if (trusted->trust_type != LSA_TRUST_TYPE_DOWNLEVEL) {
4503 #ifdef SAMBA4_USES_HEIMDAL
4504 ok = check_pw_with_krb5(tctx, incoming_creds, trusted);
4505 torture_assert_int_equal(tctx, ok, expected_result,
4506 "check_pw_with_krb5");
4507 #else
4508 torture_comment(tctx, "skipping check_pw_with_krb5 for MIT Kerberos build");
4509 #endif
4512 if (expected_result != true || next_password == NULL) {
4513 TALLOC_FREE(p2);
4514 return true;
4518 * netr_ServerPasswordSet2
4520 ok = encode_pw_buffer(samr_crypt_password.data,
4521 next_password, STR_UNICODE);
4522 torture_assert(tctx, ok, "encode_pw_buffer");
4524 if (next_version != 0) {
4525 struct NL_PASSWORD_VERSION version;
4526 uint32_t len = IVAL(samr_crypt_password.data, 512);
4527 uint32_t ofs = 512 - len;
4528 uint8_t *ptr;
4530 ofs -= 12;
4532 version.ReservedField = 0;
4533 version.PasswordVersionNumber = next_version;
4534 version.PasswordVersionPresent =
4535 NETLOGON_PASSWORD_VERSION_NUMBER_PRESENT;
4537 ptr = samr_crypt_password.data + ofs;
4538 SIVAL(ptr, 0, version.ReservedField);
4539 SIVAL(ptr, 4, version.PasswordVersionNumber);
4540 SIVAL(ptr, 8, version.PasswordVersionPresent);
4543 netlogon_creds_client_authenticator(creds, &req_auth);
4544 ZERO_STRUCT(rep_auth);
4546 dcerpc_binding_handle_auth_info(p2->binding_handle,
4547 &auth_type,
4548 &auth_level);
4549 status = netlogon_creds_encrypt_samr_CryptPassword(creds,
4550 &samr_crypt_password,
4551 auth_type,
4552 auth_level);
4553 torture_assert_ntstatus_ok(tctx, status, "encrypt_samr_CryptPassword");
4555 memcpy(netr_crypt_password.data,
4556 samr_crypt_password.data, 512);
4557 netr_crypt_password.length = IVAL(samr_crypt_password.data, 512);
4560 s.in.server_name = server_name;
4561 s.in.account_name = cli_credentials_get_username(incoming_creds);
4562 s.in.secure_channel_type = cli_credentials_get_secure_channel_type(incoming_creds);
4563 s.in.computer_name = cli_credentials_get_workstation(incoming_creds);
4564 s.in.credential = &req_auth;
4565 s.in.new_password = &netr_crypt_password;
4566 s.out.return_authenticator = &rep_auth;
4567 status = dcerpc_netr_ServerPasswordSet2_r(p2->binding_handle, tctx, &s);
4568 torture_assert_ntstatus_ok(tctx, status, "failed to set password");
4570 ok = netlogon_creds_client_check(creds, &rep_auth.cred);
4571 torture_assert(tctx, ok, "netlogon_creds_client_check");
4573 cli_credentials_set_kvno(incoming_creds, next_version);
4574 cli_credentials_set_password(incoming_creds, next_password, CRED_SPECIFIED);
4575 cli_credentials_set_old_password(incoming_creds, current_password, CRED_SPECIFIED);
4577 TALLOC_FREE(p2);
4578 status = dcerpc_pipe_connect_b(tctx, &p2, b2,
4579 &ndr_table_netlogon,
4580 cli_credentials_init_anon(tctx),
4581 tctx->ev, tctx->lp_ctx);
4582 torture_assert_ntstatus_ok(tctx, status, "dcerpc_pipe_connect_b");
4584 ok = check_pw_with_ServerAuthenticate3(p2, tctx,
4585 NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES,
4586 server_name,
4587 incoming_creds, &creds);
4588 torture_assert(tctx, ok, "check_pw_with_ServerAuthenticate3 with changed password");
4590 if (trusted->trust_type != LSA_TRUST_TYPE_DOWNLEVEL) {
4591 #if SAMBA4_USES_HEIMDAL
4592 ok = check_pw_with_krb5(tctx, incoming_creds, trusted);
4593 torture_assert(tctx, ok, "check_pw_with_krb5 with changed password");
4594 #else
4595 torture_comment(tctx, "skipping check_pw_with_krb5 for MIT Kerberos build");
4596 #endif
4599 TALLOC_FREE(p2);
4600 return true;
4603 enum ex_call {
4604 CREATE_TRUSTED_DOMAIN_EX1 = 1,
4605 CREATE_TRUSTED_DOMAIN_EX2 = 2,
4606 CREATE_TRUSTED_DOMAIN_EX3 = 3,
4609 static bool test_CreateTrustedDomainEx_common(struct dcerpc_pipe *p,
4610 struct torture_context *tctx,
4611 struct policy_handle *handle,
4612 uint32_t num_trusts,
4613 enum ex_call ex_call)
4615 NTSTATUS status;
4616 bool ret = true;
4617 struct lsa_QueryInfoPolicy2 p2;
4618 union lsa_PolicyInformation *our_info = NULL;
4619 struct lsa_CreateTrustedDomainEx r;
4620 struct lsa_CreateTrustedDomainEx2 r2;
4621 struct lsa_CreateTrustedDomainEx3 r3 = {
4622 .in = {
4623 .access_mask = 0,
4626 struct lsa_TrustDomainInfoInfoEx trustinfo;
4627 struct lsa_TrustDomainInfoAuthInfoInternal *authinfo_internal = NULL;
4628 struct lsa_TrustDomainInfoAuthInfoInternalAES
4629 *authinfo_internal_aes = NULL;
4630 struct lsa_TrustDomainInfoAuthInfo *authinfo = NULL;
4631 struct dom_sid **domsid;
4632 struct policy_handle *trustdom_handle;
4633 struct lsa_QueryTrustedDomainInfo q;
4634 union lsa_TrustedDomainInfo *info = NULL;
4635 DATA_BLOB session_key;
4636 int i;
4637 struct dcerpc_binding_handle *b = p->binding_handle;
4638 const char *id = "0";
4639 const char *incoming_v00 = TRUSTPW "InV00";
4640 const char *incoming_v0 = TRUSTPW "InV0";
4641 const char *incoming_v1 = TRUSTPW "InV1";
4642 const char *incoming_v2 = TRUSTPW "InV2";
4643 const char *incoming_v40 = TRUSTPW "InV40";
4644 const char *outgoing_v00 = TRUSTPW "OutV00";
4645 const char *outgoing_v0 = TRUSTPW "OutV0";
4647 switch (ex_call) {
4648 case CREATE_TRUSTED_DOMAIN_EX3:
4649 torture_comment(
4650 tctx,
4651 "\nTesting CreateTrustedDomainEx3 for %d domains\n",
4652 num_trusts
4654 id = "4";
4655 break;
4656 case CREATE_TRUSTED_DOMAIN_EX2:
4657 torture_comment(
4658 tctx,
4659 "\nTesting CreateTrustedDomainEx2 for %d domains\n",
4660 num_trusts
4662 id = "3";
4663 break;
4664 case CREATE_TRUSTED_DOMAIN_EX1:
4665 torture_comment(
4666 tctx,
4667 "\nTesting CreateTrustedDomainEx for %d domains\n",
4668 num_trusts
4670 id = "2";
4671 break;
4674 domsid = talloc_array(tctx, struct dom_sid *, num_trusts);
4675 trustdom_handle = talloc_array(tctx, struct policy_handle, num_trusts);
4677 status = dcerpc_binding_handle_transport_session_key(b, tctx, &session_key);
4678 if (!NT_STATUS_IS_OK(status)) {
4679 torture_comment(tctx, "transport_session_key failed - %s\n", nt_errstr(status));
4680 return false;
4683 ZERO_STRUCT(p2);
4684 p2.in.handle = handle;
4685 p2.in.level = LSA_POLICY_INFO_DNS;
4686 p2.out.info = &our_info;
4688 torture_assert_ntstatus_ok(tctx,
4689 dcerpc_lsa_QueryInfoPolicy2_r(b, tctx, &p2),
4690 "lsa_QueryInfoPolicy2 failed");
4691 torture_assert_ntstatus_ok(tctx, p2.out.result,
4692 "lsa_QueryInfoPolicy2 failed");
4693 torture_assert(tctx, our_info != NULL, "lsa_QueryInfoPolicy2 our_info");
4695 for (i=0; i< num_trusts; i++) {
4696 char *trust_name = talloc_asprintf(tctx, "TORTURE%s%02d", id, i);
4697 char *trust_name_dns = talloc_asprintf(tctx, "torturedom%s%02d.samba._none_.example.com", id, i);
4698 char *trust_sid = talloc_asprintf(tctx, "S-1-5-21-97398-379795-%s%02d", id, i);
4699 bool ok;
4701 domsid[i] = dom_sid_parse_talloc(tctx, trust_sid);
4703 trustinfo.sid = domsid[i];
4704 trustinfo.netbios_name.string = trust_name;
4705 trustinfo.domain_name.string = trust_name_dns;
4707 /* Create inbound, some outbound, and some
4708 * bi-directional trusts in a repeating pattern based
4709 * on i */
4711 /* 1 == inbound, 2 == outbound, 3 == both */
4712 trustinfo.trust_direction = (i % 3) + 1;
4714 /* Try different trust types too */
4716 /* 1 == downlevel (NT4), 2 == uplevel (ADS), 3 == MIT (kerberos but not AD) */
4717 trustinfo.trust_type = (((i / 3) + 1) % 3) + 1;
4719 trustinfo.trust_attributes = LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION;
4721 switch(ex_call) {
4722 case CREATE_TRUSTED_DOMAIN_EX3:
4723 ok = rpc_lsa_encrypt_trustdom_info_aes(
4724 tctx,
4725 incoming_v00,
4726 incoming_v0,
4727 outgoing_v00,
4728 outgoing_v0,
4729 session_key,
4730 &authinfo_internal_aes);
4731 if (!ok) {
4732 torture_comment(tctx,
4733 "gen_authinfo_internal failed");
4734 ret = false;
4737 r3.in.policy_handle = handle;
4738 r3.in.info = &trustinfo;
4739 r3.in.auth_info_internal = authinfo_internal_aes;
4740 r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4741 r3.out.trustdom_handle = &trustdom_handle[i];
4743 torture_assert_ntstatus_ok(
4744 tctx,
4745 dcerpc_lsa_CreateTrustedDomainEx3_r(b,
4746 tctx,
4747 &r3),
4748 "CreateTrustedDomainEx3 failed");
4750 status = r3.out.result;
4751 break;
4752 case CREATE_TRUSTED_DOMAIN_EX2:
4753 ok = rpc_lsa_encrypt_trustdom_info(tctx,
4754 incoming_v00,
4755 incoming_v0,
4756 outgoing_v00,
4757 outgoing_v0,
4758 session_key,
4759 &authinfo_internal);
4760 if (!ok) {
4761 torture_comment(
4762 tctx,
4763 "rpc_lsa_encrypt_trustdom_info failed");
4764 ret = false;
4767 r2.in.policy_handle = handle;
4768 r2.in.info = &trustinfo;
4769 r2.in.auth_info_internal = authinfo_internal;
4770 r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4771 r2.out.trustdom_handle = &trustdom_handle[i];
4773 torture_assert_ntstatus_ok(tctx,
4774 dcerpc_lsa_CreateTrustedDomainEx2_r(b, tctx, &r2),
4775 "CreateTrustedDomainEx2 failed");
4777 status = r2.out.result;
4778 break;
4779 case CREATE_TRUSTED_DOMAIN_EX1:
4780 ok = gen_authinfo(tctx,
4781 incoming_v00,
4782 incoming_v0,
4783 outgoing_v00,
4784 outgoing_v0,
4785 &authinfo);
4786 if (!ok) {
4787 torture_comment(tctx, "gen_authinfonfo failed");
4788 ret = false;
4791 r.in.policy_handle = handle;
4792 r.in.info = &trustinfo;
4793 r.in.auth_info = authinfo;
4794 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4795 r.out.trustdom_handle = &trustdom_handle[i];
4797 torture_assert_ntstatus_ok(tctx,
4798 dcerpc_lsa_CreateTrustedDomainEx_r(b, tctx, &r),
4799 "CreateTrustedDomainEx failed");
4801 status = r.out.result;
4802 break;
4805 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
4806 test_DeleteTrustedDomain(b, tctx, handle, trustinfo.netbios_name);
4808 switch (ex_call) {
4809 case CREATE_TRUSTED_DOMAIN_EX3:
4810 torture_assert_ntstatus_ok(
4811 tctx,
4812 dcerpc_lsa_CreateTrustedDomainEx3_r(
4813 b, tctx, &r3),
4814 "CreateTrustedDomainEx3 failed");
4815 status = r3.out.result;
4816 break;
4817 case CREATE_TRUSTED_DOMAIN_EX2:
4818 torture_assert_ntstatus_ok(
4819 tctx,
4820 dcerpc_lsa_CreateTrustedDomainEx2_r(
4821 b, tctx, &r2),
4822 "CreateTrustedDomainEx2 failed");
4823 status = r2.out.result;
4824 break;
4825 case CREATE_TRUSTED_DOMAIN_EX1:
4826 torture_assert_ntstatus_ok(
4827 tctx,
4828 dcerpc_lsa_CreateTrustedDomainEx_r(b,
4829 tctx,
4830 &r),
4831 "CreateTrustedDomainEx failed");
4832 status = r.out.result;
4833 break;
4836 if (!NT_STATUS_IS_OK(status)) {
4837 torture_comment(tctx,
4838 "CreateTrustedDomainEx(2|3) failed "
4839 "with status: %s\n",
4840 nt_errstr(status));
4841 ret = false;
4842 } else { /* For outbound and MIT trusts there is no trust account */
4843 if (trustinfo.trust_direction != 2 &&
4844 trustinfo.trust_type != 3) {
4846 if (torture_setting_bool(tctx, "samba3", false)) {
4847 torture_comment(tctx, "skipping trusted domain auth tests against samba3\n");
4848 } else if (ex_call == CREATE_TRUSTED_DOMAIN_EX1 &&
4849 torture_setting_bool(tctx, "samba4", false)) {
4850 torture_comment(tctx, "skipping CreateTrustedDomainEx trusted domain auth tests against samba4\n");
4852 } else {
4853 ok = check_dom_trust_pw(p, tctx,
4854 our_info->dns.name.string,
4855 our_info->dns.dns_domain.string,
4856 SEC_CHAN_DOMAIN,
4857 &trustinfo,
4858 NULL,
4859 "x" TRUSTPW "x", 0,
4860 NULL, 0,
4861 false);
4862 if (!ok) {
4863 torture_comment(tctx, "Password check passed unexpectedly\n");
4864 ret = false;
4866 ok = check_dom_trust_pw(p, tctx,
4867 our_info->dns.name.string,
4868 our_info->dns.dns_domain.string,
4869 SEC_CHAN_DOMAIN,
4870 &trustinfo,
4871 incoming_v00,
4872 incoming_v0, 0,
4873 incoming_v1, 1,
4874 true);
4875 if (!ok) {
4876 torture_comment(tctx, "Password check failed (SEC_CHAN_DOMAIN)\n");
4877 ret = false;
4879 ok = check_dom_trust_pw(p, tctx,
4880 our_info->dns.name.string,
4881 our_info->dns.dns_domain.string,
4882 SEC_CHAN_DNS_DOMAIN,
4883 &trustinfo,
4884 incoming_v0,
4885 incoming_v1, 1,
4886 incoming_v2, 2,
4887 true);
4888 if (!ok) {
4889 torture_comment(tctx, "Password check failed v2 (SEC_CHAN_DNS_DOMAIN)\n");
4890 ret = false;
4892 ok = check_dom_trust_pw(p, tctx,
4893 our_info->dns.name.string,
4894 our_info->dns.dns_domain.string,
4895 SEC_CHAN_DNS_DOMAIN,
4896 &trustinfo,
4897 incoming_v1,
4898 incoming_v2, 2,
4899 incoming_v40, 40,
4900 true);
4901 if (!ok) {
4902 torture_comment(tctx, "Password check failed v4 (SEC_CHAN_DNS_DOMAIN)\n");
4903 ret = false;
4908 q.in.trustdom_handle = &trustdom_handle[i];
4909 q.in.level = LSA_TRUSTED_DOMAIN_INFO_INFO_EX;
4910 q.out.info = &info;
4911 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryTrustedDomainInfo_r(b, tctx, &q),
4912 "QueryTrustedDomainInfo failed");
4913 if (!NT_STATUS_IS_OK(q.out.result)) {
4914 torture_comment(tctx, "QueryTrustedDomainInfo level 1 failed - %s\n", nt_errstr(q.out.result));
4915 ret = false;
4916 } else if (!q.out.info) {
4917 torture_comment(tctx, "QueryTrustedDomainInfo level 1 failed to return an info pointer\n");
4918 ret = false;
4919 } else {
4920 if (strcmp(info->info_ex.domain_name.string, trustinfo.domain_name.string) != 0) {
4921 torture_comment(tctx, "QueryTrustedDomainInfo returned inconsistent long name: %s != %s\n",
4922 info->info_ex.domain_name.string, trustinfo.domain_name.string);
4923 ret = false;
4925 if (strcmp(info->info_ex.netbios_name.string, trustinfo.netbios_name.string) != 0) {
4926 torture_comment(tctx, "QueryTrustedDomainInfo returned inconsistent short name: %s != %s\n",
4927 info->info_ex.netbios_name.string, trustinfo.netbios_name.string);
4928 ret = false;
4930 if (info->info_ex.trust_type != trustinfo.trust_type) {
4931 torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n",
4932 trust_name, info->info_ex.trust_type, trustinfo.trust_type);
4933 ret = false;
4935 if (info->info_ex.trust_attributes != LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION) {
4936 torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n",
4937 trust_name, info->info_ex.trust_attributes, LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION);
4938 ret = false;
4940 if (info->info_ex.trust_direction != trustinfo.trust_direction) {
4941 torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n",
4942 trust_name, info->info_ex.trust_direction, trustinfo.trust_direction);
4943 ret = false;
4949 /* now that we have some domains to look over, we can test the enum calls */
4950 if (!test_EnumTrustDom(b, tctx, handle)) {
4951 torture_comment(tctx, "test_EnumTrustDom failed\n");
4952 ret = false;
4955 if (!test_EnumTrustDomEx(b, tctx, handle)) {
4956 torture_comment(tctx, "test_EnumTrustDomEx failed\n");
4957 ret = false;
4960 for (i=0; i<num_trusts; i++) {
4961 if (!test_DeleteTrustedDomainBySid(b, tctx, handle, domsid[i])) {
4962 torture_comment(tctx, "test_DeleteTrustedDomainBySid failed\n");
4963 ret = false;
4967 return ret;
4970 static bool test_CreateTrustedDomainEx3(struct dcerpc_pipe *p,
4971 struct torture_context *tctx,
4972 struct policy_handle *handle,
4973 uint32_t num_trusts)
4975 return test_CreateTrustedDomainEx_common(
4977 tctx,
4978 handle,
4979 num_trusts,
4980 CREATE_TRUSTED_DOMAIN_EX3
4984 static bool test_CreateTrustedDomainEx2(struct dcerpc_pipe *p,
4985 struct torture_context *tctx,
4986 struct policy_handle *handle,
4987 uint32_t num_trusts)
4989 return test_CreateTrustedDomainEx_common(
4991 tctx,
4992 handle,
4993 num_trusts,
4994 CREATE_TRUSTED_DOMAIN_EX2
4998 static bool test_CreateTrustedDomainEx(struct dcerpc_pipe *p,
4999 struct torture_context *tctx,
5000 struct policy_handle *handle,
5001 uint32_t num_trusts)
5003 return test_CreateTrustedDomainEx_common(
5005 tctx,
5006 handle,
5007 num_trusts,
5008 CREATE_TRUSTED_DOMAIN_EX1
5012 static bool test_QueryDomainInfoPolicy(struct dcerpc_binding_handle *b,
5013 struct torture_context *tctx,
5014 struct policy_handle *handle)
5016 struct lsa_QueryDomainInformationPolicy r;
5017 union lsa_DomainInformationPolicy *info = NULL;
5018 int i;
5019 bool ret = true;
5021 if (torture_setting_bool(tctx, "samba3", false)) {
5022 torture_skip(tctx, "skipping QueryDomainInformationPolicy test\n");
5025 torture_comment(tctx, "\nTesting QueryDomainInformationPolicy\n");
5027 for (i=2;i<4;i++) {
5028 r.in.handle = handle;
5029 r.in.level = i;
5030 r.out.info = &info;
5032 torture_comment(tctx, "\nTrying QueryDomainInformationPolicy level %d\n", i);
5034 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryDomainInformationPolicy_r(b, tctx, &r),
5035 "QueryDomainInformationPolicy failed");
5037 /* If the server does not support EFS, then this is the correct return */
5038 if (i == LSA_DOMAIN_INFO_POLICY_EFS && NT_STATUS_EQUAL(r.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
5039 continue;
5040 } else if (!NT_STATUS_IS_OK(r.out.result)) {
5041 torture_comment(tctx, "QueryDomainInformationPolicy failed - %s\n", nt_errstr(r.out.result));
5042 ret = false;
5043 continue;
5047 return ret;
5051 static bool test_QueryInfoPolicyCalls( bool version2,
5052 struct dcerpc_binding_handle *b,
5053 struct torture_context *tctx,
5054 struct policy_handle *handle)
5056 struct lsa_QueryInfoPolicy r;
5057 union lsa_PolicyInformation *info = NULL;
5058 int i;
5059 bool ret = true;
5060 const char *call = talloc_asprintf(tctx, "QueryInfoPolicy%s", version2 ? "2":"");
5062 torture_comment(tctx, "\nTesting %s\n", call);
5064 if (version2 && torture_setting_bool(tctx, "samba3", false)) {
5065 torture_skip(tctx, "skipping QueryInfoPolicy2 tests\n");
5068 for (i=1;i<=14;i++) {
5069 r.in.handle = handle;
5070 r.in.level = i;
5071 r.out.info = &info;
5073 torture_comment(tctx, "\nTrying %s level %d\n", call, i);
5075 if (version2)
5076 /* We can perform the cast, because both types are
5077 structurally equal */
5078 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryInfoPolicy2_r(b, tctx,
5079 (struct lsa_QueryInfoPolicy2*) &r),
5080 "QueryInfoPolicy2 failed");
5081 else
5082 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QueryInfoPolicy_r(b, tctx, &r),
5083 "QueryInfoPolicy2 failed");
5085 switch (i) {
5086 case LSA_POLICY_INFO_MOD:
5087 case LSA_POLICY_INFO_AUDIT_FULL_SET:
5088 case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
5089 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_PARAMETER)) {
5090 torture_comment(tctx, "Server should have failed level %u: %s\n", i, nt_errstr(r.out.result));
5091 ret = false;
5093 break;
5094 case LSA_POLICY_INFO_DOMAIN:
5095 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
5096 case LSA_POLICY_INFO_REPLICA:
5097 case LSA_POLICY_INFO_QUOTA:
5098 case LSA_POLICY_INFO_ROLE:
5099 case LSA_POLICY_INFO_AUDIT_LOG:
5100 case LSA_POLICY_INFO_AUDIT_EVENTS:
5101 case LSA_POLICY_INFO_PD:
5102 if (!NT_STATUS_IS_OK(r.out.result)) {
5103 torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
5104 ret = false;
5106 break;
5107 case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
5108 case LSA_POLICY_INFO_DNS_INT:
5109 case LSA_POLICY_INFO_DNS:
5110 if (torture_setting_bool(tctx, "samba3", false)) {
5111 /* Other levels not implemented yet */
5112 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_INFO_CLASS)) {
5113 torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
5114 ret = false;
5116 } else if (!NT_STATUS_IS_OK(r.out.result)) {
5117 torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
5118 ret = false;
5120 break;
5121 default:
5122 if (torture_setting_bool(tctx, "samba4", false)) {
5123 /* Other levels not implemented yet */
5124 if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_INFO_CLASS)) {
5125 torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
5126 ret = false;
5128 } else if (!NT_STATUS_IS_OK(r.out.result)) {
5129 torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(r.out.result));
5130 ret = false;
5132 break;
5135 if (NT_STATUS_IS_OK(r.out.result) && (i == LSA_POLICY_INFO_DNS
5136 || i == LSA_POLICY_INFO_DNS_INT)) {
5137 /* Let's look up some of these names */
5139 struct lsa_TransNameArray tnames, dnames;
5140 tnames.count = 14;
5141 tnames.names = talloc_zero_array(tctx, struct lsa_TranslatedName, tnames.count);
5142 tnames.names[0].name.string = info->dns.name.string;
5143 tnames.names[0].sid_type = SID_NAME_DOMAIN;
5144 tnames.names[1].name.string = info->dns.dns_domain.string;
5145 tnames.names[1].sid_type = SID_NAME_DOMAIN;
5146 tnames.names[2].name.string = talloc_asprintf(tctx, "%s\\", info->dns.name.string);
5147 tnames.names[2].sid_type = SID_NAME_DOMAIN;
5148 tnames.names[3].name.string = talloc_asprintf(tctx, "%s\\", info->dns.dns_domain.string);
5149 tnames.names[3].sid_type = SID_NAME_DOMAIN;
5150 tnames.names[4].name.string = talloc_asprintf(tctx, "%s\\guest", info->dns.name.string);
5151 tnames.names[4].sid_type = SID_NAME_USER;
5152 tnames.names[5].name.string = talloc_asprintf(tctx, "%s\\krbtgt", info->dns.name.string);
5153 tnames.names[5].sid_type = SID_NAME_USER;
5154 tnames.names[6].name.string = talloc_asprintf(tctx, "%s\\guest", info->dns.dns_domain.string);
5155 tnames.names[6].sid_type = SID_NAME_USER;
5156 tnames.names[7].name.string = talloc_asprintf(tctx, "%s\\krbtgt", info->dns.dns_domain.string);
5157 tnames.names[7].sid_type = SID_NAME_USER;
5158 tnames.names[8].name.string = talloc_asprintf(tctx, "krbtgt@%s", info->dns.name.string);
5159 tnames.names[8].sid_type = SID_NAME_USER;
5160 tnames.names[9].name.string = talloc_asprintf(tctx, "krbtgt@%s", info->dns.dns_domain.string);
5161 tnames.names[9].sid_type = SID_NAME_USER;
5162 tnames.names[10].name.string = talloc_asprintf(tctx, "%s\\"TEST_MACHINENAME "$", info->dns.name.string);
5163 tnames.names[10].sid_type = SID_NAME_USER;
5164 tnames.names[11].name.string = talloc_asprintf(tctx, "%s\\"TEST_MACHINENAME "$", info->dns.dns_domain.string);
5165 tnames.names[11].sid_type = SID_NAME_USER;
5166 tnames.names[12].name.string = talloc_asprintf(tctx, TEST_MACHINENAME "$@%s", info->dns.name.string);
5167 tnames.names[12].sid_type = SID_NAME_USER;
5168 tnames.names[13].name.string = talloc_asprintf(tctx, TEST_MACHINENAME "$@%s", info->dns.dns_domain.string);
5169 tnames.names[13].sid_type = SID_NAME_USER;
5170 ret &= test_LookupNames(b, tctx, handle, LSA_LOOKUP_NAMES_ALL, &tnames);
5172 /* Try to use in-forest search for the test machine */
5173 dnames.count = 1;
5174 dnames.names = talloc_zero_array(tctx, struct lsa_TranslatedName, dnames.count);
5175 dnames.names[0].name.string = talloc_asprintf(tctx, "%s\\"TEST_MACHINENAME "$", info->dns.name.string);
5176 dnames.names[0].sid_type = SID_NAME_USER;
5177 ret &= test_LookupNames(b, tctx, handle, LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2, &dnames);
5181 return ret;
5184 static bool test_QueryInfoPolicy(struct dcerpc_binding_handle *b,
5185 struct torture_context *tctx,
5186 struct policy_handle *handle)
5188 return test_QueryInfoPolicyCalls(false, b, tctx, handle);
5191 static bool test_QueryInfoPolicy2(struct dcerpc_binding_handle *b,
5192 struct torture_context *tctx,
5193 struct policy_handle *handle)
5195 return test_QueryInfoPolicyCalls(true, b, tctx, handle);
5198 static bool test_GetUserName(struct dcerpc_binding_handle *b,
5199 struct torture_context *tctx)
5201 struct lsa_GetUserName r;
5202 struct lsa_String *authority_name_p = NULL;
5203 struct lsa_String *account_name_p = NULL;
5205 torture_comment(tctx, "\nTesting GetUserName\n");
5207 r.in.system_name = "\\";
5208 r.in.account_name = &account_name_p;
5209 r.in.authority_name = NULL;
5210 r.out.account_name = &account_name_p;
5212 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetUserName_r(b, tctx, &r),
5213 "GetUserName failed");
5214 torture_assert_ntstatus_ok(tctx, r.out.result,
5215 "GetUserName result failed");
5216 torture_assert_not_null(tctx, r.out.account_name, "r.out.account_name");
5217 torture_assert_not_null(tctx, *r.out.account_name, "*r.out.account_name");
5218 torture_assert(tctx, r.out.authority_name == NULL, "r.out.authority_name");
5220 account_name_p = NULL;
5221 r.in.account_name = &account_name_p;
5222 r.in.authority_name = &authority_name_p;
5223 r.out.account_name = &account_name_p;
5225 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_GetUserName_r(b, tctx, &r),
5226 "GetUserName failed");
5227 torture_assert_ntstatus_ok(tctx, r.out.result,
5228 "GetUserName result failed");
5229 torture_assert_not_null(tctx, r.out.account_name, "r.out.account_name");
5230 torture_assert_not_null(tctx, *r.out.account_name, "*r.out.account_name");
5231 torture_assert_not_null(tctx, r.out.authority_name, "r.out.authority_name");
5232 torture_assert_not_null(tctx, *r.out.authority_name, "*r.out.authority_name");
5234 torture_comment(tctx,
5235 "Account Name: %s, Authority Name: %s\n",
5236 (*r.out.account_name)->string,
5237 (*r.out.authority_name)->string);
5239 return true;
5242 static bool test_GetUserName_fail(struct dcerpc_binding_handle *b,
5243 struct torture_context *tctx)
5245 struct lsa_GetUserName r;
5246 struct lsa_String *account_name_p = NULL;
5247 NTSTATUS status;
5249 torture_comment(tctx, "\nTesting GetUserName_fail\n");
5251 r.in.system_name = "\\";
5252 r.in.account_name = &account_name_p;
5253 r.in.authority_name = NULL;
5254 r.out.account_name = &account_name_p;
5256 status = dcerpc_lsa_GetUserName_r(b, tctx, &r);
5257 if (!NT_STATUS_IS_OK(status)) {
5258 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5259 torture_comment(tctx,
5260 "GetUserName correctly returned with "
5261 "status: %s\n",
5262 nt_errstr(status));
5263 return true;
5266 torture_assert_ntstatus_equal(tctx,
5267 status,
5268 NT_STATUS_ACCESS_DENIED,
5269 "GetUserName return value should "
5270 "be ACCESS_DENIED");
5271 return true;
5274 if (!NT_STATUS_IS_OK(r.out.result)) {
5275 if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_ACCESS_DENIED) ||
5276 NT_STATUS_EQUAL(r.out.result, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
5277 torture_comment(tctx,
5278 "GetUserName correctly returned with "
5279 "result: %s\n",
5280 nt_errstr(r.out.result));
5281 return true;
5285 torture_assert_ntstatus_equal(tctx,
5286 r.out.result,
5287 NT_STATUS_OK,
5288 "GetUserName return value should be "
5289 "ACCESS_DENIED");
5291 return false;
5294 bool test_lsa_Close(struct dcerpc_binding_handle *b,
5295 struct torture_context *tctx,
5296 struct policy_handle *handle)
5298 struct lsa_Close r;
5299 struct policy_handle handle2;
5301 torture_comment(tctx, "\nTesting Close\n");
5303 r.in.handle = handle;
5304 r.out.handle = &handle2;
5306 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_Close_r(b, tctx, &r),
5307 "Close failed");
5308 torture_assert_ntstatus_ok(tctx, r.out.result,
5309 "Close failed");
5311 torture_assert_ntstatus_equal(tctx, dcerpc_lsa_Close_r(b, tctx, &r),
5312 NT_STATUS_RPC_SS_CONTEXT_MISMATCH, "Close should failed");
5314 torture_comment(tctx, "\n");
5316 return true;
5319 bool torture_rpc_lsa(struct torture_context *tctx)
5321 NTSTATUS status;
5322 struct dcerpc_pipe *p;
5323 bool ret = true;
5324 struct policy_handle *handle = NULL;
5325 struct test_join *join = NULL;
5326 struct cli_credentials *machine_creds;
5327 struct dcerpc_binding_handle *b;
5328 enum dcerpc_transport_t transport;
5330 status = torture_rpc_connection(tctx, &p, &ndr_table_lsarpc);
5331 torture_assert_ntstatus_ok(tctx, status, "Error connecting to server");
5333 b = p->binding_handle;
5334 transport = dcerpc_binding_handle_get_transport(b);
5336 /* Test lsaLookupSids3 and lsaLookupNames4 over tcpip */
5337 if (transport == NCACN_IP_TCP) {
5338 if (!test_OpenPolicy_fail(b, tctx)) {
5339 ret = false;
5342 if (!test_OpenPolicy2_fail(b, tctx)) {
5343 ret = false;
5346 if (!test_OpenPolicy3_fail(b, tctx)) {
5347 ret = false;
5350 if (!test_many_LookupSids(p, tctx, handle, LSA_LOOKUP_NAMES_ALL)) {
5351 ret = false;
5354 return ret;
5357 if (!test_OpenPolicy(b, tctx)) {
5358 ret = false;
5361 if (!test_lsa_OpenPolicy2(b, tctx, &handle)) {
5362 ret = false;
5365 if (!test_lsa_OpenPolicy3(b, tctx, &handle)) {
5366 ret = false;
5369 if (handle) {
5370 join = torture_join_domain(tctx, TEST_MACHINENAME, ACB_WSTRUST, &machine_creds);
5371 if (!join) {
5372 ret = false;
5375 if (!test_LookupSids_async(b, tctx, handle, LSA_LOOKUP_NAMES_ALL)) {
5376 ret = false;
5379 if (!test_QueryDomainInfoPolicy(b, tctx, handle)) {
5380 ret = false;
5383 if (!test_CreateSecret(p, tctx, handle)) {
5384 ret = false;
5387 if (!test_QueryInfoPolicy(b, tctx, handle)) {
5388 ret = false;
5391 if (!test_QueryInfoPolicy2(b, tctx, handle)) {
5392 ret = false;
5395 if (!test_Delete(b, tctx, handle)) {
5396 ret = false;
5399 if (!test_many_LookupSids(p, tctx, handle, LSA_LOOKUP_NAMES_ALL)) {
5400 ret = false;
5403 if (!test_lsa_Close(b, tctx, handle)) {
5404 ret = false;
5407 torture_leave_domain(tctx, join);
5409 } else {
5410 if (!test_many_LookupSids(p, tctx, handle, LSA_LOOKUP_NAMES_ALL)) {
5411 ret = false;
5415 if (!test_GetUserName(b, tctx)) {
5416 ret = false;
5419 return ret;
5422 bool torture_rpc_lsa_get_user(struct torture_context *tctx)
5424 NTSTATUS status;
5425 struct dcerpc_pipe *p;
5426 bool ret = true;
5427 struct dcerpc_binding_handle *b;
5428 enum dcerpc_transport_t transport;
5430 status = torture_rpc_connection(tctx, &p, &ndr_table_lsarpc);
5431 torture_assert_ntstatus_ok(tctx, status, "Error connecting to server");
5433 b = p->binding_handle;
5434 transport = dcerpc_binding_handle_get_transport(b);
5436 if (transport == NCACN_IP_TCP) {
5437 if (!test_GetUserName_fail(b, tctx)) {
5438 ret = false;
5440 return ret;
5443 if (!test_GetUserName(b, tctx)) {
5444 ret = false;
5447 return ret;
5450 static bool testcase_LookupNames(struct torture_context *tctx,
5451 struct dcerpc_pipe *p)
5453 bool ret = true;
5454 struct policy_handle *handle;
5455 struct lsa_TransNameArray tnames;
5456 struct lsa_TransNameArray2 tnames2;
5457 struct dcerpc_binding_handle *b = p->binding_handle;
5458 enum dcerpc_transport_t transport = dcerpc_binding_handle_get_transport(b);
5460 if (transport != NCACN_NP && transport != NCALRPC) {
5461 torture_comment(tctx, "testcase_LookupNames is only available "
5462 "over NCACN_NP or NCALRPC");
5463 return true;
5466 if (!test_OpenPolicy(b, tctx)) {
5467 ret = false;
5470 if (!test_lsa_OpenPolicy2(b, tctx, &handle)) {
5471 ret = false;
5474 if (!handle) {
5475 ret = false;
5478 tnames.count = 1;
5479 tnames.names = talloc_array(tctx, struct lsa_TranslatedName, tnames.count);
5480 ZERO_STRUCT(tnames.names[0]);
5481 tnames.names[0].name.string = "BUILTIN";
5482 tnames.names[0].sid_type = SID_NAME_DOMAIN;
5484 if (!test_LookupNames(b, tctx, handle, LSA_LOOKUP_NAMES_ALL, &tnames)) {
5485 ret = false;
5488 tnames2.count = 1;
5489 tnames2.names = talloc_array(tctx, struct lsa_TranslatedName2, tnames2.count);
5490 ZERO_STRUCT(tnames2.names[0]);
5491 tnames2.names[0].name.string = "BUILTIN";
5492 tnames2.names[0].sid_type = SID_NAME_DOMAIN;
5494 if (!test_LookupNames2(b, tctx, handle, LSA_LOOKUP_NAMES_ALL, &tnames2, true)) {
5495 ret = false;
5498 if (!test_LookupNames3(b, tctx, handle, LSA_LOOKUP_NAMES_ALL, &tnames2, true)) {
5499 ret = false;
5502 if (!test_LookupNames_wellknown(b, tctx, handle, LSA_LOOKUP_NAMES_ALL)) {
5503 ret = false;
5506 if (!test_LookupNames_NULL(b, tctx, handle, LSA_LOOKUP_NAMES_ALL)) {
5507 ret = false;
5510 if (!test_LookupNames_bogus(b, tctx, handle, LSA_LOOKUP_NAMES_ALL)) {
5511 ret = false;
5514 if (!test_lsa_Close(b, tctx, handle)) {
5515 ret = false;
5518 return ret;
5521 struct torture_suite *torture_rpc_lsa_lookup_names(TALLOC_CTX *mem_ctx)
5523 struct torture_suite *suite;
5524 struct torture_rpc_tcase *tcase;
5526 suite = torture_suite_create(mem_ctx, "lsa.lookupnames");
5528 tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa",
5529 &ndr_table_lsarpc);
5530 torture_rpc_tcase_add_test(tcase, "LookupNames",
5531 testcase_LookupNames);
5533 return suite;
5536 struct lsa_trustdom_state {
5537 uint32_t num_trusts;
5540 static bool testcase_TrustedDomains(struct torture_context *tctx,
5541 struct dcerpc_pipe *p,
5542 void *data)
5544 bool ret = true;
5545 struct policy_handle *handle;
5546 struct lsa_trustdom_state *state =
5547 talloc_get_type_abort(data, struct lsa_trustdom_state);
5548 struct dcerpc_binding_handle *b = p->binding_handle;
5549 enum dcerpc_transport_t transport = dcerpc_binding_handle_get_transport(b);
5551 if (transport != NCACN_NP && transport != NCALRPC) {
5552 torture_comment(tctx, "testcase_TrustedDomains is only available "
5553 "over NCACN_NP or NCALRPC");
5554 return true;
5557 torture_comment(tctx, "Testing %d domains\n", state->num_trusts);
5559 if (!test_OpenPolicy(b, tctx)) {
5560 ret = false;
5563 if (!test_lsa_OpenPolicy2(b, tctx, &handle)) {
5564 ret = false;
5567 if (!test_lsa_OpenPolicy3(b, tctx, &handle)) {
5568 ret = false;
5571 if (!handle) {
5572 ret = false;
5575 if (!test_CreateTrustedDomain(b, tctx, handle, state->num_trusts)) {
5576 ret = false;
5579 if (!test_CreateTrustedDomainEx(p, tctx, handle, state->num_trusts)) {
5580 ret = false;
5583 if (!test_CreateTrustedDomainEx2(p, tctx, handle, state->num_trusts)) {
5584 ret = false;
5587 if (!test_CreateTrustedDomainEx3(p, tctx, handle, state->num_trusts)) {
5588 ret = false;
5591 if (!test_lsa_Close(b, tctx, handle)) {
5592 ret = false;
5595 return ret;
5598 struct torture_suite *torture_rpc_lsa_trusted_domains(TALLOC_CTX *mem_ctx)
5600 struct torture_suite *suite;
5601 struct torture_rpc_tcase *tcase;
5602 struct lsa_trustdom_state *state;
5604 state = talloc(mem_ctx, struct lsa_trustdom_state);
5606 state->num_trusts = 12;
5608 suite = torture_suite_create(mem_ctx, "lsa.trusted.domains");
5610 tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa",
5611 &ndr_table_lsarpc);
5612 torture_rpc_tcase_add_test_ex(tcase, "TrustedDomains",
5613 testcase_TrustedDomains,
5614 state);
5616 return suite;
5619 static bool testcase_Privileges(struct torture_context *tctx,
5620 struct dcerpc_pipe *p)
5622 struct policy_handle *handle;
5623 struct dcerpc_binding_handle *b = p->binding_handle;
5624 enum dcerpc_transport_t transport = dcerpc_binding_handle_get_transport(b);
5626 if (transport != NCACN_NP && transport != NCALRPC) {
5627 torture_skip(tctx, "testcase_Privileges is only available "
5628 "over NCACN_NP or NCALRPC");
5631 if (!test_OpenPolicy(b, tctx)) {
5632 return false;
5635 if (!test_lsa_OpenPolicy2(b, tctx, &handle)) {
5636 return false;
5639 if (!handle) {
5640 return false;
5643 if (!test_CreateAccount(b, tctx, handle)) {
5644 return false;
5647 if (!test_EnumAccounts(b, tctx, handle)) {
5648 return false;
5651 if (!test_EnumPrivs(b, tctx, handle)) {
5652 return false;
5655 if (!test_lsa_Close(b, tctx, handle)) {
5656 return false;
5659 return true;
5663 struct torture_suite *torture_rpc_lsa_privileges(TALLOC_CTX *mem_ctx)
5665 struct torture_suite *suite;
5666 struct torture_rpc_tcase *tcase;
5668 suite = torture_suite_create(mem_ctx, "lsa.privileges");
5670 tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa",
5671 &ndr_table_lsarpc);
5672 torture_rpc_tcase_add_test(tcase, "Privileges",
5673 testcase_Privileges);
5675 return suite;