s4:torture/rpc: test the old password in test_validate_trust() for rpc.lsa.forest...
[Samba.git] / source4 / torture / rpc / forest_trust.c
blob7650462b6c905f672017f91fd0787540b3b454e3
1 /*
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/>.
23 #include "includes.h"
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,
43 uint32_t access_mask,
44 struct policy_handle **handle )
46 struct policy_handle *h;
47 struct lsa_OpenPolicy2 pr;
48 struct lsa_ObjectAttribute attr;
49 NTSTATUS status;
51 h = talloc(tctx, struct policy_handle);
52 torture_assert(tctx, h != NULL, "talloc(tctx, struct policy_handle)");
54 attr.len = 0;
55 attr.root_dir = NULL;
56 attr.object_name = NULL;
57 attr.attributes = 0;
58 attr.sec_desc = NULL;
59 attr.sec_qos = NULL;
61 pr.in.system_name = "\\";
62 pr.in.attr = &attr;
63 pr.in.access_mask = access_mask;
64 pr.out.handle = h;
66 status = dcerpc_lsa_OpenPolicy2_r(p->binding_handle, tctx, &pr);
67 torture_assert_ntstatus_ok(tctx, status, "OpenPolicy2 failed");
68 torture_assert_ntstatus_ok(tctx, pr.out.result, "OpenPolicy2 failed");
70 *handle = h;
71 return true;
74 static bool test_create_trust_and_set_info(struct dcerpc_pipe *p,
75 struct torture_context *tctx,
76 const char *trust_name,
77 const char *trust_name_dns,
78 struct dom_sid *domsid,
79 struct lsa_TrustDomainInfoAuthInfoInternal *authinfo)
81 struct policy_handle *handle;
82 struct lsa_lsaRSetForestTrustInformation fti;
83 struct lsa_ForestTrustCollisionInfo *collision_info = NULL;
84 struct lsa_Close cr;
85 struct policy_handle closed_handle;
86 struct lsa_CreateTrustedDomainEx2 r;
87 struct lsa_TrustDomainInfoInfoEx trustinfo;
88 struct policy_handle trustdom_handle;
89 struct lsa_QueryTrustedDomainInfo q;
90 union lsa_TrustedDomainInfo *info = NULL;
92 if (!test_get_policy_handle(tctx, p,
93 (LSA_POLICY_VIEW_LOCAL_INFORMATION |
94 LSA_POLICY_TRUST_ADMIN |
95 LSA_POLICY_CREATE_SECRET), &handle)) {
96 return false;
99 torture_comment(tctx, "\nTesting CreateTrustedDomainEx2\n");
101 trustinfo.sid = domsid;
102 trustinfo.netbios_name.string = trust_name;
103 trustinfo.domain_name.string = trust_name_dns;
105 trustinfo.trust_direction = LSA_TRUST_DIRECTION_INBOUND |
106 LSA_TRUST_DIRECTION_OUTBOUND;
108 trustinfo.trust_type = LSA_TRUST_TYPE_UPLEVEL;
111 * MS-LSAD: Section 3.1.4.7.10 makes it clear that Win2k3
112 * functional level and above return
113 * NT_STATUS_INVALID_DOMAIN_STATE if
114 * TRUST_ATTRIBUTE_FOREST_TRANSITIVE or
115 * TRUST_ATTRIBUTE_CROSS_ORGANIZATION is set here.
117 * But we really want to test forest trusts here.
119 trustinfo.trust_attributes = LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE;
121 r.in.policy_handle = handle;
122 r.in.info = &trustinfo;
123 r.in.auth_info_internal = authinfo;
124 /* LSA_TRUSTED_QUERY_DOMAIN_NAME is needed for for following
125 * QueryTrustedDomainInfo call, although it seems that Windows does not
126 * expect this */
127 r.in.access_mask = LSA_TRUSTED_SET_POSIX | LSA_TRUSTED_SET_AUTH | LSA_TRUSTED_QUERY_DOMAIN_NAME;
128 r.out.trustdom_handle = &trustdom_handle;
130 torture_assert_ntstatus_ok(tctx,
131 dcerpc_lsa_CreateTrustedDomainEx2_r(p->binding_handle, tctx, &r),
132 "CreateTrustedDomainEx2 failed");
133 torture_assert_ntstatus_ok(tctx, r.out.result, "CreateTrustedDomainEx2 failed");
135 q.in.trustdom_handle = &trustdom_handle;
136 q.in.level = LSA_TRUSTED_DOMAIN_INFO_INFO_EX;
137 q.out.info = &info;
139 torture_assert_ntstatus_ok(tctx,
140 dcerpc_lsa_QueryTrustedDomainInfo_r(p->binding_handle, tctx, &q),
141 "QueryTrustedDomainInfo failed");
142 torture_assert_ntstatus_ok(tctx, q.out.result, "QueryTrustedDomainInfo level 1");
143 torture_assert(tctx, q.out.info != NULL, "QueryTrustedDomainInfo level 1 failed to return an info pointer");
144 torture_assert_str_equal(tctx, info->info_ex.netbios_name.string,
145 trustinfo.netbios_name.string,
146 "QueryTrustedDomainInfo returned inconsistent short name");
147 torture_assert_int_equal(tctx, info->info_ex.trust_type, trustinfo.trust_type,
148 "QueryTrustedDomainInfo returned incorrect trust type");
149 torture_assert_int_equal(tctx, info->info_ex.trust_attributes, trustinfo.trust_attributes,
150 "QueryTrustedDomainInfo of returned incorrect trust attributes");
151 torture_assert_int_equal(tctx, info->info_ex.trust_direction, trustinfo.trust_direction,
152 "QueryTrustedDomainInfo of returned incorrect trust direction");
154 fti.in.handle = handle;
155 fti.in.trusted_domain_name = talloc_zero(tctx, struct lsa_StringLarge);
156 fti.in.trusted_domain_name->string = trust_name_dns;
157 fti.in.highest_record_type = 2;
158 fti.in.forest_trust_info = talloc_zero(tctx, struct lsa_ForestTrustInformation);
159 fti.in.forest_trust_info->count = 2;
160 fti.in.forest_trust_info->entries = talloc_array(tctx, struct lsa_ForestTrustRecord *, 2);
161 fti.in.forest_trust_info->entries[0] = talloc_zero(tctx, struct lsa_ForestTrustRecord);
162 fti.in.forest_trust_info->entries[0]->flags = 0;
163 fti.in.forest_trust_info->entries[0]->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
164 fti.in.forest_trust_info->entries[0]->time = 0;
165 fti.in.forest_trust_info->entries[0]->forest_trust_data.top_level_name.string = trust_name_dns;
166 fti.in.forest_trust_info->entries[1] = talloc_zero(tctx, struct lsa_ForestTrustRecord);
167 fti.in.forest_trust_info->entries[1]->flags = 0;
168 fti.in.forest_trust_info->entries[1]->type = LSA_FOREST_TRUST_DOMAIN_INFO;
169 fti.in.forest_trust_info->entries[1]->time = 0;
170 fti.in.forest_trust_info->entries[1]->forest_trust_data.domain_info.domain_sid = domsid;
171 fti.in.forest_trust_info->entries[1]->forest_trust_data.domain_info.dns_domain_name.string = trust_name_dns;
172 fti.in.forest_trust_info->entries[1]->forest_trust_data.domain_info.netbios_domain_name.string = trust_name;
173 fti.in.check_only = 0;
174 fti.out.collision_info = &collision_info;
176 torture_comment(tctx, "\nTesting SetForestTrustInformation\n");
178 torture_assert_ntstatus_ok(tctx,
179 dcerpc_lsa_lsaRSetForestTrustInformation_r(p->binding_handle, tctx, &fti),
180 "lsaRSetForestTrustInformation failed");
181 torture_assert_ntstatus_ok(tctx, fti.out.result, "lsaRSetForestTrustInformation failed");
183 cr.in.handle = handle;
184 cr.out.handle = &closed_handle;
185 torture_assert_ntstatus_ok(tctx,
186 dcerpc_lsa_Close_r(p->binding_handle, tctx, &cr),
187 "Close failed");
188 torture_assert_ntstatus_ok(tctx, cr.out.result, "Close failed");
190 return true;
193 struct get_set_info {
194 enum lsa_TrustDomInfoEnum info_level;
195 NTSTATUS get_result;
196 NTSTATUS set_result;
199 static bool get_and_set_info(struct dcerpc_pipe *p,
200 struct torture_context *tctx,
201 const char *name)
203 struct policy_handle *handle;
204 NTSTATUS status;
205 struct lsa_QueryTrustedDomainInfoByName qr;
206 struct lsa_SetTrustedDomainInfoByName sr;
207 union lsa_TrustedDomainInfo *info;
208 struct lsa_Close cr;
209 struct policy_handle closed_handle;
210 size_t c;
212 struct get_set_info il[] = {
213 {LSA_TRUSTED_DOMAIN_INFO_NAME, NT_STATUS_OK, NT_STATUS_INVALID_PARAMETER},
214 /* {LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS, NT_STATUS_INVALID_PARAMETER, NT_STATUS_INVALID_INFO_CLASS}, */
215 {LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET, NT_STATUS_OK, NT_STATUS_OK},
216 /* {LSA_TRUSTED_DOMAIN_INFO_PASSWORD, NT_STATUS_INVALID_PARAMETER, NT_STATUS_INVALID_INFO_CLASS}, */
217 /* {LSA_TRUSTED_DOMAIN_INFO_BASIC, NT_STATUS_INVALID_PARAMETER, NT_STATUS_INVALID_INFO_CLASS}, */
218 {LSA_TRUSTED_DOMAIN_INFO_INFO_EX, NT_STATUS_OK, NT_STATUS_OK},
219 /* {LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO, NT_STATUS_INVALID_PARAMETER, NT_STATUS_INVALID_INFO_CLASS}, */
220 {LSA_TRUSTED_DOMAIN_INFO_FULL_INFO, NT_STATUS_OK, NT_STATUS_OK},
221 /* {LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL, NT_STATUS_INVALID_PARAMETER, NT_STATUS_INVALID_INFO_CLASS}, */
222 /* {LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL, NT_STATUS_INVALID_PARAMETER, NT_STATUS_INVALID_INFO_CLASS}, */
223 /* {LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL, NT_STATUS_INVALID_PARAMETER, NT_STATUS_INVALID_INFO_CLASS}, */
224 {LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL, NT_STATUS_OK, NT_STATUS_INVALID_PARAMETER},
225 {LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES, NT_STATUS_OK, NT_STATUS_OK},
226 {-1, NT_STATUS_OK}
229 torture_comment(tctx, "\nGetting/Setting dom info\n");
231 if(!test_get_policy_handle(tctx, p, LSA_POLICY_VIEW_LOCAL_INFORMATION,
232 &handle)) {
233 return false;
236 qr.in.handle = handle;
237 qr.in.trusted_domain = talloc_zero(tctx, struct lsa_String);
238 qr.in.trusted_domain->string = name;
239 qr.out.info = &info;
241 sr.in.handle = handle;
242 sr.in.trusted_domain = talloc_zero(tctx, struct lsa_String);
243 sr.in.trusted_domain->string = name;
244 sr.in.info = info;
246 for (c = 0; il[c].info_level != -1; c++) {
247 torture_comment(tctx, "\nGetting/Setting dom info [%d]\n",il[c].info_level);
249 qr.in.level = il[c].info_level;
250 status = dcerpc_lsa_QueryTrustedDomainInfoByName_r(p->binding_handle,
251 tctx, &qr);
252 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OK,
253 "QueryTrustedDomainInfoByName failed");
254 if (!NT_STATUS_EQUAL(qr.out.result, il[c].get_result)) {
255 torture_comment(tctx, "QueryTrustedDomainInfoByName did not return "
256 "%s but %s\n",
257 nt_errstr(il[c].get_result),
258 nt_errstr(qr.out.result));
260 /* We may be testing a server without support for this level */
261 if (qr.in.level == LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES && NT_STATUS_EQUAL(qr.out.result, NT_STATUS_INVALID_PARAMETER)) {
262 return true;
264 return false;
267 sr.in.level = il[c].info_level;
268 sr.in.info = info;
269 status = dcerpc_lsa_SetTrustedDomainInfoByName_r(p->binding_handle,
270 tctx, &sr);
271 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OK,
272 "SetTrustedDomainInfoByName failed");
273 if (!NT_STATUS_EQUAL(sr.out.result, il[c].set_result)) {
274 torture_comment(tctx, "SetTrustedDomainInfoByName did not return "
275 "%s but %s\n",
276 nt_errstr(il[c].set_result),
277 nt_errstr(sr.out.result));
278 return false;
282 cr.in.handle = handle;
283 cr.out.handle = &closed_handle;
284 torture_assert_ntstatus_ok(tctx,
285 dcerpc_lsa_Close_r(p->binding_handle, tctx, &cr),
286 "Close failed");
287 torture_assert_ntstatus_ok(tctx, cr.out.result, "Close failed");
289 return true;
292 static bool check_name(struct dcerpc_pipe *p, struct torture_context *tctx,
293 const char *name)
295 struct policy_handle *handle;
296 NTSTATUS status;
297 struct lsa_QueryTrustedDomainInfoByName qr;
298 union lsa_TrustedDomainInfo *info;
299 struct lsa_Close cr;
300 struct policy_handle closed_handle;
302 torture_comment(tctx, "\nGetting LSA_TRUSTED_DOMAIN_INFO_FULL_INFO\n");
304 if(!test_get_policy_handle(tctx, p, LSA_POLICY_VIEW_LOCAL_INFORMATION,
305 &handle)) {
306 return false;
309 qr.in.handle = handle;
310 qr.in.trusted_domain = talloc_zero(tctx, struct lsa_String);
311 qr.in.trusted_domain->string = name;
312 qr.in.level = LSA_TRUSTED_DOMAIN_INFO_FULL_INFO;
313 qr.out.info = &info;
314 status = dcerpc_lsa_QueryTrustedDomainInfoByName_r(p->binding_handle,
315 tctx, &qr);
316 torture_assert_ntstatus_ok(tctx, status,
317 "QueryInfoPolicy2 failed");
318 torture_assert_ntstatus_equal(tctx, qr.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND,
319 "QueryInfoPolicy2 did not return "
320 "NT_STATUS_OBJECT_NAME_NOT_FOUND");
322 cr.in.handle = handle;
323 cr.out.handle = &closed_handle;
324 torture_assert_ntstatus_ok(tctx,
325 dcerpc_lsa_Close_r(p->binding_handle, tctx, &cr),
326 "Close failed");
327 torture_assert_ntstatus_ok(tctx, cr.out.result, "Close failed");
329 return true;
332 static bool get_lsa_policy_info_dns(struct dcerpc_pipe *p,
333 struct torture_context *tctx,
334 union lsa_PolicyInformation **info)
336 struct policy_handle *handle;
337 NTSTATUS status;
338 struct lsa_QueryInfoPolicy2 qr;
339 struct lsa_Close cr;
340 struct policy_handle closed_handle;
342 torture_comment(tctx, "\nGetting LSA_POLICY_INFO_DNS\n");
344 if (!test_get_policy_handle(tctx, p, LSA_POLICY_VIEW_LOCAL_INFORMATION,
345 &handle)) {
346 return false;
349 qr.in.handle = handle;
350 qr.in.level = LSA_POLICY_INFO_DNS;
351 qr.out.info = info;
352 status = dcerpc_lsa_QueryInfoPolicy2_r(p->binding_handle, tctx, &qr);
353 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OK,
354 "QueryInfoPolicy2 failed");
355 if (!NT_STATUS_IS_OK(qr.out.result)) {
356 torture_comment(tctx, "QueryInfoPolicy2 failed - %s\n",
357 nt_errstr(qr.out.result));
358 return false;
361 cr.in.handle = handle;
362 cr.out.handle = &closed_handle;
363 torture_assert_ntstatus_ok(tctx,
364 dcerpc_lsa_Close_r(p->binding_handle, tctx, &cr),
365 "Close failed");
366 torture_assert_ntstatus_ok(tctx, cr.out.result, "Close failed");
368 return true;
371 static bool delete_trusted_domain_by_sid(struct dcerpc_pipe *p,
372 struct torture_context *tctx,
373 struct dom_sid *domsid)
375 struct policy_handle *handle;
376 struct lsa_Close cr;
377 struct policy_handle closed_handle;
378 struct lsa_DeleteTrustedDomain dr;
380 torture_comment(tctx, "\nDeleting trusted domain.\n");
382 /* Against a windows server it was sufficient to have
383 * LSA_POLICY_VIEW_LOCAL_INFORMATION although the documentations says
384 * otherwise. */
385 if (!test_get_policy_handle(tctx, p, LSA_POLICY_TRUST_ADMIN,
386 &handle)) {
387 return false;
390 dr.in.handle = handle;
391 dr.in.dom_sid = domsid;
393 torture_assert_ntstatus_ok(tctx,
394 dcerpc_lsa_DeleteTrustedDomain_r(p->binding_handle, tctx, &dr),
395 "DeleteTrustedDomain failed");
396 torture_assert_ntstatus_ok(tctx, dr.out.result, "DeleteTrustedDomain failed");
398 cr.in.handle = handle;
399 cr.out.handle = &closed_handle;
400 torture_assert_ntstatus_ok(tctx,
401 dcerpc_lsa_Close_r(p->binding_handle, tctx, &cr),
402 "Close failed");
403 torture_assert_ntstatus_ok(tctx, cr.out.result, "Close failed");
405 return true;
408 static const uint8_t my_blob[] = {
409 0xa3,0x0b,0x32,0x45,0x8b,0x84,0x3b,0x01,0x68,0xe8,0x2b,0xbb,0x00,0x13,0x69,0x1f,
410 0x10,0x35,0x72,0xa9,0x4f,0x77,0xb7,0xeb,0x59,0x08,0x07,0xc3,0xe8,0x17,0x00,0xc5,
411 0xf2,0xa9,0x6d,0xb7,0x69,0x45,0x63,0x20,0xcb,0x44,0x44,0x22,0x02,0xe3,0x28,0x84,
412 0x9b,0xd5,0x43,0x6f,0x8d,0x36,0x9b,0x9b,0x3b,0x31,0x86,0x84,0x8b,0xf2,0x36,0xd4,
413 0xe8,0xc4,0xee,0x90,0x0c,0xcb,0x3e,0x11,0x2f,0x86,0xfe,0x87,0x6d,0xce,0xae,0x0c,
414 0x83,0xfb,0x21,0x22,0x6d,0x7f,0x5e,0x08,0x71,0x1a,0x35,0xf4,0x5a,0x76,0x9b,0xf7,
415 0x54,0x62,0xa5,0x4c,0xcd,0xf6,0xa5,0xb0,0x0b,0xc7,0x79,0xe1,0x6f,0x85,0x16,0x6f,
416 0x82,0xdd,0x15,0x11,0x4c,0x9d,0x26,0x01,0x74,0x7e,0xbb,0xec,0x88,0x1d,0x71,0x9e,
417 0x5f,0xb2,0x9c,0xab,0x66,0x20,0x08,0x3d,0xae,0x07,0x2d,0xbb,0xa6,0xfb,0xec,0xcc,
418 0x51,0x58,0x48,0x47,0x38,0x3b,0x47,0x66,0xe8,0x17,0xfa,0x54,0x5c,0x95,0x73,0x29,
419 0xdf,0x7e,0x4a,0xb4,0x45,0x30,0xf7,0xbf,0xc0,0x56,0x6d,0x80,0xf6,0x11,0x56,0x93,
420 0xeb,0x97,0xd5,0x10,0xd6,0xd6,0xf7,0x23,0xc3,0xc0,0x93,0xa7,0x5c,0xa9,0xc0,0x81,
421 0x55,0x3d,0xec,0x03,0x31,0x7e,0x9d,0xf9,0xd0,0x9e,0xb5,0xc7,0xef,0xa8,0x54,0xf6,
422 0x9c,0xdc,0x0d,0xd4,0xd7,0xee,0x8d,0x5f,0xbd,0x89,0x48,0x3b,0x63,0xff,0xe8,0xca,
423 0x10,0x64,0x61,0xdf,0xfd,0x50,0xff,0x51,0xa0,0x2c,0xd7,0x8a,0xf1,0x13,0x02,0x02,
424 0x71,0xe9,0xff,0x0d,0x03,0x48,0xf8,0x08,0x8d,0xd5,0xe6,0x31,0x9f,0xf0,0x26,0x07,
425 0x91,0x6d,0xd3,0x01,0x91,0x92,0xc7,0x28,0x18,0x58,0xd8,0xf6,0x1b,0x97,0x8d,0xd0,
426 0xd2,0xa1,0x7c,0xae,0xc1,0xca,0xfe,0x20,0x91,0x1c,0x4d,0x15,0x89,0x29,0x37,0xd5,
427 0xf5,0xca,0x40,0x2b,0x03,0x8f,0x7b,0xc2,0x10,0xb4,0xd3,0xe8,0x14,0xb0,0x9b,0x5d,
428 0x85,0x30,0xe5,0x13,0x24,0xf7,0x78,0xec,0xbe,0x0b,0x9a,0x3f,0xb5,0x76,0xd9,0x0d,
429 0x49,0x64,0xa4,0xa7,0x33,0x88,0xdd,0xe9,0xe2,0x5f,0x04,0x51,0xdd,0x89,0xe2,0x68,
430 0x5b,0x5f,0x64,0x35,0xe3,0x23,0x4a,0x0e,0x09,0x15,0xcc,0x97,0x47,0xf4,0xc2,0x4f,
431 0x06,0xc3,0x96,0xa9,0x2f,0xb3,0xde,0x29,0x10,0xc7,0xf5,0x16,0xc5,0x3c,0x84,0xd2,
432 0x9b,0x6b,0xaa,0x54,0x59,0x8d,0x94,0xde,0xd1,0x75,0xb6,0x08,0x0d,0x7d,0xf1,0x18,
433 0xc8,0xf5,0xdf,0xaa,0xcd,0xec,0xab,0xb6,0xd1,0xcb,0xdb,0xe7,0x75,0x5d,0xbe,0x76,
434 0xea,0x1d,0x01,0xc8,0x0b,0x2d,0x32,0xe9,0xa8,0x65,0xbb,0x4a,0xcb,0x72,0xbc,0xda,
435 0x04,0x7f,0x82,0xfb,0x04,0xeb,0xd8,0xe1,0xb9,0xb1,0x1e,0xdc,0xb3,0x60,0xf3,0x55,
436 0x1e,0xcf,0x90,0x6a,0x15,0x74,0x4d,0xff,0xb4,0xc7,0xc9,0xc2,0x4f,0x67,0x9e,0xeb,
437 0x00,0x61,0x02,0xe3,0x9e,0x59,0x88,0x20,0xf1,0x0c,0xbe,0xe0,0x26,0x69,0x63,0x67,
438 0x72,0x3c,0x06,0x00,0x9e,0x4f,0xc7,0xa6,0x4d,0x6c,0xbe,0x68,0x8e,0xf4,0x32,0x36,
439 0x2e,0x5f,0xa6,0xcf,0xa7,0x19,0x40,0x2b,0xbd,0xa2,0x22,0x73,0xc4,0xb6,0xe3,0x86,
440 0x64,0xeb,0xb1,0xc7,0x45,0x7d,0xd6,0xd9,0x36,0xf1,0x04,0xd4,0x61,0xdc,0x41,0xb7,
441 0x01,0x00,0x00,0x00,0x0c,0x00,0x00,0x00, 0x30,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
442 0x02,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0x31,0x00,0x32,0x00,0x33,0x00,0x34,0x00,
443 0x35,0x00,0x36,0x00,0x37,0x00,0x38,0x00,0x39,0x00,0x30,0x00,0x01,0x00,0x00,0x00,
444 0x0c,0x00,0x00,0x00, 0x30,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
445 0x14,0x00,0x00,0x00,0x31,0x00,0x32,0x00,0x33,0x00,0x34,0x00,0x35,0x00,0x36,0x00,
446 0x37,0x00,0x38,0x00,0x39,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x00,0x00
449 static bool get_trust_domain_passwords_auth_blob(TALLOC_CTX *mem_ctx,
450 const char *password,
451 DATA_BLOB *auth_blob)
453 struct trustDomainPasswords auth_struct;
454 struct AuthenticationInformation *auth_info_array;
455 enum ndr_err_code ndr_err;
456 size_t converted_size;
458 generate_random_buffer(auth_struct.confounder,
459 sizeof(auth_struct.confounder));
461 auth_info_array = talloc_array(mem_ctx,
462 struct AuthenticationInformation, 1);
463 if (auth_info_array == NULL) {
464 return false;
467 auth_info_array[0].AuthType = TRUST_AUTH_TYPE_CLEAR;
468 if (!convert_string_talloc(mem_ctx, CH_UNIX, CH_UTF16, password,
469 strlen(password),
470 &auth_info_array[0].AuthInfo.clear.password,
471 &converted_size)) {
472 return false;
475 auth_info_array[0].AuthInfo.clear.size = converted_size;
477 auth_struct.outgoing.count = 1;
478 auth_struct.outgoing.current.count = 1;
479 auth_struct.outgoing.current.array = auth_info_array;
480 auth_struct.outgoing.previous.count = 0;
481 auth_struct.outgoing.previous.array = NULL;
483 auth_struct.incoming.count = 1;
484 auth_struct.incoming.current.count = 1;
485 auth_struct.incoming.current.array = auth_info_array;
486 auth_struct.incoming.previous.count = 0;
487 auth_struct.incoming.previous.array = NULL;
489 ndr_err = ndr_push_struct_blob(auth_blob, mem_ctx, &auth_struct,
490 (ndr_push_flags_fn_t)ndr_push_trustDomainPasswords);
491 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
492 return false;
495 return true;
498 static bool test_validate_trust(struct torture_context *tctx,
499 const char *binding,
500 const char *trusting_dom_name,
501 const char *trusting_dom_dns_name,
502 const char *trusted_dom_name,
503 const char *trusted_dom_dns_name,
504 const char *trust_password)
506 struct netr_ServerGetTrustInfo r;
508 struct netr_Authenticator a;
509 struct netr_Authenticator return_authenticator;
510 struct samr_Password new_owf_password;
511 struct samr_Password old_owf_password;
512 struct netr_TrustInfo *trust_info;
514 struct netlogon_creds_CredentialState *creds;
516 NTSTATUS status;
517 struct cli_credentials *credentials;
518 struct dcerpc_binding *b;
519 struct dcerpc_pipe *p;
521 struct netr_GetForestTrustInformation fr;
522 struct lsa_ForestTrustInformation *forest_trust_info;
523 struct lsa_ForestTrustRecord *tln = NULL;
524 struct lsa_ForestTrustRecord *di = NULL;
525 int i;
526 struct samr_Password *new_nt_hash;
527 struct samr_Password *old_nt_hash;
528 char *dummy;
529 uint32_t trust_attributes = LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE;
531 status = dcerpc_parse_binding(tctx, binding, &b);
532 torture_assert_ntstatus_ok(tctx, status, "Bad binding string");
534 credentials = cli_credentials_init(tctx);
535 torture_assert(tctx, credentials != NULL, "cli_credentials_init()");
537 dummy = talloc_asprintf(tctx, "%s$", trusted_dom_name);
538 cli_credentials_set_username(credentials, dummy,
539 CRED_SPECIFIED);
540 cli_credentials_set_domain(credentials, trusting_dom_name,
541 CRED_SPECIFIED);
542 cli_credentials_set_realm(credentials, trusting_dom_dns_name,
543 CRED_SPECIFIED);
544 cli_credentials_set_password(credentials, trust_password, CRED_SPECIFIED);
545 cli_credentials_set_old_password(credentials, trust_password, CRED_SPECIFIED);
546 cli_credentials_set_workstation(credentials,
547 trusted_dom_name, CRED_SPECIFIED);
548 cli_credentials_set_secure_channel_type(credentials, SEC_CHAN_DOMAIN);
550 status = dcerpc_pipe_connect_b(tctx, &p, b,
551 &ndr_table_netlogon, credentials,
552 tctx->ev, tctx->lp_ctx);
554 if (NT_STATUS_IS_ERR(status)) {
555 torture_comment(tctx, "Failed to connect to remote server: %s with %s - %s\n",
556 binding,
557 cli_credentials_get_unparsed_name(credentials, tctx),
558 nt_errstr(status));
559 return false;
562 if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES,
563 credentials, &creds)) {
564 torture_comment(tctx, "test_SetupCredentials3 failed.\n");
565 return false;
568 netlogon_creds_client_authenticator(creds, &a);
570 r.in.server_name = talloc_asprintf(tctx, "\\\\%s",
571 dcerpc_server_name(p));
572 r.in.account_name = talloc_asprintf(tctx, "%s$", trusted_dom_name);
573 r.in.secure_channel_type = cli_credentials_get_secure_channel_type(credentials);
574 r.in.computer_name = trusted_dom_name;
575 r.in.credential = &a;
577 r.out.return_authenticator = &return_authenticator;
578 r.out.new_owf_password = &new_owf_password;
579 r.out.old_owf_password = &old_owf_password;
580 r.out.trust_info = &trust_info;
582 torture_assert_ntstatus_ok(tctx,
583 dcerpc_netr_ServerGetTrustInfo_r(p->binding_handle, tctx, &r),
584 "ServerGetTrustInfo failed");
585 torture_assert_ntstatus_ok(tctx, r.out.result,
586 "ServerGetTrustInfo failed");
588 torture_assert(tctx, trust_info != NULL, "ServerGetTrustInfo got no trust_info");
589 torture_assert_int_equal(tctx, trust_info->count, 1,
590 "Unexpected number of results");
591 torture_assert_int_equal(tctx, trust_info->data[0], trust_attributes,
592 "Unexpected trust_attributes");
594 new_nt_hash = cli_credentials_get_nt_hash(credentials, tctx);
595 torture_assert(tctx, new_nt_hash != NULL, "cli_credentials_get_nt_hash()");
597 old_nt_hash = cli_credentials_get_old_nt_hash(credentials, tctx);
598 torture_assert(tctx, old_nt_hash != NULL, "cli_credentials_get_old_nt_hash()");
600 netlogon_creds_des_decrypt(creds, &new_owf_password);
601 netlogon_creds_des_decrypt(creds, &old_owf_password);
603 dump_data(1, new_owf_password.hash, 16);
604 dump_data(1, new_nt_hash->hash, 16);
605 dump_data(1, old_owf_password.hash, 16);
606 dump_data(1, old_nt_hash->hash, 16);
608 torture_assert_mem_equal(tctx, new_owf_password.hash, new_nt_hash->hash, 16,
609 "received unexpected new owf password\n");
611 torture_assert_mem_equal(tctx, old_owf_password.hash, old_nt_hash->hash, 16,
612 "received unexpected old owf password\n");
614 netlogon_creds_client_authenticator(creds, &a);
616 fr.in.server_name = talloc_asprintf(tctx, "\\\\%s",
617 dcerpc_server_name(p));
618 fr.in.computer_name = trusted_dom_name;
619 fr.in.credential = &a;
620 fr.in.flags = 0;
621 fr.out.return_authenticator = &return_authenticator;
622 fr.out.forest_trust_info = &forest_trust_info;
624 torture_assert_ntstatus_ok(tctx,
625 dcerpc_netr_GetForestTrustInformation_r(p->binding_handle, tctx, &fr),
626 "netr_GetForestTrustInformation failed");
627 torture_assert_ntstatus_ok(tctx, r.out.result,
628 "netr_GetForestTrustInformation failed");
630 for(i = 0; i < forest_trust_info->count; i++) {
631 struct lsa_ForestTrustRecord *e = forest_trust_info->entries[i];
633 switch (e->type) {
634 case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
635 if (strcmp(e->forest_trust_data.top_level_name.string, trusting_dom_dns_name) != 0) {
636 break;
639 torture_assert(tctx, tln == NULL, "TOP_LEVEL_NAME found twice");
641 tln = e;
642 break;
644 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
645 break;
647 case LSA_FOREST_TRUST_DOMAIN_INFO:
648 if (strcmp(e->forest_trust_data.domain_info.dns_domain_name.string, trusting_dom_dns_name) != 0) {
649 break;
652 torture_assert(tctx, di == NULL, "DOMAIN_INFO found twice");
654 di = e;
655 break;
656 default:
657 torture_assert_int_equal(tctx, e->type, LSA_FOREST_TRUST_TOP_LEVEL_NAME,
658 "Unexptected LSA_FOREST_TRUST_* type");
662 torture_assert(tctx, tln != NULL, "TOP_LEVEL_NAME entry missing");
663 torture_assert(tctx, di != NULL, "DOMAIN_INFO entry missing");
665 torture_assert_str_equal(tctx, di->forest_trust_data.domain_info.netbios_domain_name.string,
666 trusting_dom_name,
667 "netbios_domain_name mismatch");
669 return true;
672 static bool test_setup_trust(struct torture_context *tctx,
673 struct dcerpc_pipe *p,
674 const char *netbios_name,
675 const char *dns_name,
676 struct dom_sid *sid,
677 DATA_BLOB *auth_blob)
680 DATA_BLOB session_key;
681 struct lsa_TrustDomainInfoAuthInfoInternal authinfo;
682 NTSTATUS status;
684 if (!check_name(p, tctx, netbios_name)) {
685 return false;
687 if (!check_name(p, tctx, dns_name)) {
688 return false;
691 status = dcerpc_fetch_session_key(p, &session_key);
692 if (!NT_STATUS_IS_OK(status)) {
693 torture_comment(tctx, "dcerpc_fetch_session_key failed - %s\n",
694 nt_errstr(status));
695 return false;
698 authinfo.auth_blob.data = talloc_memdup(tctx, auth_blob->data,
699 auth_blob->length);
700 if (authinfo.auth_blob.data == NULL) {
701 return false;
703 authinfo.auth_blob.size = auth_blob->length;
705 arcfour_crypt_blob(authinfo.auth_blob.data, authinfo.auth_blob.size,
706 &session_key);
708 if (!test_create_trust_and_set_info(p, tctx, netbios_name,
709 dns_name, sid, &authinfo)) {
710 return false;
713 return true;
716 static bool testcase_ForestTrusts(struct torture_context *tctx,
717 struct dcerpc_pipe *p)
719 const char *dom2_binding_string;
720 const char * dom2_cred_string;
721 NTSTATUS status;
722 struct dom_sid *domsid;
723 DATA_BLOB auth_blob;
724 struct dcerpc_binding *dom2_binding;
725 struct dcerpc_pipe *dom2_p;
726 struct cli_credentials *dom2_credentials;
727 union lsa_PolicyInformation *dom1_info_dns = NULL;
728 union lsa_PolicyInformation *dom2_info_dns = NULL;
729 const char *binding = torture_setting_string(tctx, "binding", NULL);
730 char *test_password;
732 torture_comment(tctx, "Testing Forest Trusts\n");
734 test_password = generate_random_password(tctx, 32, 64);
735 torture_assert(tctx, test_password != NULL, "test password must be generated");
737 if (!get_trust_domain_passwords_auth_blob(tctx, test_password, &auth_blob)) {
738 torture_comment(tctx,
739 "get_trust_domain_passwords_auth_blob failed\n");
740 return false;
743 #if 0
744 /* Use the following if get_trust_domain_passwords_auth_blob() cannot
745 * generate a usable blob due to errors in the IDL */
746 auth_blob.data = talloc_memdup(tctx, my_blob, sizeof(my_blob));
747 auth_blob.length = sizeof(my_blob);
749 test_password = "1234567890"
750 #endif
752 domsid = dom_sid_parse_talloc(tctx, TEST_DOM_SID);
753 if (domsid == NULL) {
754 return false;
757 if (!test_setup_trust(tctx, p, TEST_DOM, TEST_DOM_DNS, domsid,
758 &auth_blob)) {
759 return false;
762 if (!get_lsa_policy_info_dns(p, tctx, &dom1_info_dns)) {
763 return false;
766 if (!get_and_set_info(p, tctx, TEST_DOM)) {
767 return false;
770 if (!test_validate_trust(tctx, binding,
771 dom1_info_dns->dns.name.string,
772 dom1_info_dns->dns.dns_domain.string,
773 TEST_DOM, TEST_DOM_DNS, test_password)) {
774 return false;
777 if (!delete_trusted_domain_by_sid(p, tctx, domsid)) {
778 return false;
781 dom2_binding_string = torture_setting_string(tctx,
782 "Forest_Trust_Dom2_Binding",
783 NULL);
784 if (dom2_binding_string == NULL) {
785 return true;
788 status = dcerpc_parse_binding(tctx, dom2_binding_string, &dom2_binding);
789 torture_assert_ntstatus_ok(tctx, status, "dcerpc_parse_binding()");
791 dom2_cred_string = torture_setting_string(tctx,
792 "Forest_Trust_Dom2_Creds",
793 NULL);
794 torture_assert(tctx, dom2_cred_string != NULL, "torture:Forest_Trust_Dom2_Creds missing");
796 dom2_credentials = cli_credentials_init(tctx);
797 torture_assert(tctx, dom2_credentials != NULL, "cli_credentials_init()");
799 cli_credentials_parse_string(dom2_credentials, dom2_cred_string,
800 CRED_SPECIFIED);
801 cli_credentials_set_workstation(dom2_credentials,
802 TEST_MACHINE_NAME, CRED_SPECIFIED);
804 status = dcerpc_pipe_connect_b(tctx, &dom2_p, dom2_binding,
805 &ndr_table_lsarpc, dom2_credentials,
806 tctx->ev, tctx->lp_ctx);
807 torture_assert_ntstatus_ok(tctx, status, talloc_asprintf(tctx,
808 "Failed to connect to remote server: %s\n",
809 dcerpc_binding_string(tctx, dom2_binding)));
811 if (!get_lsa_policy_info_dns(dom2_p, tctx, &dom2_info_dns)) {
812 return false;
815 if (strcasecmp(dom1_info_dns->dns.name.string,
816 dom2_info_dns->dns.name.string) == 0 ||
817 strcasecmp(dom1_info_dns->dns.dns_domain.string,
818 dom2_info_dns->dns.dns_domain.string) == 0)
820 torture_assert(tctx, false, talloc_asprintf(tctx,
821 "Trusting (%s;%s) and trusted domain (%s;%s) have the "
822 "same name",
823 dom1_info_dns->dns.name.string,
824 dom1_info_dns->dns.dns_domain.string,
825 dom2_info_dns->dns.name.string,
826 dom2_info_dns->dns.dns_domain.string));
829 if (!test_setup_trust(tctx, p, dom2_info_dns->dns.name.string,
830 dom2_info_dns->dns.dns_domain.string,
831 dom2_info_dns->dns.sid, &auth_blob)) {
832 return false;
834 if (!test_setup_trust(tctx, dom2_p, dom1_info_dns->dns.name.string,
835 dom1_info_dns->dns.dns_domain.string,
836 dom1_info_dns->dns.sid, &auth_blob)) {
837 return false;
840 if (!test_validate_trust(tctx, binding,
841 dom1_info_dns->dns.name.string,
842 dom1_info_dns->dns.dns_domain.string,
843 dom2_info_dns->dns.name.string,
844 dom2_info_dns->dns.dns_domain.string, test_password)) {
845 return false;
848 if (!test_validate_trust(tctx, dom2_binding_string,
849 dom2_info_dns->dns.name.string,
850 dom2_info_dns->dns.dns_domain.string,
851 dom1_info_dns->dns.name.string,
852 dom1_info_dns->dns.dns_domain.string, test_password)) {
853 return false;
856 if (!delete_trusted_domain_by_sid(p, tctx, dom2_info_dns->dns.sid)) {
857 return false;
860 if (!delete_trusted_domain_by_sid(dom2_p, tctx, dom1_info_dns->dns.sid)) {
861 return false;
864 return true;
867 /* By default this test creates a trust object in the destination server to a
868 * dummy domain. If a second server from a different domain is specified on the
869 * command line a trust is created between those two domains.
871 * Example:
872 * smbtorture ncacn_np:srv1.dom1.test[print] RPC-LSA-FOREST-TRUST \
873 * -U 'dom1\testadm1%12345678' \
874 * --option=torture:Forest_Trust_Dom2_Binding=ncacn_np:srv2.dom2.test[print] \
875 * --option=torture:Forest_Trust_Dom2_Creds='dom2\testadm2%12345678'
878 struct torture_suite *torture_rpc_lsa_forest_trust(TALLOC_CTX *mem_ctx)
880 struct torture_suite *suite;
881 struct torture_rpc_tcase *tcase;
883 suite = torture_suite_create(mem_ctx, "lsa.forest.trust");
885 tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa-forest-trust",
886 &ndr_table_lsarpc);
887 torture_rpc_tcase_add_test(tcase, "ForestTrust", testcase_ForestTrusts);
889 return suite;