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 "../lib/crypto/crypto.h"
35 #define TEST_DOM "torturedom"
36 #define TEST_DOM_DNS "torturedom.samba.example.com"
37 #define TEST_DOM_SID "S-1-5-21-97398-379795-10000"
38 #define TEST_MACHINE_NAME "lsatestmach"
41 static bool test_get_policy_handle(struct torture_context
*tctx
,
42 struct dcerpc_pipe
*p
,
44 struct policy_handle
**handle
)
46 struct policy_handle
*h
;
47 struct lsa_OpenPolicy2 pr
;
48 struct lsa_ObjectAttribute attr
;
51 h
= talloc(tctx
, struct policy_handle
);
58 attr
.object_name
= NULL
;
63 pr
.in
.system_name
= "\\";
65 pr
.in
.access_mask
= access_mask
;
68 status
= dcerpc_lsa_OpenPolicy2_r(p
->binding_handle
, tctx
, &pr
);
69 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_OK
,
70 "OpenPolicy2 failed");
71 if (!NT_STATUS_IS_OK(pr
.out
.result
)) {
72 torture_comment(tctx
, "OpenPolicy2 failed - %s\n",
73 nt_errstr(pr
.out
.result
));
82 static bool test_create_trust_and_set_info(struct dcerpc_pipe
*p
,
83 struct torture_context
*tctx
,
84 const char *trust_name
,
85 const char *trust_name_dns
,
86 struct dom_sid
*domsid
,
87 struct lsa_TrustDomainInfoAuthInfoInternal
*authinfo
)
89 struct policy_handle
*handle
;
91 struct lsa_lsaRSetForestTrustInformation fti
;
92 struct lsa_ForestTrustCollisionInfo
*collision_info
= NULL
;
94 struct policy_handle closed_handle
;
96 struct lsa_CreateTrustedDomainEx2 r
;
97 struct lsa_TrustDomainInfoInfoEx trustinfo
;
98 struct policy_handle trustdom_handle
;
99 struct lsa_QueryTrustedDomainInfo q
;
100 union lsa_TrustedDomainInfo
*info
= NULL
;
102 if (!test_get_policy_handle(tctx
, p
,
103 (LSA_POLICY_VIEW_LOCAL_INFORMATION
|
104 LSA_POLICY_TRUST_ADMIN
|
105 LSA_POLICY_CREATE_SECRET
), &handle
)) {
109 torture_comment(tctx
, "\nTesting CreateTrustedDomainEx2\n");
111 trustinfo
.sid
= domsid
;
112 trustinfo
.netbios_name
.string
= trust_name
;
113 trustinfo
.domain_name
.string
= trust_name_dns
;
115 trustinfo
.trust_direction
= LSA_TRUST_DIRECTION_INBOUND
|
116 LSA_TRUST_DIRECTION_OUTBOUND
;
118 trustinfo
.trust_type
= LSA_TRUST_TYPE_UPLEVEL
;
120 /* MS-LSAD: Section 3.1.4.7.10 makes it clear that Win2k3
121 * functional level and above return
122 * NT_STATUS_INVALID_DOMAIN_STATE if
123 * TRUST_ATTRIBUTE_FOREST_TRANSITIVE or
124 * TRUST_ATTRIBUTE_CROSS_ORGANIZATION is set here.
126 trustinfo
.trust_attributes
= 0;
128 r
.in
.policy_handle
= handle
;
129 r
.in
.info
= &trustinfo
;
130 r
.in
.auth_info_internal
= authinfo
;
131 /* LSA_TRUSTED_QUERY_DOMAIN_NAME is needed for for following
132 * QueryTrustedDomainInfo call, although it seems that Windows does not
134 r
.in
.access_mask
= LSA_TRUSTED_SET_POSIX
| LSA_TRUSTED_SET_AUTH
| LSA_TRUSTED_QUERY_DOMAIN_NAME
;
135 r
.out
.trustdom_handle
= &trustdom_handle
;
137 torture_assert_ntstatus_ok(tctx
,
138 dcerpc_lsa_CreateTrustedDomainEx2_r(p
->binding_handle
, tctx
, &r
),
139 "CreateTrustedDomainEx2 failed");
140 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
141 torture_comment(tctx
, "CreateTrustedDomainEx2 failed - %s\n", nt_errstr(r
.out
.result
));
145 q
.in
.trustdom_handle
= &trustdom_handle
;
146 q
.in
.level
= LSA_TRUSTED_DOMAIN_INFO_INFO_EX
;
149 torture_assert_ntstatus_ok(tctx
,
150 dcerpc_lsa_QueryTrustedDomainInfo_r(p
->binding_handle
, tctx
, &q
),
151 "QueryTrustedDomainInfo failed");
152 if (!NT_STATUS_IS_OK(q
.out
.result
)) {
153 torture_comment(tctx
,
154 "QueryTrustedDomainInfo level 1 failed - %s\n",
155 nt_errstr(q
.out
.result
));
157 } else if (!q
.out
.info
) {
158 torture_comment(tctx
,
159 "QueryTrustedDomainInfo level 1 failed to return an info pointer\n");
162 if (strcmp(info
->info_ex
.netbios_name
.string
, trustinfo
.netbios_name
.string
) != 0) {
163 torture_comment(tctx
,
164 "QueryTrustedDomainInfo returned inconsistent short name: %s != %s\n",
165 info
->info_ex
.netbios_name
.string
,
166 trustinfo
.netbios_name
.string
);
169 if (info
->info_ex
.trust_type
!= trustinfo
.trust_type
) {
170 torture_comment(tctx
,
171 "QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n",
173 info
->info_ex
.trust_type
,
174 trustinfo
.trust_type
);
177 if (info
->info_ex
.trust_attributes
!= trustinfo
.trust_attributes
) {
178 torture_comment(tctx
,
179 "QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n",
181 info
->info_ex
.trust_attributes
,
182 trustinfo
.trust_attributes
);
185 if (info
->info_ex
.trust_direction
!= trustinfo
.trust_direction
) {
186 torture_comment(tctx
,
187 "QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n",
189 info
->info_ex
.trust_direction
,
190 trustinfo
.trust_direction
);
197 fti
.in
.handle
= handle
;
198 fti
.in
.trusted_domain_name
= talloc_zero(tctx
, struct lsa_StringLarge
);
199 fti
.in
.trusted_domain_name
->string
= trust_name_dns
;
200 fti
.in
.highest_record_type
= 2;
201 fti
.in
.forest_trust_info
= talloc_zero(tctx
, struct lsa_ForestTrustInformation
);
202 fti
.in
.forest_trust_info
->count
= 2;
203 fti
.in
.forest_trust_info
->entries
= talloc_array(tctx
, struct lsa_ForestTrustRecord
*, 2);
204 fti
.in
.forest_trust_info
->entries
[0] = talloc_zero(tctx
, struct lsa_ForestTrustRecord
);
205 fti
.in
.forest_trust_info
->entries
[0]->flags
= 0;
206 fti
.in
.forest_trust_info
->entries
[0]->type
= LSA_FOREST_TRUST_TOP_LEVEL_NAME
;
207 fti
.in
.forest_trust_info
->entries
[0]->time
= 0;
208 fti
.in
.forest_trust_info
->entries
[0]->forest_trust_data
.top_level_name
.string
= trust_name_dns
;
209 fti
.in
.forest_trust_info
->entries
[1] = talloc_zero(tctx
, struct lsa_ForestTrustRecord
);
210 fti
.in
.forest_trust_info
->entries
[1]->flags
= 0;
211 fti
.in
.forest_trust_info
->entries
[1]->type
= LSA_FOREST_TRUST_DOMAIN_INFO
;
212 fti
.in
.forest_trust_info
->entries
[1]->time
= 0;
213 fti
.in
.forest_trust_info
->entries
[1]->forest_trust_data
.domain_info
.domain_sid
= domsid
;
214 fti
.in
.forest_trust_info
->entries
[1]->forest_trust_data
.domain_info
.dns_domain_name
.string
= trust_name_dns
;
215 fti
.in
.forest_trust_info
->entries
[1]->forest_trust_data
.domain_info
.netbios_domain_name
.string
= trust_name
;
216 fti
.in
.check_only
= 0;
217 fti
.out
.collision_info
= &collision_info
;
219 torture_comment(tctx
, "\nTesting SetForestTrustInformation\n");
221 torture_assert_ntstatus_ok(tctx
,
222 dcerpc_lsa_lsaRSetForestTrustInformation_r(p
->binding_handle
, tctx
, &fti
),
223 "lsaRSetForestTrustInformation failed");
224 if (!NT_STATUS_IS_OK(fti
.out
.result
)) {
225 torture_comment(tctx
,
226 "lsaRSetForestTrustInformation failed - %s\n",
227 nt_errstr(fti
.out
.result
));
232 cr
.in
.handle
= handle
;
233 cr
.out
.handle
= &closed_handle
;
234 status
= dcerpc_lsa_Close_r(p
->binding_handle
, tctx
, &cr
);
235 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_OK
,
237 if (!NT_STATUS_IS_OK(cr
.out
.result
)) {
238 torture_comment(tctx
, "Close failed - %s\n",
239 nt_errstr(cr
.out
.result
));
246 struct get_set_info
{
247 enum lsa_TrustDomInfoEnum info_level
;
252 static bool get_and_set_info(struct dcerpc_pipe
*p
,
253 struct torture_context
*tctx
,
256 struct policy_handle
*handle
;
258 struct lsa_QueryTrustedDomainInfoByName qr
;
259 struct lsa_SetTrustedDomainInfoByName sr
;
260 union lsa_TrustedDomainInfo
*info
;
262 struct policy_handle closed_handle
;
265 struct get_set_info il
[] = {
266 {LSA_TRUSTED_DOMAIN_INFO_NAME
, NT_STATUS_OK
, NT_STATUS_INVALID_PARAMETER
},
267 /* {LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS, NT_STATUS_INVALID_PARAMETER, NT_STATUS_INVALID_INFO_CLASS}, */
268 {LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET
, NT_STATUS_OK
, NT_STATUS_OK
},
269 /* {LSA_TRUSTED_DOMAIN_INFO_PASSWORD, NT_STATUS_INVALID_PARAMETER, NT_STATUS_INVALID_INFO_CLASS}, */
270 /* {LSA_TRUSTED_DOMAIN_INFO_BASIC, NT_STATUS_INVALID_PARAMETER, NT_STATUS_INVALID_INFO_CLASS}, */
271 {LSA_TRUSTED_DOMAIN_INFO_INFO_EX
, NT_STATUS_OK
, NT_STATUS_OK
},
272 /* {LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO, NT_STATUS_INVALID_PARAMETER, NT_STATUS_INVALID_INFO_CLASS}, */
273 {LSA_TRUSTED_DOMAIN_INFO_FULL_INFO
, NT_STATUS_OK
, NT_STATUS_OK
},
274 /* {LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL, NT_STATUS_INVALID_PARAMETER, NT_STATUS_INVALID_INFO_CLASS}, */
275 /* {LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL, NT_STATUS_INVALID_PARAMETER, NT_STATUS_INVALID_INFO_CLASS}, */
276 /* {LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL, NT_STATUS_INVALID_PARAMETER, NT_STATUS_INVALID_INFO_CLASS}, */
277 {LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL
, NT_STATUS_OK
, NT_STATUS_INVALID_PARAMETER
},
278 {LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES
, NT_STATUS_OK
, NT_STATUS_OK
},
282 torture_comment(tctx
, "\nGetting/Setting dom info\n");
284 if(!test_get_policy_handle(tctx
, p
, LSA_POLICY_VIEW_LOCAL_INFORMATION
,
289 qr
.in
.handle
= handle
;
290 qr
.in
.trusted_domain
= talloc_zero(tctx
, struct lsa_String
);
291 qr
.in
.trusted_domain
->string
= name
;
294 sr
.in
.handle
= handle
;
295 sr
.in
.trusted_domain
= talloc_zero(tctx
, struct lsa_String
);
296 sr
.in
.trusted_domain
->string
= name
;
299 for (c
= 0; il
[c
].info_level
!= -1; c
++) {
300 torture_comment(tctx
, "\nGetting/Setting dom info [%d]\n",il
[c
].info_level
);
301 qr
.in
.level
= il
[c
].info_level
;
302 status
= dcerpc_lsa_QueryTrustedDomainInfoByName_r(p
->binding_handle
,
304 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_OK
,
305 "QueryTrustedDomainInfoByName failed");
306 if (!NT_STATUS_EQUAL(qr
.out
.result
, il
[c
].get_result
)) {
307 torture_comment(tctx
, "QueryTrustedDomainInfoByName did not return "
309 nt_errstr(il
[c
].get_result
),
310 nt_errstr(qr
.out
.result
));
312 /* We may be testing a server without support for this level */
313 if (qr
.in
.level
== LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES
&& NT_STATUS_EQUAL(qr
.out
.result
, NT_STATUS_INVALID_PARAMETER
)) {
319 sr
.in
.level
= il
[c
].info_level
;
321 status
= dcerpc_lsa_SetTrustedDomainInfoByName_r(p
->binding_handle
,
323 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_OK
,
324 "SetTrustedDomainInfoByName failed");
325 if (!NT_STATUS_EQUAL(sr
.out
.result
, il
[c
].set_result
)) {
326 torture_comment(tctx
, "SetTrustedDomainInfoByName did not return "
328 nt_errstr(il
[c
].set_result
),
329 nt_errstr(sr
.out
.result
));
334 cr
.in
.handle
= handle
;
335 cr
.out
.handle
= &closed_handle
;
336 status
= dcerpc_lsa_Close_r(p
->binding_handle
, tctx
, &cr
);
337 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_OK
,
339 if (!NT_STATUS_IS_OK(cr
.out
.result
)) {
340 torture_comment(tctx
, "Close failed - %s\n",
341 nt_errstr(cr
.out
.result
));
348 static bool check_name(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
351 struct policy_handle
*handle
;
353 struct lsa_QueryTrustedDomainInfoByName qr
;
354 union lsa_TrustedDomainInfo
*info
;
356 struct policy_handle closed_handle
;
358 torture_comment(tctx
, "\nGetting LSA_TRUSTED_DOMAIN_INFO_FULL_INFO\n");
360 if(!test_get_policy_handle(tctx
, p
, LSA_POLICY_VIEW_LOCAL_INFORMATION
,
365 qr
.in
.handle
= handle
;
366 qr
.in
.trusted_domain
= talloc_zero(tctx
, struct lsa_String
);
367 qr
.in
.trusted_domain
->string
= name
;
368 qr
.in
.level
= LSA_TRUSTED_DOMAIN_INFO_FULL_INFO
;
370 status
= dcerpc_lsa_QueryTrustedDomainInfoByName_r(p
->binding_handle
,
372 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_OK
,
373 "QueryInfoPolicy2 failed");
374 if (!NT_STATUS_EQUAL(qr
.out
.result
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
375 torture_comment(tctx
, "QueryInfoPolicy2 did not return "
376 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n");
380 cr
.in
.handle
= handle
;
381 cr
.out
.handle
= &closed_handle
;
382 status
= dcerpc_lsa_Close_r(p
->binding_handle
, tctx
, &cr
);
383 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_OK
,
385 if (!NT_STATUS_IS_OK(cr
.out
.result
)) {
386 torture_comment(tctx
, "Close failed - %s\n",
387 nt_errstr(cr
.out
.result
));
394 static bool get_lsa_policy_info_dns(struct dcerpc_pipe
*p
,
395 struct torture_context
*tctx
,
396 union lsa_PolicyInformation
**info
)
398 struct policy_handle
*handle
;
400 struct lsa_QueryInfoPolicy2 qr
;
402 struct policy_handle closed_handle
;
404 torture_comment(tctx
, "\nGetting LSA_POLICY_INFO_DNS\n");
406 if (!test_get_policy_handle(tctx
, p
, LSA_POLICY_VIEW_LOCAL_INFORMATION
,
411 qr
.in
.handle
= handle
;
412 qr
.in
.level
= LSA_POLICY_INFO_DNS
;
414 status
= dcerpc_lsa_QueryInfoPolicy2_r(p
->binding_handle
, tctx
, &qr
);
415 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_OK
,
416 "QueryInfoPolicy2 failed");
417 if (!NT_STATUS_IS_OK(qr
.out
.result
)) {
418 torture_comment(tctx
, "QueryInfoPolicy2 failed - %s\n",
419 nt_errstr(qr
.out
.result
));
423 cr
.in
.handle
= handle
;
424 cr
.out
.handle
= &closed_handle
;
425 status
= dcerpc_lsa_Close_r(p
->binding_handle
, tctx
, &cr
);
426 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_OK
,
428 if (!NT_STATUS_IS_OK(cr
.out
.result
)) {
429 torture_comment(tctx
, "Close failed - %s\n",
430 nt_errstr(cr
.out
.result
));
437 static bool delete_trusted_domain_by_sid(struct dcerpc_pipe
*p
,
438 struct torture_context
*tctx
,
439 struct dom_sid
*domsid
)
441 struct policy_handle
*handle
;
444 struct policy_handle closed_handle
;
445 struct lsa_DeleteTrustedDomain dr
;
448 torture_comment(tctx
, "\nDeleting trusted domain.\n");
450 /* Against a windows server it was sufficient to have
451 * LSA_POLICY_VIEW_LOCAL_INFORMATION although the documentations says
453 if (!test_get_policy_handle(tctx
, p
, LSA_POLICY_TRUST_ADMIN
,
458 dr
.in
.handle
= handle
;
459 dr
.in
.dom_sid
= domsid
;
461 torture_assert_ntstatus_ok(tctx
,
462 dcerpc_lsa_DeleteTrustedDomain_r(p
->binding_handle
, tctx
, &dr
),
463 "DeleteTrustedDomain failed");
464 if (!NT_STATUS_IS_OK(dr
.out
.result
)) {
465 torture_comment(tctx
, "DeleteTrustedDomain failed - %s\n",
466 nt_errstr(dr
.out
.result
));
470 cr
.in
.handle
= handle
;
471 cr
.out
.handle
= &closed_handle
;
472 status
= dcerpc_lsa_Close_r(p
->binding_handle
, tctx
, &cr
);
473 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_OK
,
475 if (!NT_STATUS_IS_OK(cr
.out
.result
)) {
476 torture_comment(tctx
, "Close failed - %s\n",
477 nt_errstr(cr
.out
.result
));
484 static const uint8_t my_blob
[] = {
485 0xa3,0x0b,0x32,0x45,0x8b,0x84,0x3b,0x01,0x68,0xe8,0x2b,0xbb,0x00,0x13,0x69,0x1f,
486 0x10,0x35,0x72,0xa9,0x4f,0x77,0xb7,0xeb,0x59,0x08,0x07,0xc3,0xe8,0x17,0x00,0xc5,
487 0xf2,0xa9,0x6d,0xb7,0x69,0x45,0x63,0x20,0xcb,0x44,0x44,0x22,0x02,0xe3,0x28,0x84,
488 0x9b,0xd5,0x43,0x6f,0x8d,0x36,0x9b,0x9b,0x3b,0x31,0x86,0x84,0x8b,0xf2,0x36,0xd4,
489 0xe8,0xc4,0xee,0x90,0x0c,0xcb,0x3e,0x11,0x2f,0x86,0xfe,0x87,0x6d,0xce,0xae,0x0c,
490 0x83,0xfb,0x21,0x22,0x6d,0x7f,0x5e,0x08,0x71,0x1a,0x35,0xf4,0x5a,0x76,0x9b,0xf7,
491 0x54,0x62,0xa5,0x4c,0xcd,0xf6,0xa5,0xb0,0x0b,0xc7,0x79,0xe1,0x6f,0x85,0x16,0x6f,
492 0x82,0xdd,0x15,0x11,0x4c,0x9d,0x26,0x01,0x74,0x7e,0xbb,0xec,0x88,0x1d,0x71,0x9e,
493 0x5f,0xb2,0x9c,0xab,0x66,0x20,0x08,0x3d,0xae,0x07,0x2d,0xbb,0xa6,0xfb,0xec,0xcc,
494 0x51,0x58,0x48,0x47,0x38,0x3b,0x47,0x66,0xe8,0x17,0xfa,0x54,0x5c,0x95,0x73,0x29,
495 0xdf,0x7e,0x4a,0xb4,0x45,0x30,0xf7,0xbf,0xc0,0x56,0x6d,0x80,0xf6,0x11,0x56,0x93,
496 0xeb,0x97,0xd5,0x10,0xd6,0xd6,0xf7,0x23,0xc3,0xc0,0x93,0xa7,0x5c,0xa9,0xc0,0x81,
497 0x55,0x3d,0xec,0x03,0x31,0x7e,0x9d,0xf9,0xd0,0x9e,0xb5,0xc7,0xef,0xa8,0x54,0xf6,
498 0x9c,0xdc,0x0d,0xd4,0xd7,0xee,0x8d,0x5f,0xbd,0x89,0x48,0x3b,0x63,0xff,0xe8,0xca,
499 0x10,0x64,0x61,0xdf,0xfd,0x50,0xff,0x51,0xa0,0x2c,0xd7,0x8a,0xf1,0x13,0x02,0x02,
500 0x71,0xe9,0xff,0x0d,0x03,0x48,0xf8,0x08,0x8d,0xd5,0xe6,0x31,0x9f,0xf0,0x26,0x07,
501 0x91,0x6d,0xd3,0x01,0x91,0x92,0xc7,0x28,0x18,0x58,0xd8,0xf6,0x1b,0x97,0x8d,0xd0,
502 0xd2,0xa1,0x7c,0xae,0xc1,0xca,0xfe,0x20,0x91,0x1c,0x4d,0x15,0x89,0x29,0x37,0xd5,
503 0xf5,0xca,0x40,0x2b,0x03,0x8f,0x7b,0xc2,0x10,0xb4,0xd3,0xe8,0x14,0xb0,0x9b,0x5d,
504 0x85,0x30,0xe5,0x13,0x24,0xf7,0x78,0xec,0xbe,0x0b,0x9a,0x3f,0xb5,0x76,0xd9,0x0d,
505 0x49,0x64,0xa4,0xa7,0x33,0x88,0xdd,0xe9,0xe2,0x5f,0x04,0x51,0xdd,0x89,0xe2,0x68,
506 0x5b,0x5f,0x64,0x35,0xe3,0x23,0x4a,0x0e,0x09,0x15,0xcc,0x97,0x47,0xf4,0xc2,0x4f,
507 0x06,0xc3,0x96,0xa9,0x2f,0xb3,0xde,0x29,0x10,0xc7,0xf5,0x16,0xc5,0x3c,0x84,0xd2,
508 0x9b,0x6b,0xaa,0x54,0x59,0x8d,0x94,0xde,0xd1,0x75,0xb6,0x08,0x0d,0x7d,0xf1,0x18,
509 0xc8,0xf5,0xdf,0xaa,0xcd,0xec,0xab,0xb6,0xd1,0xcb,0xdb,0xe7,0x75,0x5d,0xbe,0x76,
510 0xea,0x1d,0x01,0xc8,0x0b,0x2d,0x32,0xe9,0xa8,0x65,0xbb,0x4a,0xcb,0x72,0xbc,0xda,
511 0x04,0x7f,0x82,0xfb,0x04,0xeb,0xd8,0xe1,0xb9,0xb1,0x1e,0xdc,0xb3,0x60,0xf3,0x55,
512 0x1e,0xcf,0x90,0x6a,0x15,0x74,0x4d,0xff,0xb4,0xc7,0xc9,0xc2,0x4f,0x67,0x9e,0xeb,
513 0x00,0x61,0x02,0xe3,0x9e,0x59,0x88,0x20,0xf1,0x0c,0xbe,0xe0,0x26,0x69,0x63,0x67,
514 0x72,0x3c,0x06,0x00,0x9e,0x4f,0xc7,0xa6,0x4d,0x6c,0xbe,0x68,0x8e,0xf4,0x32,0x36,
515 0x2e,0x5f,0xa6,0xcf,0xa7,0x19,0x40,0x2b,0xbd,0xa2,0x22,0x73,0xc4,0xb6,0xe3,0x86,
516 0x64,0xeb,0xb1,0xc7,0x45,0x7d,0xd6,0xd9,0x36,0xf1,0x04,0xd4,0x61,0xdc,0x41,0xb7,
517 0x01,0x00,0x00,0x00,0x0c,0x00,0x00,0x00, 0x30,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
518 0x02,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0x31,0x00,0x32,0x00,0x33,0x00,0x34,0x00,
519 0x35,0x00,0x36,0x00,0x37,0x00,0x38,0x00,0x39,0x00,0x30,0x00,0x01,0x00,0x00,0x00,
520 0x0c,0x00,0x00,0x00, 0x30,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
521 0x14,0x00,0x00,0x00,0x31,0x00,0x32,0x00,0x33,0x00,0x34,0x00,0x35,0x00,0x36,0x00,
522 0x37,0x00,0x38,0x00,0x39,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x00,0x00
525 static bool get_trust_domain_passwords_auth_blob(TALLOC_CTX
*mem_ctx
,
526 const char *password
,
527 DATA_BLOB
*auth_blob
)
529 struct trustDomainPasswords auth_struct
;
530 struct AuthenticationInformation
*auth_info_array
;
531 enum ndr_err_code ndr_err
;
532 size_t converted_size
;
534 generate_random_buffer(auth_struct
.confounder
,
535 sizeof(auth_struct
.confounder
));
537 auth_info_array
= talloc_array(mem_ctx
,
538 struct AuthenticationInformation
, 1);
539 if (auth_info_array
== NULL
) {
543 auth_info_array
[0].AuthType
= TRUST_AUTH_TYPE_CLEAR
;
544 if (!convert_string_talloc(mem_ctx
, CH_UNIX
, CH_UTF16
, password
,
546 &auth_info_array
[0].AuthInfo
.clear
.password
,
551 auth_info_array
[0].AuthInfo
.clear
.size
= converted_size
;
553 auth_struct
.outgoing
.count
= 1;
554 auth_struct
.outgoing
.current
.count
= 1;
555 auth_struct
.outgoing
.current
.array
= auth_info_array
;
556 auth_struct
.outgoing
.previous
.count
= 0;
557 auth_struct
.outgoing
.previous
.array
= NULL
;
559 auth_struct
.incoming
.count
= 1;
560 auth_struct
.incoming
.current
.count
= 1;
561 auth_struct
.incoming
.current
.array
= auth_info_array
;
562 auth_struct
.incoming
.previous
.count
= 0;
563 auth_struct
.incoming
.previous
.array
= NULL
;
565 ndr_err
= ndr_push_struct_blob(auth_blob
, mem_ctx
, &auth_struct
,
566 (ndr_push_flags_fn_t
)ndr_push_trustDomainPasswords
);
567 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
574 static bool test_validate_trust(struct torture_context
*tctx
,
576 const char *trusting_dom_name
,
577 const char *trusting_dom_dns_name
,
578 const char *trusted_dom_name
,
579 const char *trusted_dom_dns_name
,
580 const char *trust_password
)
582 struct netr_ServerGetTrustInfo r
;
584 struct netr_Authenticator a
;
585 struct netr_Authenticator return_authenticator
;
586 struct samr_Password new_owf_password
;
587 struct samr_Password old_owf_password
;
588 struct netr_TrustInfo
*trust_info
;
590 struct netlogon_creds_CredentialState
*creds
;
593 struct cli_credentials
*credentials
;
594 struct dcerpc_binding
*b
;
595 struct dcerpc_pipe
*p
;
597 struct netr_GetForestTrustInformation fr
;
598 struct lsa_ForestTrustInformation
*forest_trust_info
;
600 struct samr_Password nt_hash
;
603 status
= dcerpc_parse_binding(tctx
, binding
, &b
);
604 torture_assert_ntstatus_ok(tctx
, status
, "Bad binding string");
606 credentials
= cli_credentials_init(tctx
);
607 if (credentials
== NULL
) {
611 dummy
= talloc_asprintf(tctx
, "%s$", trusted_dom_name
);
612 cli_credentials_set_username(credentials
, dummy
,
614 cli_credentials_set_domain(credentials
, trusting_dom_name
,
616 cli_credentials_set_realm(credentials
, trusting_dom_dns_name
,
618 cli_credentials_set_password(credentials
, trust_password
, CRED_SPECIFIED
);
619 cli_credentials_set_workstation(credentials
,
620 trusted_dom_name
, CRED_SPECIFIED
);
621 cli_credentials_set_secure_channel_type(credentials
, SEC_CHAN_DOMAIN
);
623 status
= dcerpc_pipe_connect_b(tctx
, &p
, b
,
624 &ndr_table_netlogon
, credentials
,
625 tctx
->ev
, tctx
->lp_ctx
);
627 if (NT_STATUS_IS_ERR(status
)) {
628 torture_comment(tctx
, "Failed to connect to remote server: %s with %s - %s\n",
630 cli_credentials_get_unparsed_name(credentials
, tctx
),
635 if (!test_SetupCredentials3(p
, tctx
, NETLOGON_NEG_AUTH2_ADS_FLAGS
| NETLOGON_NEG_SUPPORTS_AES
,
636 credentials
, &creds
)) {
637 torture_comment(tctx
, "test_SetupCredentials3 failed.\n");
641 netlogon_creds_client_authenticator(creds
, &a
);
643 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s",
644 dcerpc_server_name(p
));
645 r
.in
.account_name
= talloc_asprintf(tctx
, "%s$", trusted_dom_name
);
646 r
.in
.secure_channel_type
= cli_credentials_get_secure_channel_type(credentials
);
647 r
.in
.computer_name
= trusted_dom_name
;
648 r
.in
.credential
= &a
;
650 r
.out
.return_authenticator
= &return_authenticator
;
651 r
.out
.new_owf_password
= &new_owf_password
;
652 r
.out
.old_owf_password
= &old_owf_password
;
653 r
.out
.trust_info
= &trust_info
;
655 torture_assert_ntstatus_ok(tctx
,
656 dcerpc_netr_ServerGetTrustInfo_r(p
->binding_handle
, tctx
, &r
),
657 "ServerGetTrustInfo failed");
658 torture_assert_ntstatus_ok(tctx
, r
.out
.result
,
659 "ServerGetTrustInfo failed");
661 if (trust_info
->count
!= 1) {
662 torture_comment(tctx
, "Unexpected number of results, "
663 "expected %d, got %d.\n",
664 1, trust_info
->count
);
667 if (trust_info
->data
[0] != 0) {
668 torture_comment(tctx
, "Unexpected result, "
669 "expected %d, got %d.\n",
671 trust_info
->data
[0]);
675 E_md4hash(cli_credentials_get_password(credentials
), nt_hash
.hash
);
677 netlogon_creds_des_decrypt(creds
, &new_owf_password
);
679 dump_data(1, new_owf_password
.hash
, 16);
680 dump_data(1, nt_hash
.hash
, 16);
682 torture_assert_mem_equal(tctx
, new_owf_password
.hash
, nt_hash
.hash
, 16,
683 "received unexpected owf password\n");
685 netlogon_creds_client_authenticator(creds
, &a
);
687 fr
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s",
688 dcerpc_server_name(p
));
689 fr
.in
.computer_name
= trusted_dom_name
;
690 fr
.in
.credential
= &a
;
692 fr
.out
.return_authenticator
= &return_authenticator
;
693 fr
.out
.forest_trust_info
= &forest_trust_info
;
695 torture_assert_ntstatus_ok(tctx
,
696 dcerpc_netr_GetForestTrustInformation_r(p
->binding_handle
, tctx
, &fr
),
697 "netr_GetForestTrustInformation failed");
698 if (NT_STATUS_IS_ERR(fr
.out
.result
)) {
699 torture_comment(tctx
,
700 "netr_GetForestTrustInformation failed - %s.\n",
701 nt_errstr(fr
.out
.result
));
705 if (forest_trust_info
->count
!= 2) {
706 torture_comment(tctx
, "Unexpected number of results, "
707 "expected %d, got %d.\n", 2,
708 forest_trust_info
->count
);
711 for(i
= 0; i
< forest_trust_info
->count
; i
++) {
712 switch(forest_trust_info
->entries
[i
]->type
) {
713 case LSA_FOREST_TRUST_TOP_LEVEL_NAME
:
714 if (strcmp(forest_trust_info
->entries
[i
]->forest_trust_data
.top_level_name
.string
, trusting_dom_dns_name
) != 0) {
715 torture_comment(tctx
, "Unexpected result, "
716 "expected %s, got %s.\n",
717 trusting_dom_dns_name
,
718 forest_trust_info
->entries
[i
]->forest_trust_data
.top_level_name
.string
);
722 case LSA_FOREST_TRUST_DOMAIN_INFO
:
723 if (strcmp(forest_trust_info
->entries
[i
]->forest_trust_data
.domain_info
.netbios_domain_name
.string
, trusting_dom_name
) != 0) {
724 torture_comment(tctx
, "Unexpected result, "
725 "expected %s, got %s.\n",
726 trusting_dom_dns_name
,
727 forest_trust_info
->entries
[i
]->forest_trust_data
.domain_info
.netbios_domain_name
.string
);
730 if (strcmp(forest_trust_info
->entries
[i
]->forest_trust_data
.domain_info
.dns_domain_name
.string
, trusting_dom_dns_name
) != 0) {
731 torture_comment(tctx
, "Unexpected result, "
732 "expected %s, got %s.\n",
733 trusting_dom_dns_name
,
734 forest_trust_info
->entries
[i
]->forest_trust_data
.domain_info
.dns_domain_name
.string
);
739 torture_comment(tctx
, "Unexpected result type, "
740 "expected %d|%d, got %d.\n",
741 LSA_FOREST_TRUST_TOP_LEVEL_NAME
,
742 LSA_FOREST_TRUST_DOMAIN_INFO
,
743 forest_trust_info
->entries
[i
]->type
);
751 static bool test_setup_trust(struct torture_context
*tctx
,
752 struct dcerpc_pipe
*p
,
753 const char *netbios_name
,
754 const char *dns_name
,
756 DATA_BLOB
*auth_blob
)
759 DATA_BLOB session_key
;
760 struct lsa_TrustDomainInfoAuthInfoInternal authinfo
;
763 if (!check_name(p
, tctx
, netbios_name
)) {
766 if (!check_name(p
, tctx
, dns_name
)) {
770 status
= dcerpc_fetch_session_key(p
, &session_key
);
771 if (!NT_STATUS_IS_OK(status
)) {
772 torture_comment(tctx
, "dcerpc_fetch_session_key failed - %s\n",
777 authinfo
.auth_blob
.data
= talloc_memdup(tctx
, auth_blob
->data
,
779 if (authinfo
.auth_blob
.data
== NULL
) {
782 authinfo
.auth_blob
.size
= auth_blob
->length
;
784 arcfour_crypt_blob(authinfo
.auth_blob
.data
, authinfo
.auth_blob
.size
,
787 if (!test_create_trust_and_set_info(p
, tctx
, netbios_name
,
788 dns_name
, sid
, &authinfo
)) {
795 static bool testcase_ForestTrusts(struct torture_context
*tctx
,
796 struct dcerpc_pipe
*p
)
799 const char *dom2_binding_string
;
800 const char * dom2_cred_string
;
802 struct dom_sid
*domsid
;
804 struct dcerpc_binding
*dom2_binding
;
805 struct dcerpc_pipe
*dom2_p
;
806 struct cli_credentials
*dom2_credentials
;
807 union lsa_PolicyInformation
*dom1_info_dns
= NULL
;
808 union lsa_PolicyInformation
*dom2_info_dns
= NULL
;
809 const char *binding
= torture_setting_string(tctx
, "binding", NULL
);
812 torture_comment(tctx
, "Testing Forest Trusts\n");
814 test_password
= generate_random_password(tctx
, 32, 64);
815 torture_assert(tctx
, test_password
!= NULL
, "test password must be generated");
817 if (!get_trust_domain_passwords_auth_blob(tctx
, test_password
, &auth_blob
)) {
818 torture_comment(tctx
,
819 "get_trust_domain_passwords_auth_blob failed\n");
824 /* Use the following if get_trust_domain_passwords_auth_blob() cannot
825 * generate a usable blob due to errors in the IDL */
826 auth_blob
.data
= talloc_memdup(tctx
, my_blob
, sizeof(my_blob
));
827 auth_blob
.length
= sizeof(my_blob
);
829 test_password
= "1234567890"
832 domsid
= dom_sid_parse_talloc(tctx
, TEST_DOM_SID
);
833 if (domsid
== NULL
) {
837 if (!test_setup_trust(tctx
, p
, TEST_DOM
, TEST_DOM_DNS
, domsid
,
842 if (!get_lsa_policy_info_dns(p
, tctx
, &dom1_info_dns
)) {
846 if (!get_and_set_info(p
, tctx
, TEST_DOM
)) {
850 if (!test_validate_trust(tctx
, binding
,
851 dom1_info_dns
->dns
.name
.string
,
852 dom1_info_dns
->dns
.dns_domain
.string
,
853 TEST_DOM
, TEST_DOM_DNS
, test_password
)) {
857 if (!delete_trusted_domain_by_sid(p
, tctx
, domsid
)) {
861 dom2_binding_string
= torture_setting_string(tctx
,
862 "Forest_Trust_Dom2_Binding",
864 if (dom2_binding_string
== NULL
) {
868 status
= dcerpc_parse_binding(tctx
, dom2_binding_string
, &dom2_binding
);
869 if (NT_STATUS_IS_ERR(status
)) {
870 DEBUG(0,("Failed to parse dcerpc binding '%s'\n",
871 dom2_binding_string
));
875 dom2_cred_string
= torture_setting_string(tctx
,
876 "Forest_Trust_Dom2_Creds",
878 if (dom2_cred_string
== NULL
) {
882 dom2_credentials
= cli_credentials_init(tctx
);
883 if (dom2_credentials
== NULL
) {
887 cli_credentials_parse_string(dom2_credentials
, dom2_cred_string
,
889 cli_credentials_set_workstation(dom2_credentials
,
890 TEST_MACHINE_NAME
, CRED_SPECIFIED
);
892 status
= dcerpc_pipe_connect_b(tctx
, &dom2_p
, dom2_binding
,
893 &ndr_table_lsarpc
, dom2_credentials
,
894 tctx
->ev
, tctx
->lp_ctx
);
896 if (NT_STATUS_IS_ERR(status
)) {
897 torture_comment(tctx
, "Failed to connect to remote server: %s %s\n",
898 dcerpc_binding_string(tctx
, dom2_binding
),
903 if (!get_lsa_policy_info_dns(dom2_p
, tctx
, &dom2_info_dns
)) {
907 if (strcasecmp(dom1_info_dns
->dns
.name
.string
,
908 dom2_info_dns
->dns
.name
.string
) == 0 ||
909 strcasecmp(dom1_info_dns
->dns
.dns_domain
.string
,
910 dom2_info_dns
->dns
.dns_domain
.string
) == 0)
912 torture_comment(tctx
, "Trusting and trusted domain have the "
917 if (!test_setup_trust(tctx
, p
, dom2_info_dns
->dns
.name
.string
,
918 dom2_info_dns
->dns
.dns_domain
.string
,
919 dom2_info_dns
->dns
.sid
, &auth_blob
)) {
922 if (!test_setup_trust(tctx
, dom2_p
, dom1_info_dns
->dns
.name
.string
,
923 dom1_info_dns
->dns
.dns_domain
.string
,
924 dom1_info_dns
->dns
.sid
, &auth_blob
)) {
928 if (!test_validate_trust(tctx
, binding
,
929 dom1_info_dns
->dns
.name
.string
,
930 dom1_info_dns
->dns
.dns_domain
.string
,
931 dom2_info_dns
->dns
.name
.string
,
932 dom2_info_dns
->dns
.dns_domain
.string
, test_password
)) {
936 if (!test_validate_trust(tctx
, dom2_binding_string
,
937 dom2_info_dns
->dns
.name
.string
,
938 dom2_info_dns
->dns
.dns_domain
.string
,
939 dom1_info_dns
->dns
.name
.string
,
940 dom1_info_dns
->dns
.dns_domain
.string
, test_password
)) {
944 if (!delete_trusted_domain_by_sid(p
, tctx
, dom2_info_dns
->dns
.sid
)) {
948 if (!delete_trusted_domain_by_sid(dom2_p
, tctx
, dom1_info_dns
->dns
.sid
)) {
955 /* By default this test creates a trust object in the destination server to a
956 * dummy domain. If a second server from a different domain is specified on the
957 * command line a trust is created between those two domains.
960 * smbtorture ncacn_np:srv1.dom1.test[print] RPC-LSA-FOREST-TRUST \
961 * -U 'dom1\testadm1%12345678' \
962 * --option=torture:Forest_Trust_Dom2_Binding=ncacn_np:srv2.dom2.test[print] \
963 * --option=torture:Forest_Trust_Dom2_Creds='dom2\testadm2%12345678'
966 struct torture_suite
*torture_rpc_lsa_forest_trust(TALLOC_CTX
*mem_ctx
)
968 struct torture_suite
*suite
;
969 struct torture_rpc_tcase
*tcase
;
971 suite
= torture_suite_create(mem_ctx
, "lsa.forest.trust");
973 tcase
= torture_suite_add_rpc_iface_tcase(suite
, "lsa-forest-trust",
975 torture_rpc_tcase_add_test(tcase
, "ForestTrust", testcase_ForestTrusts
);