2 Unix SMB/CIFS implementation.
3 test suite for forest trust
5 Copyright (C) Andrew Tridgell 2003
6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2005
7 Copyright (C) Sumit Bose <sbose@redhat.com> 2010
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "torture/torture.h"
25 #include "librpc/gen_ndr/ndr_lsa_c.h"
26 #include "librpc/gen_ndr/ndr_drsblobs.h"
27 #include "librpc/gen_ndr/ndr_netlogon_c.h"
28 #include "libcli/security/security.h"
29 #include "libcli/auth/credentials.h"
30 #include "libcli/auth/libcli_auth.h"
31 #include "torture/rpc/torture_rpc.h"
32 #include "param/param.h"
33 #include "source3/rpc_client/init_lsa.h"
35 #include <gnutls/gnutls.h>
36 #include <gnutls/crypto.h>
40 #define TEST_DOM "torturedom"
41 #define TEST_DOM_DNS "torturedom.samba.example.com"
42 #define TEST_DOM_SID "S-1-5-21-97398-379795-10000"
43 #define TEST_MACHINE_NAME "lsatestmach"
46 static bool test_get_policy_handle(struct torture_context
*tctx
,
47 struct dcerpc_pipe
*p
,
49 struct policy_handle
**handle
)
51 struct policy_handle
*h
= NULL
;
52 struct lsa_ObjectAttribute attr
= {
55 union lsa_revision_info in_rinfo
= {
58 .supported_features
= LSA_FEATURE_TDO_AUTH_INFO_AES_CIPHER
,
61 union lsa_revision_info out_rinfo
= {
64 uint32_t out_version
= 0;
65 struct lsa_OpenPolicy3 r
= {
69 .access_mask
= access_mask
,
71 .in_revision_info
= &in_rinfo
,
74 .out_version
= &out_version
,
75 .out_revision_info
= &out_rinfo
,
82 h
= talloc_zero(tctx
, struct policy_handle
);
83 torture_assert_not_null(tctx
, h
, "talloc_zero(tctx, struct policy_handle)");
86 status
= dcerpc_lsa_OpenPolicy3_r(p
->binding_handle
, tctx
, &r
);
87 torture_assert_ntstatus_ok(tctx
, status
, "OpenPolicy3 failed");
88 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "OpenPolicy3 failed");
90 torture_assert_int_equal(tctx
,
94 torture_assert_int_equal(tctx
,
95 out_rinfo
.info1
.revision
,
98 torture_assert_int_equal(tctx
,
99 out_rinfo
.info1
.supported_features
,
100 LSA_FEATURE_TDO_AUTH_INFO_AES_CIPHER
,
101 "Invalid supported feature set");
107 static bool test_set_forest_trust_info(struct dcerpc_pipe
*p
,
108 struct torture_context
*tctx
,
109 struct policy_handle
*handle
,
110 struct dom_sid
*domsid
,
111 const char *trust_name
,
112 const char *trust_name_dns
)
114 struct lsa_ForestTrustCollisionInfo
*collision_info
= NULL
;
115 struct lsa_ForestTrustInformation
*fti
= NULL
;
116 struct lsa_lsaRSetForestTrustInformation ft_info
= {
119 .highest_record_type
= 2,
122 .collision_info
= &collision_info
,
126 torture_comment(tctx
, "\nTesting lsaRSetForestTrustInformation\n");
128 ft_info
.in
.trusted_domain_name
= talloc_zero(tctx
, struct lsa_StringLarge
);
129 torture_assert_not_null(tctx
, ft_info
.in
.trusted_domain_name
, "No memory");
130 ft_info
.in
.trusted_domain_name
->string
= trust_name_dns
;
132 fti
= talloc_zero(tctx
, struct lsa_ForestTrustInformation
);
133 torture_assert_not_null(tctx
, fti
, "No memory");
135 fti
->entries
= talloc_array(tctx
, struct lsa_ForestTrustRecord
*, 2);
136 fti
->entries
[0] = talloc_zero(tctx
, struct lsa_ForestTrustRecord
);
137 fti
->entries
[0]->flags
= 0;
138 fti
->entries
[0]->type
= LSA_FOREST_TRUST_TOP_LEVEL_NAME
;
139 fti
->entries
[0]->time
= 0;
140 fti
->entries
[0]->forest_trust_data
.top_level_name
.string
= trust_name_dns
;
141 fti
->entries
[1] = talloc_zero(tctx
, struct lsa_ForestTrustRecord
);
142 fti
->entries
[1]->flags
= 0;
143 fti
->entries
[1]->type
= LSA_FOREST_TRUST_DOMAIN_INFO
;
144 fti
->entries
[1]->time
= 0;
145 fti
->entries
[1]->forest_trust_data
.domain_info
.domain_sid
= domsid
;
146 fti
->entries
[1]->forest_trust_data
.domain_info
.dns_domain_name
.string
=
149 ->forest_trust_data
.domain_info
.netbios_domain_name
150 .string
= trust_name
;
152 ft_info
.in
.forest_trust_info
= fti
;
154 torture_assert_ntstatus_ok(tctx
,
155 dcerpc_lsa_lsaRSetForestTrustInformation_r(
156 p
->binding_handle
, tctx
, &ft_info
),
157 "lsaRSetForestTrustInformation failed");
158 torture_assert_ntstatus_ok(tctx
,
160 "lsaRSetForestTrustInformation failed");
162 /* There should be no collisions */
163 torture_assert(tctx
, collision_info
== NULL
, "collision info returned");
168 static bool test_query_forest_trust_info(struct dcerpc_pipe
*p
,
169 struct torture_context
*tctx
,
170 struct policy_handle
*handle
,
171 const char *trust_name_dns
)
173 struct lsa_String trusted_domain_name
= {
176 struct lsa_ForestTrustInformation
*fti
= NULL
;
177 struct lsa_lsaRQueryForestTrustInformation r
= {
180 .highest_record_type
= 2,
181 .trusted_domain_name
= &trusted_domain_name
,
184 .forest_trust_info
= &fti
,
187 struct lsa_ForestTrustRecord
*rec
= NULL
;
189 init_lsa_String(&trusted_domain_name
, trust_name_dns
);
191 torture_comment(tctx
, "\nTesting lsaRQueryForestTrustInformation\n");
194 torture_assert_ntstatus_ok(tctx
,
195 dcerpc_lsa_lsaRQueryForestTrustInformation_r(
196 p
->binding_handle
, tctx
, &r
),
197 "lsaRQueryForestTrustInformation failed");
198 torture_assert_ntstatus_ok(tctx
,
200 "lsaRQueryForestTrustInformation failed");
202 torture_assert_not_null(tctx
,
203 r
.out
.forest_trust_info
,
204 "forest_trust_info is not set");
205 torture_assert_int_equal(tctx
,
208 "Unexpected forest_trust_info count");
210 rec
= fti
->entries
[0];
211 torture_assert_int_equal(tctx
,
213 LSA_FOREST_TRUST_TOP_LEVEL_NAME
,
215 torture_assert_str_equal(tctx
,
216 rec
->forest_trust_data
.top_level_name
.string
,
218 "Unexpected top level name");
223 static bool test_create_trust_and_set_info(struct dcerpc_pipe
*p
,
224 struct torture_context
*tctx
,
225 const char *trust_name
,
226 const char *trust_name_dns
,
227 struct dom_sid
*domsid
,
228 struct lsa_TrustDomainInfoAuthInfoInternal
*authinfo
)
230 struct policy_handle
*handle
;
232 struct policy_handle closed_handle
;
233 struct lsa_CreateTrustedDomainEx2 r
;
234 struct lsa_TrustDomainInfoInfoEx trustinfo
;
235 struct policy_handle trustdom_handle
;
236 struct lsa_QueryTrustedDomainInfo q
;
237 union lsa_TrustedDomainInfo
*info
= NULL
;
240 if (!test_get_policy_handle(tctx
, p
,
241 (LSA_POLICY_VIEW_LOCAL_INFORMATION
|
242 LSA_POLICY_TRUST_ADMIN
|
243 LSA_POLICY_CREATE_SECRET
), &handle
)) {
247 torture_comment(tctx
, "\nTesting CreateTrustedDomainEx2\n");
249 trustinfo
.sid
= domsid
;
250 trustinfo
.netbios_name
.string
= trust_name
;
251 trustinfo
.domain_name
.string
= trust_name_dns
;
253 trustinfo
.trust_direction
= LSA_TRUST_DIRECTION_INBOUND
|
254 LSA_TRUST_DIRECTION_OUTBOUND
;
256 trustinfo
.trust_type
= LSA_TRUST_TYPE_UPLEVEL
;
259 * MS-LSAD: Section 3.1.4.7.10 makes it clear that Win2k3
260 * functional level and above return
261 * NT_STATUS_INVALID_DOMAIN_STATE if
262 * TRUST_ATTRIBUTE_FOREST_TRANSITIVE or
263 * TRUST_ATTRIBUTE_CROSS_ORGANIZATION is set here.
265 * But we really want to test forest trusts here.
267 trustinfo
.trust_attributes
= LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE
;
269 r
.in
.policy_handle
= handle
;
270 r
.in
.info
= &trustinfo
;
271 r
.in
.auth_info_internal
= authinfo
;
272 /* LSA_TRUSTED_QUERY_DOMAIN_NAME is needed for for following
273 * QueryTrustedDomainInfo call, although it seems that Windows does not
275 r
.in
.access_mask
= LSA_TRUSTED_SET_POSIX
| LSA_TRUSTED_SET_AUTH
| LSA_TRUSTED_QUERY_DOMAIN_NAME
;
276 r
.out
.trustdom_handle
= &trustdom_handle
;
278 torture_assert_ntstatus_ok(tctx
,
279 dcerpc_lsa_CreateTrustedDomainEx2_r(p
->binding_handle
, tctx
, &r
),
280 "CreateTrustedDomainEx2 failed");
281 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "CreateTrustedDomainEx2 failed");
283 q
.in
.trustdom_handle
= &trustdom_handle
;
284 q
.in
.level
= LSA_TRUSTED_DOMAIN_INFO_INFO_EX
;
287 torture_assert_ntstatus_ok(tctx
,
288 dcerpc_lsa_QueryTrustedDomainInfo_r(p
->binding_handle
, tctx
, &q
),
289 "QueryTrustedDomainInfo failed");
290 torture_assert_ntstatus_ok(tctx
, q
.out
.result
, "QueryTrustedDomainInfo level 1");
291 torture_assert(tctx
, q
.out
.info
!= NULL
, "QueryTrustedDomainInfo level 1 failed to return an info pointer");
292 torture_assert_str_equal(tctx
, info
->info_ex
.netbios_name
.string
,
293 trustinfo
.netbios_name
.string
,
294 "QueryTrustedDomainInfo returned inconsistent short name");
295 torture_assert_int_equal(tctx
, info
->info_ex
.trust_type
, trustinfo
.trust_type
,
296 "QueryTrustedDomainInfo returned incorrect trust type");
297 torture_assert_int_equal(tctx
, info
->info_ex
.trust_attributes
, trustinfo
.trust_attributes
,
298 "QueryTrustedDomainInfo of returned incorrect trust attributes");
299 torture_assert_int_equal(tctx
, info
->info_ex
.trust_direction
, trustinfo
.trust_direction
,
300 "QueryTrustedDomainInfo of returned incorrect trust direction");
302 ok
= test_set_forest_trust_info(
303 p
, tctx
, handle
, domsid
, trust_name
, trust_name_dns
);
308 ok
= test_query_forest_trust_info(p
, tctx
, handle
, trust_name_dns
);
313 cr
.in
.handle
= handle
;
314 cr
.out
.handle
= &closed_handle
;
315 torture_assert_ntstatus_ok(tctx
,
316 dcerpc_lsa_Close_r(p
->binding_handle
, tctx
, &cr
),
318 torture_assert_ntstatus_ok(tctx
, cr
.out
.result
, "Close failed");
323 struct get_set_info
{
324 enum lsa_TrustDomInfoEnum info_level
;
329 static bool get_and_set_info(struct dcerpc_pipe
*p
,
330 struct torture_context
*tctx
,
333 struct policy_handle
*handle
;
335 struct lsa_QueryTrustedDomainInfoByName qr
;
336 struct lsa_SetTrustedDomainInfoByName sr
;
337 union lsa_TrustedDomainInfo
*info
= NULL
;
339 struct policy_handle closed_handle
;
342 struct get_set_info il
[] = {
343 {LSA_TRUSTED_DOMAIN_INFO_NAME
, NT_STATUS_OK
, NT_STATUS_INVALID_PARAMETER
},
344 /* {LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS, NT_STATUS_INVALID_PARAMETER, NT_STATUS_INVALID_INFO_CLASS}, */
345 {LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET
, NT_STATUS_OK
, NT_STATUS_OK
},
346 /* {LSA_TRUSTED_DOMAIN_INFO_PASSWORD, NT_STATUS_INVALID_PARAMETER, NT_STATUS_INVALID_INFO_CLASS}, */
347 /* {LSA_TRUSTED_DOMAIN_INFO_BASIC, NT_STATUS_INVALID_PARAMETER, NT_STATUS_INVALID_INFO_CLASS}, */
348 {LSA_TRUSTED_DOMAIN_INFO_INFO_EX
, NT_STATUS_OK
, NT_STATUS_OK
},
349 /* {LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO, NT_STATUS_INVALID_PARAMETER, NT_STATUS_INVALID_INFO_CLASS}, */
350 {LSA_TRUSTED_DOMAIN_INFO_FULL_INFO
, NT_STATUS_OK
, NT_STATUS_OK
},
351 /* {LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL, NT_STATUS_INVALID_PARAMETER, NT_STATUS_INVALID_INFO_CLASS}, */
352 /* {LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL, NT_STATUS_INVALID_PARAMETER, NT_STATUS_INVALID_INFO_CLASS}, */
353 /* {LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL, NT_STATUS_INVALID_PARAMETER, NT_STATUS_INVALID_INFO_CLASS}, */
354 {LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL
, NT_STATUS_OK
, NT_STATUS_INVALID_PARAMETER
},
355 {LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES
, NT_STATUS_OK
, NT_STATUS_OK
},
356 { .info_level
= -1, },
359 torture_comment(tctx
, "\nGetting/Setting dom info\n");
361 if(!test_get_policy_handle(tctx
, p
, LSA_POLICY_VIEW_LOCAL_INFORMATION
,
366 qr
.in
.handle
= handle
;
367 qr
.in
.trusted_domain
= talloc_zero(tctx
, struct lsa_String
);
368 qr
.in
.trusted_domain
->string
= name
;
371 sr
.in
.handle
= handle
;
372 sr
.in
.trusted_domain
= talloc_zero(tctx
, struct lsa_String
);
373 sr
.in
.trusted_domain
->string
= name
;
375 for (c
= 0; il
[c
].info_level
!= -1; c
++) {
376 torture_comment(tctx
, "\nGetting/Setting dom info [%d]\n",il
[c
].info_level
);
378 qr
.in
.level
= il
[c
].info_level
;
379 status
= dcerpc_lsa_QueryTrustedDomainInfoByName_r(p
->binding_handle
,
381 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_OK
,
382 "QueryTrustedDomainInfoByName failed");
383 if (!NT_STATUS_EQUAL(qr
.out
.result
, il
[c
].get_result
)) {
384 torture_comment(tctx
, "QueryTrustedDomainInfoByName did not return "
386 nt_errstr(il
[c
].get_result
),
387 nt_errstr(qr
.out
.result
));
389 /* We may be testing a server without support for this level */
390 if (qr
.in
.level
== LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES
&& NT_STATUS_EQUAL(qr
.out
.result
, NT_STATUS_INVALID_PARAMETER
)) {
396 sr
.in
.level
= il
[c
].info_level
;
398 status
= dcerpc_lsa_SetTrustedDomainInfoByName_r(p
->binding_handle
,
400 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_OK
,
401 "SetTrustedDomainInfoByName failed");
402 if (!NT_STATUS_EQUAL(sr
.out
.result
, il
[c
].set_result
)) {
403 torture_comment(tctx
, "SetTrustedDomainInfoByName did not return "
405 nt_errstr(il
[c
].set_result
),
406 nt_errstr(sr
.out
.result
));
411 cr
.in
.handle
= handle
;
412 cr
.out
.handle
= &closed_handle
;
413 torture_assert_ntstatus_ok(tctx
,
414 dcerpc_lsa_Close_r(p
->binding_handle
, tctx
, &cr
),
416 torture_assert_ntstatus_ok(tctx
, cr
.out
.result
, "Close failed");
421 static bool check_name(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
424 struct policy_handle
*handle
;
426 struct lsa_QueryTrustedDomainInfoByName qr
;
427 union lsa_TrustedDomainInfo
*info
;
429 struct policy_handle closed_handle
;
431 torture_comment(tctx
, "\nGetting LSA_TRUSTED_DOMAIN_INFO_FULL_INFO\n");
433 if(!test_get_policy_handle(tctx
, p
, LSA_POLICY_VIEW_LOCAL_INFORMATION
,
438 qr
.in
.handle
= handle
;
439 qr
.in
.trusted_domain
= talloc_zero(tctx
, struct lsa_String
);
440 qr
.in
.trusted_domain
->string
= name
;
441 qr
.in
.level
= LSA_TRUSTED_DOMAIN_INFO_FULL_INFO
;
443 status
= dcerpc_lsa_QueryTrustedDomainInfoByName_r(p
->binding_handle
,
445 torture_assert_ntstatus_ok(tctx
, status
,
446 "QueryInfoPolicy2 failed");
447 torture_assert_ntstatus_equal(tctx
, qr
.out
.result
, NT_STATUS_OBJECT_NAME_NOT_FOUND
,
448 "QueryInfoPolicy2 did not return "
449 "NT_STATUS_OBJECT_NAME_NOT_FOUND");
451 cr
.in
.handle
= handle
;
452 cr
.out
.handle
= &closed_handle
;
453 torture_assert_ntstatus_ok(tctx
,
454 dcerpc_lsa_Close_r(p
->binding_handle
, tctx
, &cr
),
456 torture_assert_ntstatus_ok(tctx
, cr
.out
.result
, "Close failed");
461 static bool get_lsa_policy_info_dns(struct dcerpc_pipe
*p
,
462 struct torture_context
*tctx
,
463 union lsa_PolicyInformation
**info
)
465 struct policy_handle
*handle
;
467 struct lsa_QueryInfoPolicy2 qr
;
469 struct policy_handle closed_handle
;
471 torture_comment(tctx
, "\nGetting LSA_POLICY_INFO_DNS\n");
473 if (!test_get_policy_handle(tctx
, p
, LSA_POLICY_VIEW_LOCAL_INFORMATION
,
478 qr
.in
.handle
= handle
;
479 qr
.in
.level
= LSA_POLICY_INFO_DNS
;
481 status
= dcerpc_lsa_QueryInfoPolicy2_r(p
->binding_handle
, tctx
, &qr
);
482 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_OK
,
483 "QueryInfoPolicy2 failed");
484 if (!NT_STATUS_IS_OK(qr
.out
.result
)) {
485 torture_comment(tctx
, "QueryInfoPolicy2 failed - %s\n",
486 nt_errstr(qr
.out
.result
));
490 cr
.in
.handle
= handle
;
491 cr
.out
.handle
= &closed_handle
;
492 torture_assert_ntstatus_ok(tctx
,
493 dcerpc_lsa_Close_r(p
->binding_handle
, tctx
, &cr
),
495 torture_assert_ntstatus_ok(tctx
, cr
.out
.result
, "Close failed");
500 static bool delete_trusted_domain_by_sid(struct dcerpc_pipe
*p
,
501 struct torture_context
*tctx
,
502 struct dom_sid
*domsid
)
504 struct policy_handle
*handle
;
506 struct policy_handle closed_handle
;
507 struct lsa_DeleteTrustedDomain dr
;
509 torture_comment(tctx
, "\nDeleting trusted domain.\n");
511 /* Against a windows server it was sufficient to have
512 * LSA_POLICY_VIEW_LOCAL_INFORMATION although the documentations says
514 if (!test_get_policy_handle(tctx
, p
, LSA_POLICY_TRUST_ADMIN
,
519 dr
.in
.handle
= handle
;
520 dr
.in
.dom_sid
= domsid
;
522 torture_assert_ntstatus_ok(tctx
,
523 dcerpc_lsa_DeleteTrustedDomain_r(p
->binding_handle
, tctx
, &dr
),
524 "DeleteTrustedDomain failed");
525 torture_assert_ntstatus_ok(tctx
, dr
.out
.result
, "DeleteTrustedDomain failed");
527 cr
.in
.handle
= handle
;
528 cr
.out
.handle
= &closed_handle
;
529 torture_assert_ntstatus_ok(tctx
,
530 dcerpc_lsa_Close_r(p
->binding_handle
, tctx
, &cr
),
532 torture_assert_ntstatus_ok(tctx
, cr
.out
.result
, "Close failed");
538 static const uint8_t my_blob[] = {
539 0xa3,0x0b,0x32,0x45,0x8b,0x84,0x3b,0x01,0x68,0xe8,0x2b,0xbb,0x00,0x13,0x69,0x1f,
540 0x10,0x35,0x72,0xa9,0x4f,0x77,0xb7,0xeb,0x59,0x08,0x07,0xc3,0xe8,0x17,0x00,0xc5,
541 0xf2,0xa9,0x6d,0xb7,0x69,0x45,0x63,0x20,0xcb,0x44,0x44,0x22,0x02,0xe3,0x28,0x84,
542 0x9b,0xd5,0x43,0x6f,0x8d,0x36,0x9b,0x9b,0x3b,0x31,0x86,0x84,0x8b,0xf2,0x36,0xd4,
543 0xe8,0xc4,0xee,0x90,0x0c,0xcb,0x3e,0x11,0x2f,0x86,0xfe,0x87,0x6d,0xce,0xae,0x0c,
544 0x83,0xfb,0x21,0x22,0x6d,0x7f,0x5e,0x08,0x71,0x1a,0x35,0xf4,0x5a,0x76,0x9b,0xf7,
545 0x54,0x62,0xa5,0x4c,0xcd,0xf6,0xa5,0xb0,0x0b,0xc7,0x79,0xe1,0x6f,0x85,0x16,0x6f,
546 0x82,0xdd,0x15,0x11,0x4c,0x9d,0x26,0x01,0x74,0x7e,0xbb,0xec,0x88,0x1d,0x71,0x9e,
547 0x5f,0xb2,0x9c,0xab,0x66,0x20,0x08,0x3d,0xae,0x07,0x2d,0xbb,0xa6,0xfb,0xec,0xcc,
548 0x51,0x58,0x48,0x47,0x38,0x3b,0x47,0x66,0xe8,0x17,0xfa,0x54,0x5c,0x95,0x73,0x29,
549 0xdf,0x7e,0x4a,0xb4,0x45,0x30,0xf7,0xbf,0xc0,0x56,0x6d,0x80,0xf6,0x11,0x56,0x93,
550 0xeb,0x97,0xd5,0x10,0xd6,0xd6,0xf7,0x23,0xc3,0xc0,0x93,0xa7,0x5c,0xa9,0xc0,0x81,
551 0x55,0x3d,0xec,0x03,0x31,0x7e,0x9d,0xf9,0xd0,0x9e,0xb5,0xc7,0xef,0xa8,0x54,0xf6,
552 0x9c,0xdc,0x0d,0xd4,0xd7,0xee,0x8d,0x5f,0xbd,0x89,0x48,0x3b,0x63,0xff,0xe8,0xca,
553 0x10,0x64,0x61,0xdf,0xfd,0x50,0xff,0x51,0xa0,0x2c,0xd7,0x8a,0xf1,0x13,0x02,0x02,
554 0x71,0xe9,0xff,0x0d,0x03,0x48,0xf8,0x08,0x8d,0xd5,0xe6,0x31,0x9f,0xf0,0x26,0x07,
555 0x91,0x6d,0xd3,0x01,0x91,0x92,0xc7,0x28,0x18,0x58,0xd8,0xf6,0x1b,0x97,0x8d,0xd0,
556 0xd2,0xa1,0x7c,0xae,0xc1,0xca,0xfe,0x20,0x91,0x1c,0x4d,0x15,0x89,0x29,0x37,0xd5,
557 0xf5,0xca,0x40,0x2b,0x03,0x8f,0x7b,0xc2,0x10,0xb4,0xd3,0xe8,0x14,0xb0,0x9b,0x5d,
558 0x85,0x30,0xe5,0x13,0x24,0xf7,0x78,0xec,0xbe,0x0b,0x9a,0x3f,0xb5,0x76,0xd9,0x0d,
559 0x49,0x64,0xa4,0xa7,0x33,0x88,0xdd,0xe9,0xe2,0x5f,0x04,0x51,0xdd,0x89,0xe2,0x68,
560 0x5b,0x5f,0x64,0x35,0xe3,0x23,0x4a,0x0e,0x09,0x15,0xcc,0x97,0x47,0xf4,0xc2,0x4f,
561 0x06,0xc3,0x96,0xa9,0x2f,0xb3,0xde,0x29,0x10,0xc7,0xf5,0x16,0xc5,0x3c,0x84,0xd2,
562 0x9b,0x6b,0xaa,0x54,0x59,0x8d,0x94,0xde,0xd1,0x75,0xb6,0x08,0x0d,0x7d,0xf1,0x18,
563 0xc8,0xf5,0xdf,0xaa,0xcd,0xec,0xab,0xb6,0xd1,0xcb,0xdb,0xe7,0x75,0x5d,0xbe,0x76,
564 0xea,0x1d,0x01,0xc8,0x0b,0x2d,0x32,0xe9,0xa8,0x65,0xbb,0x4a,0xcb,0x72,0xbc,0xda,
565 0x04,0x7f,0x82,0xfb,0x04,0xeb,0xd8,0xe1,0xb9,0xb1,0x1e,0xdc,0xb3,0x60,0xf3,0x55,
566 0x1e,0xcf,0x90,0x6a,0x15,0x74,0x4d,0xff,0xb4,0xc7,0xc9,0xc2,0x4f,0x67,0x9e,0xeb,
567 0x00,0x61,0x02,0xe3,0x9e,0x59,0x88,0x20,0xf1,0x0c,0xbe,0xe0,0x26,0x69,0x63,0x67,
568 0x72,0x3c,0x06,0x00,0x9e,0x4f,0xc7,0xa6,0x4d,0x6c,0xbe,0x68,0x8e,0xf4,0x32,0x36,
569 0x2e,0x5f,0xa6,0xcf,0xa7,0x19,0x40,0x2b,0xbd,0xa2,0x22,0x73,0xc4,0xb6,0xe3,0x86,
570 0x64,0xeb,0xb1,0xc7,0x45,0x7d,0xd6,0xd9,0x36,0xf1,0x04,0xd4,0x61,0xdc,0x41,0xb7,
571 0x01,0x00,0x00,0x00,0x0c,0x00,0x00,0x00, 0x30,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
572 0x02,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0x31,0x00,0x32,0x00,0x33,0x00,0x34,0x00,
573 0x35,0x00,0x36,0x00,0x37,0x00,0x38,0x00,0x39,0x00,0x30,0x00,0x01,0x00,0x00,0x00,
574 0x0c,0x00,0x00,0x00, 0x30,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
575 0x14,0x00,0x00,0x00,0x31,0x00,0x32,0x00,0x33,0x00,0x34,0x00,0x35,0x00,0x36,0x00,
576 0x37,0x00,0x38,0x00,0x39,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x00,0x00
579 static bool get_trust_domain_passwords_auth_blob(TALLOC_CTX
*mem_ctx
,
580 const char *password
,
581 DATA_BLOB
*auth_blob
)
583 struct trustDomainPasswords auth_struct
;
584 struct AuthenticationInformation
*auth_info_array
;
585 enum ndr_err_code ndr_err
;
586 size_t converted_size
;
588 generate_random_buffer(auth_struct
.confounder
,
589 sizeof(auth_struct
.confounder
));
591 auth_info_array
= talloc_array(mem_ctx
,
592 struct AuthenticationInformation
, 1);
593 if (auth_info_array
== NULL
) {
597 auth_info_array
[0].AuthType
= TRUST_AUTH_TYPE_CLEAR
;
598 if (!convert_string_talloc(mem_ctx
, CH_UNIX
, CH_UTF16
, password
,
600 &auth_info_array
[0].AuthInfo
.clear
.password
,
605 auth_info_array
[0].AuthInfo
.clear
.size
= converted_size
;
607 auth_struct
.outgoing
.count
= 1;
608 auth_struct
.outgoing
.current
.count
= 1;
609 auth_struct
.outgoing
.current
.array
= auth_info_array
;
610 auth_struct
.outgoing
.previous
.count
= 0;
611 auth_struct
.outgoing
.previous
.array
= NULL
;
613 auth_struct
.incoming
.count
= 1;
614 auth_struct
.incoming
.current
.count
= 1;
615 auth_struct
.incoming
.current
.array
= auth_info_array
;
616 auth_struct
.incoming
.previous
.count
= 0;
617 auth_struct
.incoming
.previous
.array
= NULL
;
619 ndr_err
= ndr_push_struct_blob(auth_blob
, mem_ctx
, &auth_struct
,
620 (ndr_push_flags_fn_t
)ndr_push_trustDomainPasswords
);
621 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
628 static bool test_validate_trust(struct torture_context
*tctx
,
630 const char *trusting_dom_name
,
631 const char *trusting_dom_dns_name
,
632 const char *trusted_dom_name
,
633 const char *trusted_dom_dns_name
,
634 const char *trust_password
)
636 struct netr_ServerGetTrustInfo r
;
638 struct netr_Authenticator a
;
639 struct netr_Authenticator return_authenticator
;
640 struct samr_Password new_owf_password
;
641 struct samr_Password old_owf_password
;
642 struct netr_TrustInfo
*trust_info
;
644 struct netlogon_creds_CredentialState
*creds
;
647 struct cli_credentials
*credentials
;
648 struct dcerpc_binding
*b
;
649 struct dcerpc_pipe
*p1
= NULL
;
650 struct dcerpc_pipe
*p
= NULL
;
652 struct netr_GetForestTrustInformation fr
;
653 struct lsa_ForestTrustInformation
*forest_trust_info
;
654 struct lsa_ForestTrustRecord
*tln
= NULL
;
655 struct lsa_ForestTrustRecord
*di
= NULL
;
657 struct samr_Password
*new_nt_hash
;
658 struct samr_Password
*old_nt_hash
;
660 uint32_t trust_attributes
= LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE
;
661 enum dcerpc_AuthType auth_type
= DCERPC_AUTH_TYPE_NONE
;
662 enum dcerpc_AuthLevel auth_level
= DCERPC_AUTH_LEVEL_NONE
;
664 status
= dcerpc_parse_binding(tctx
, binding
, &b
);
665 torture_assert_ntstatus_ok(tctx
, status
, "Bad binding string");
667 credentials
= cli_credentials_init(tctx
);
668 torture_assert(tctx
, credentials
!= NULL
, "cli_credentials_init()");
670 dummy
= talloc_asprintf(tctx
, "%s$", trusted_dom_name
);
671 cli_credentials_set_username(credentials
, dummy
,
673 cli_credentials_set_domain(credentials
, trusting_dom_name
,
675 cli_credentials_set_realm(credentials
, trusting_dom_dns_name
,
677 cli_credentials_set_password(credentials
, trust_password
, CRED_SPECIFIED
);
678 cli_credentials_set_old_password(credentials
, trust_password
, CRED_SPECIFIED
);
679 cli_credentials_set_workstation(credentials
,
680 trusted_dom_name
, CRED_SPECIFIED
);
681 cli_credentials_set_secure_channel_type(credentials
, SEC_CHAN_DOMAIN
);
683 status
= dcerpc_pipe_connect_b(tctx
, &p1
, b
,
684 &ndr_table_netlogon
, credentials
,
685 tctx
->ev
, tctx
->lp_ctx
);
687 if (NT_STATUS_IS_ERR(status
)) {
688 torture_comment(tctx
, "Failed to connect to remote server: %s with %s - %s\n",
690 cli_credentials_get_unparsed_name(credentials
, tctx
),
695 if (!test_SetupCredentials3(p1
, tctx
, NETLOGON_NEG_AUTH2_ADS_FLAGS
| NETLOGON_NEG_SUPPORTS_AES
,
696 credentials
, &creds
)) {
697 torture_comment(tctx
, "test_SetupCredentials3 failed.\n");
700 if (!test_SetupCredentialsPipe(p1
, tctx
, credentials
, creds
,
701 DCERPC_SIGN
| DCERPC_SEAL
, &p
)) {
702 torture_comment(tctx
, "test_SetupCredentialsPipe failed.\n");
706 netlogon_creds_client_authenticator(creds
, &a
);
708 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s",
709 dcerpc_server_name(p
));
710 r
.in
.account_name
= talloc_asprintf(tctx
, "%s$", trusted_dom_name
);
711 r
.in
.secure_channel_type
= cli_credentials_get_secure_channel_type(credentials
);
712 r
.in
.computer_name
= trusted_dom_name
;
713 r
.in
.credential
= &a
;
715 r
.out
.return_authenticator
= &return_authenticator
;
716 r
.out
.new_owf_password
= &new_owf_password
;
717 r
.out
.old_owf_password
= &old_owf_password
;
718 r
.out
.trust_info
= &trust_info
;
720 torture_assert_ntstatus_ok(tctx
,
721 dcerpc_netr_ServerGetTrustInfo_r(p
->binding_handle
, tctx
, &r
),
722 "ServerGetTrustInfo failed");
723 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
724 "ServerGetTrustInfo failed");
726 torture_assert(tctx
, trust_info
!= NULL
, "ServerGetTrustInfo got no trust_info");
727 torture_assert_int_equal(tctx
, trust_info
->count
, 1,
728 "Unexpected number of results");
729 torture_assert_int_equal(tctx
, trust_info
->data
[0], trust_attributes
,
730 "Unexpected trust_attributes");
732 new_nt_hash
= cli_credentials_get_nt_hash(credentials
, tctx
);
733 torture_assert(tctx
, new_nt_hash
!= NULL
, "cli_credentials_get_nt_hash()");
735 old_nt_hash
= cli_credentials_get_old_nt_hash(credentials
, tctx
);
736 torture_assert(tctx
, old_nt_hash
!= NULL
, "cli_credentials_get_old_nt_hash()");
738 dcerpc_binding_handle_auth_info(p
->binding_handle
,
741 status
= netlogon_creds_decrypt_samr_Password(creds
,
745 torture_assert_ntstatus_ok(tctx
, status
, "decrypt_samr_Password");
746 status
= netlogon_creds_decrypt_samr_Password(creds
,
750 torture_assert_ntstatus_ok(tctx
, status
, "decrypt_samr_Password");
752 dump_data(1, new_owf_password
.hash
, 16);
753 dump_data(1, new_nt_hash
->hash
, 16);
754 dump_data(1, old_owf_password
.hash
, 16);
755 dump_data(1, old_nt_hash
->hash
, 16);
757 torture_assert_mem_equal(tctx
, new_owf_password
.hash
, new_nt_hash
->hash
, 16,
758 "received unexpected new owf password\n");
760 torture_assert_mem_equal(tctx
, old_owf_password
.hash
, old_nt_hash
->hash
, 16,
761 "received unexpected old owf password\n");
763 netlogon_creds_client_authenticator(creds
, &a
);
765 fr
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s",
766 dcerpc_server_name(p
));
767 fr
.in
.computer_name
= trusted_dom_name
;
768 fr
.in
.credential
= &a
;
770 fr
.out
.return_authenticator
= &return_authenticator
;
771 fr
.out
.forest_trust_info
= &forest_trust_info
;
773 torture_assert_ntstatus_ok(tctx
,
774 dcerpc_netr_GetForestTrustInformation_r(p
->binding_handle
, tctx
, &fr
),
775 "netr_GetForestTrustInformation failed");
776 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
777 "netr_GetForestTrustInformation failed");
779 for(i
= 0; i
< forest_trust_info
->count
; i
++) {
780 struct lsa_ForestTrustRecord
*e
= forest_trust_info
->entries
[i
];
783 case LSA_FOREST_TRUST_TOP_LEVEL_NAME
:
784 if (strcmp(e
->forest_trust_data
.top_level_name
.string
, trusting_dom_dns_name
) != 0) {
788 torture_assert(tctx
, tln
== NULL
, "TOP_LEVEL_NAME found twice");
793 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX
:
796 case LSA_FOREST_TRUST_DOMAIN_INFO
:
797 if (strcmp(e
->forest_trust_data
.domain_info
.dns_domain_name
.string
, trusting_dom_dns_name
) != 0) {
801 torture_assert(tctx
, di
== NULL
, "DOMAIN_INFO found twice");
806 torture_assert_int_equal(tctx
, e
->type
, LSA_FOREST_TRUST_TOP_LEVEL_NAME
,
807 "Unexpected LSA_FOREST_TRUST_* type");
811 torture_assert(tctx
, tln
!= NULL
, "TOP_LEVEL_NAME entry missing");
812 torture_assert(tctx
, di
!= NULL
, "DOMAIN_INFO entry missing");
814 torture_assert_str_equal(tctx
, di
->forest_trust_data
.domain_info
.netbios_domain_name
.string
,
816 "netbios_domain_name mismatch");
821 static bool test_setup_trust(struct torture_context
*tctx
,
822 struct dcerpc_pipe
*p
,
823 const char *netbios_name
,
824 const char *dns_name
,
826 DATA_BLOB
*auth_blob
)
829 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
830 DATA_BLOB session_key
;
831 struct lsa_TrustDomainInfoAuthInfoInternal authinfo
;
833 gnutls_cipher_hd_t cipher_hnd
= NULL
;
834 gnutls_datum_t _session_key
;
836 if (!check_name(p
, tctx
, netbios_name
)) {
839 if (!check_name(p
, tctx
, dns_name
)) {
843 status
= dcerpc_binding_handle_transport_session_key(b
, p
, &session_key
);
844 if (!NT_STATUS_IS_OK(status
)) {
845 torture_comment(tctx
, "transport_session_key failed - %s\n",
850 authinfo
.auth_blob
.data
= talloc_memdup(tctx
, auth_blob
->data
,
852 if (authinfo
.auth_blob
.data
== NULL
) {
855 authinfo
.auth_blob
.size
= auth_blob
->length
;
857 _session_key
= (gnutls_datum_t
) {
858 .data
= session_key
.data
,
859 .size
= session_key
.length
,
862 gnutls_cipher_init(&cipher_hnd
,
863 GNUTLS_CIPHER_ARCFOUR_128
,
866 gnutls_cipher_encrypt(cipher_hnd
,
867 authinfo
.auth_blob
.data
,
868 authinfo
.auth_blob
.size
);
869 gnutls_cipher_deinit(cipher_hnd
);
871 if (!test_create_trust_and_set_info(p
, tctx
, netbios_name
,
872 dns_name
, sid
, &authinfo
)) {
879 static bool testcase_ForestTrusts(struct torture_context
*tctx
,
880 struct dcerpc_pipe
*p
)
882 const char *dom2_binding_string
;
883 const char * dom2_cred_string
;
885 struct dom_sid
*domsid
;
887 struct dcerpc_binding
*dom2_binding
;
888 struct dcerpc_pipe
*dom2_p
;
889 struct cli_credentials
*dom2_credentials
;
890 union lsa_PolicyInformation
*dom1_info_dns
= NULL
;
891 union lsa_PolicyInformation
*dom2_info_dns
= NULL
;
892 const char *binding
= torture_setting_string(tctx
, "binding", NULL
);
895 torture_comment(tctx
, "Testing Forest Trusts\n");
897 test_password
= generate_random_password(tctx
, 32, 64);
898 torture_assert(tctx
, test_password
!= NULL
, "test password must be generated");
900 if (!get_trust_domain_passwords_auth_blob(tctx
, test_password
, &auth_blob
)) {
901 torture_comment(tctx
,
902 "get_trust_domain_passwords_auth_blob failed\n");
907 /* Use the following if get_trust_domain_passwords_auth_blob() cannot
908 * generate a usable blob due to errors in the IDL */
909 auth_blob
.data
= talloc_memdup(tctx
, my_blob
, sizeof(my_blob
));
910 auth_blob
.length
= sizeof(my_blob
);
912 test_password
= "1234567890"
915 domsid
= dom_sid_parse_talloc(tctx
, TEST_DOM_SID
);
916 if (domsid
== NULL
) {
920 if (!test_setup_trust(tctx
, p
, TEST_DOM
, TEST_DOM_DNS
, domsid
,
925 if (!get_lsa_policy_info_dns(p
, tctx
, &dom1_info_dns
)) {
929 if (!get_and_set_info(p
, tctx
, TEST_DOM
)) {
933 if (!test_validate_trust(tctx
, binding
,
934 dom1_info_dns
->dns
.name
.string
,
935 dom1_info_dns
->dns
.dns_domain
.string
,
936 TEST_DOM
, TEST_DOM_DNS
, test_password
)) {
940 if (!delete_trusted_domain_by_sid(p
, tctx
, domsid
)) {
944 dom2_binding_string
= torture_setting_string(tctx
,
945 "Forest_Trust_Dom2_Binding",
947 if (dom2_binding_string
== NULL
) {
948 torture_skip(tctx
, "torture:Forest_Trust_Dom2_Binding not specified\n");
951 status
= dcerpc_parse_binding(tctx
, dom2_binding_string
, &dom2_binding
);
952 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_parse_binding()");
954 dom2_cred_string
= torture_setting_string(tctx
,
955 "Forest_Trust_Dom2_Creds",
957 torture_assert(tctx
, dom2_cred_string
!= NULL
, "torture:Forest_Trust_Dom2_Creds missing");
959 dom2_credentials
= cli_credentials_init(tctx
);
960 torture_assert(tctx
, dom2_credentials
!= NULL
, "cli_credentials_init()");
962 cli_credentials_parse_string(dom2_credentials
, dom2_cred_string
,
964 cli_credentials_set_workstation(dom2_credentials
,
965 TEST_MACHINE_NAME
, CRED_SPECIFIED
);
967 status
= dcerpc_pipe_connect_b(tctx
, &dom2_p
, dom2_binding
,
968 &ndr_table_lsarpc
, dom2_credentials
,
969 tctx
->ev
, tctx
->lp_ctx
);
970 torture_assert_ntstatus_ok(tctx
, status
, talloc_asprintf(tctx
,
971 "Failed to connect to remote server: %s\n",
972 dcerpc_binding_string(tctx
, dom2_binding
)));
974 if (!get_lsa_policy_info_dns(dom2_p
, tctx
, &dom2_info_dns
)) {
978 if (strcasecmp(dom1_info_dns
->dns
.name
.string
,
979 dom2_info_dns
->dns
.name
.string
) == 0 ||
980 strcasecmp(dom1_info_dns
->dns
.dns_domain
.string
,
981 dom2_info_dns
->dns
.dns_domain
.string
) == 0)
983 torture_assert(tctx
, false, talloc_asprintf(tctx
,
984 "Trusting (%s;%s) and trusted domain (%s;%s) have the "
986 dom1_info_dns
->dns
.name
.string
,
987 dom1_info_dns
->dns
.dns_domain
.string
,
988 dom2_info_dns
->dns
.name
.string
,
989 dom2_info_dns
->dns
.dns_domain
.string
));
992 if (!test_setup_trust(tctx
, p
, dom2_info_dns
->dns
.name
.string
,
993 dom2_info_dns
->dns
.dns_domain
.string
,
994 dom2_info_dns
->dns
.sid
, &auth_blob
)) {
997 if (!test_setup_trust(tctx
, dom2_p
, dom1_info_dns
->dns
.name
.string
,
998 dom1_info_dns
->dns
.dns_domain
.string
,
999 dom1_info_dns
->dns
.sid
, &auth_blob
)) {
1003 if (!test_validate_trust(tctx
, binding
,
1004 dom1_info_dns
->dns
.name
.string
,
1005 dom1_info_dns
->dns
.dns_domain
.string
,
1006 dom2_info_dns
->dns
.name
.string
,
1007 dom2_info_dns
->dns
.dns_domain
.string
, test_password
)) {
1011 if (!test_validate_trust(tctx
, dom2_binding_string
,
1012 dom2_info_dns
->dns
.name
.string
,
1013 dom2_info_dns
->dns
.dns_domain
.string
,
1014 dom1_info_dns
->dns
.name
.string
,
1015 dom1_info_dns
->dns
.dns_domain
.string
, test_password
)) {
1019 if (!delete_trusted_domain_by_sid(p
, tctx
, dom2_info_dns
->dns
.sid
)) {
1023 if (!delete_trusted_domain_by_sid(dom2_p
, tctx
, dom1_info_dns
->dns
.sid
)) {
1030 /* By default this test creates a trust object in the destination server to a
1031 * dummy domain. If a second server from a different domain is specified on the
1032 * command line a trust is created between those two domains.
1035 * smbtorture ncacn_np:srv1.dom1.test[print] RPC-LSA-FOREST-TRUST \
1036 * -U 'dom1\testadm1%12345678' \
1037 * --option=torture:Forest_Trust_Dom2_Binding=ncacn_np:srv2.dom2.test[print] \
1038 * --option=torture:Forest_Trust_Dom2_Creds='dom2\testadm2%12345678'
1041 struct torture_suite
*torture_rpc_lsa_forest_trust(TALLOC_CTX
*mem_ctx
)
1043 struct torture_suite
*suite
;
1044 struct torture_rpc_tcase
*tcase
;
1046 suite
= torture_suite_create(mem_ctx
, "lsa.forest.trust");
1048 tcase
= torture_suite_add_rpc_iface_tcase(suite
, "lsa-forest-trust",
1050 torture_rpc_tcase_add_test(tcase
, "ForestTrust", testcase_ForestTrusts
);