s4-smbtorture: Make test names lowercase and dot-separated.
[sfrench/samba-autobuild/.git] / source4 / torture / rpc / forest_trust.c
1 /*
2    Unix SMB/CIFS implementation.
3    test suite for forest trust
4
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
8
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.
13
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.
18
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/>.
21 */
22
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"
34
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"
39 #define TPASS "1234567890"
40
41
42 static bool test_get_policy_handle(struct torture_context *tctx,
43                                    struct dcerpc_pipe *p,
44                                    uint32_t access_mask,
45                                    struct policy_handle **handle  )
46 {
47         struct policy_handle *h;
48         struct lsa_OpenPolicy2 pr;
49         struct lsa_ObjectAttribute attr;
50         NTSTATUS status;
51
52         h = talloc(tctx, struct policy_handle);
53         if (!h) {
54                 return false;
55         }
56
57         attr.len = 0;
58         attr.root_dir = NULL;
59         attr.object_name = NULL;
60         attr.attributes = 0;
61         attr.sec_desc = NULL;
62         attr.sec_qos = NULL;
63
64         pr.in.system_name = "\\";
65         pr.in.attr = &attr;
66         pr.in.access_mask = access_mask;
67         pr.out.handle = h;
68
69         status = dcerpc_lsa_OpenPolicy2_r(p->binding_handle, tctx, &pr);
70         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OK,
71                                       "OpenPolicy2 failed");
72         if (!NT_STATUS_IS_OK(pr.out.result)) {
73                 torture_comment(tctx, "OpenPolicy2 failed - %s\n",
74                                 nt_errstr(pr.out.result));
75                 talloc_free(h);
76                 return false;
77         }
78
79         *handle = h;
80         return true;
81 }
82
83 static bool test_create_trust_and_set_info(struct dcerpc_pipe *p,
84                                            struct torture_context *tctx,
85                                            const char *trust_name,
86                                            const char *trust_name_dns,
87                                            struct dom_sid *domsid,
88                                            struct lsa_TrustDomainInfoAuthInfoInternal *authinfo)
89 {
90         struct policy_handle *handle;
91         NTSTATUS status;
92         struct lsa_lsaRSetForestTrustInformation fti;
93         struct lsa_ForestTrustCollisionInfo *collision_info = NULL;
94         struct lsa_Close cr;
95         struct policy_handle closed_handle;
96         bool ret = true;
97         struct lsa_CreateTrustedDomainEx2 r;
98         struct lsa_TrustDomainInfoInfoEx trustinfo;
99         struct policy_handle trustdom_handle;
100         struct lsa_QueryTrustedDomainInfo q;
101         union lsa_TrustedDomainInfo *info = NULL;
102
103         if (!test_get_policy_handle(tctx, p,
104                                    (LSA_POLICY_VIEW_LOCAL_INFORMATION |
105                                     LSA_POLICY_TRUST_ADMIN |
106                                     LSA_POLICY_CREATE_SECRET), &handle)) {
107                 return false;
108         }
109
110         torture_comment(tctx, "\nTesting CreateTrustedDomainEx2\n");
111
112         trustinfo.sid = domsid;
113         trustinfo.netbios_name.string = trust_name;
114         trustinfo.domain_name.string = trust_name_dns;
115
116         trustinfo.trust_direction = LSA_TRUST_DIRECTION_INBOUND |
117                                     LSA_TRUST_DIRECTION_OUTBOUND;
118
119         trustinfo.trust_type = LSA_TRUST_TYPE_UPLEVEL;
120
121         trustinfo.trust_attributes = LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE;
122
123         r.in.policy_handle = handle;
124         r.in.info = &trustinfo;
125         r.in.auth_info = authinfo;
126         r.in.access_mask = LSA_TRUSTED_SET_POSIX | LSA_TRUSTED_SET_AUTH;
127         r.out.trustdom_handle = &trustdom_handle;
128
129         torture_assert_ntstatus_ok(tctx,
130                                    dcerpc_lsa_CreateTrustedDomainEx2_r(p->binding_handle, tctx, &r),
131                                    "CreateTrustedDomainEx2 failed");
132         if (!NT_STATUS_IS_OK(r.out.result)) {
133                 torture_comment(tctx, "CreateTrustedDomainEx failed2 - %s\n", nt_errstr(r.out.result));
134                 ret = false;
135         } else {
136
137                 q.in.trustdom_handle = &trustdom_handle;
138                 q.in.level = LSA_TRUSTED_DOMAIN_INFO_INFO_EX;
139                 q.out.info = &info;
140
141                 torture_assert_ntstatus_ok(tctx,
142                                            dcerpc_lsa_QueryTrustedDomainInfo_r(p->binding_handle, tctx, &q),
143                                            "QueryTrustedDomainInfo failed");
144                 if (!NT_STATUS_IS_OK(q.out.result)) {
145                         torture_comment(tctx,
146                                         "QueryTrustedDomainInfo level 1 failed - %s\n",
147                                         nt_errstr(q.out.result));
148                         ret = false;
149                 } else if (!q.out.info) {
150                         torture_comment(tctx,
151                                         "QueryTrustedDomainInfo level 1 failed to return an info pointer\n");
152                         ret = false;
153                 } else {
154                         if (strcmp(info->info_ex.netbios_name.string, trustinfo.netbios_name.string) != 0) {
155                                 torture_comment(tctx,
156                                                 "QueryTrustedDomainInfo returned inconsistant short name: %s != %s\n",
157                                                 info->info_ex.netbios_name.string,
158                                                 trustinfo.netbios_name.string);
159                                 ret = false;
160                         }
161                         if (info->info_ex.trust_type != trustinfo.trust_type) {
162                                 torture_comment(tctx,
163                                                 "QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n",
164                                                 trust_name,
165                                                 info->info_ex.trust_type,
166                                                 trustinfo.trust_type);
167                                 ret = false;
168                         }
169                         if (info->info_ex.trust_attributes != trustinfo.trust_attributes) {
170                                 torture_comment(tctx,
171                                                 "QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n",
172                                                 trust_name,
173                                                 info->info_ex.trust_attributes,
174                                                 trustinfo.trust_attributes);
175                                 ret = false;
176                         }
177                         if (info->info_ex.trust_direction != trustinfo.trust_direction) {
178                                 torture_comment(tctx,
179                                                 "QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n",
180                                                 trust_name,
181                                                 info->info_ex.trust_direction,
182                                                 trustinfo.trust_direction);
183                                 ret = false;
184                         }
185                 }
186         }
187
188         if (ret != false) {
189                 fti.in.handle = handle;
190                 fti.in.trusted_domain_name = talloc_zero(tctx, struct lsa_StringLarge);
191                 fti.in.trusted_domain_name->string = trust_name_dns;
192                 fti.in.highest_record_type = 2;
193                 fti.in.forest_trust_info = talloc_zero(tctx, struct lsa_ForestTrustInformation);
194                 fti.in.forest_trust_info->count = 2;
195                 fti.in.forest_trust_info->entries = talloc_array(tctx, struct lsa_ForestTrustRecord *, 2);
196                 fti.in.forest_trust_info->entries[0] = talloc_zero(tctx, struct lsa_ForestTrustRecord);
197                 fti.in.forest_trust_info->entries[0]->flags = 0;
198                 fti.in.forest_trust_info->entries[0]->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
199                 fti.in.forest_trust_info->entries[0]->time = 0;
200                 fti.in.forest_trust_info->entries[0]->forest_trust_data.top_level_name.string = trust_name_dns;
201                 fti.in.forest_trust_info->entries[1] = talloc_zero(tctx, struct lsa_ForestTrustRecord);
202                 fti.in.forest_trust_info->entries[1]->flags = 0;
203                 fti.in.forest_trust_info->entries[1]->type = LSA_FOREST_TRUST_DOMAIN_INFO;
204                 fti.in.forest_trust_info->entries[1]->time = 0;
205                 fti.in.forest_trust_info->entries[1]->forest_trust_data.domain_info.domain_sid = domsid;
206                 fti.in.forest_trust_info->entries[1]->forest_trust_data.domain_info.dns_domain_name.string = trust_name_dns;
207                 fti.in.forest_trust_info->entries[1]->forest_trust_data.domain_info.netbios_domain_name.string = trust_name;
208                 fti.in.check_only = 0;
209                 fti.out.collision_info = &collision_info;
210
211                 torture_comment(tctx, "\nTesting SetForestTrustInformation\n");
212
213                 torture_assert_ntstatus_ok(tctx,
214                                            dcerpc_lsa_lsaRSetForestTrustInformation_r(p->binding_handle, tctx, &fti),
215                                            "lsaRSetForestTrustInformation failed");
216                 if (!NT_STATUS_IS_OK(fti.out.result)) {
217                         torture_comment(tctx,
218                                         "lsaRSetForestTrustInformation failed - %s\n",
219                                         nt_errstr(fti.out.result));
220                         ret = false;
221                 }
222         }
223
224         cr.in.handle = handle;
225         cr.out.handle = &closed_handle;
226         status =  dcerpc_lsa_Close_r(p->binding_handle, tctx, &cr);
227         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OK,
228                                       "Close failed");
229         if (!NT_STATUS_IS_OK(cr.out.result)) {
230                 torture_comment(tctx, "Close failed - %s\n",
231                                 nt_errstr(cr.out.result));
232                 ret = false;
233         }
234
235         return ret;
236 }
237
238 static bool check_name(struct dcerpc_pipe *p, struct torture_context *tctx,
239                        const char *name)
240 {
241         struct policy_handle *handle;
242         NTSTATUS status;
243         struct lsa_QueryTrustedDomainInfoByName qr;
244         union lsa_TrustedDomainInfo *info;
245         struct lsa_Close cr;
246         struct policy_handle closed_handle;
247
248         torture_comment(tctx, "\nGetting LSA_TRUSTED_DOMAIN_INFO_FULL_INFO\n");
249
250         if(!test_get_policy_handle(tctx, p, LSA_POLICY_VIEW_LOCAL_INFORMATION,
251                                    &handle)) {
252                 return false;
253         }
254
255         qr.in.handle = handle;
256         qr.in.trusted_domain = talloc_zero(tctx, struct lsa_String);
257         qr.in.trusted_domain->string = name;
258         qr.in.level = LSA_TRUSTED_DOMAIN_INFO_FULL_INFO;
259         qr.out.info = &info;
260         status = dcerpc_lsa_QueryTrustedDomainInfoByName_r(p->binding_handle,
261                                                            tctx, &qr);
262         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OK,
263                                       "QueryInfoPolicy2 failed");
264         if (!NT_STATUS_EQUAL(qr.out.result, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
265                 torture_comment(tctx, "QueryInfoPolicy2 did not return "
266                                       "NT_STATUS_OBJECT_NAME_NOT_FOUND\n");
267                 return false;
268         }
269
270         cr.in.handle = handle;
271         cr.out.handle = &closed_handle;
272         status =  dcerpc_lsa_Close_r(p->binding_handle, tctx, &cr);
273         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OK,
274                                       "Close failed");
275         if (!NT_STATUS_IS_OK(cr.out.result)) {
276                 torture_comment(tctx, "Close failed - %s\n",
277                                 nt_errstr(cr.out.result));
278                 return false;
279         }
280
281         return true;
282 }
283 static bool get_lsa_policy_info_dns(struct dcerpc_pipe *p,
284                                     struct torture_context *tctx,
285                                     union lsa_PolicyInformation **info)
286 {
287         struct policy_handle *handle;
288         NTSTATUS status;
289         struct lsa_QueryInfoPolicy2 qr;
290         struct lsa_Close cr;
291         struct policy_handle closed_handle;
292
293         torture_comment(tctx, "\nGetting LSA_POLICY_INFO_DNS\n");
294
295         if (!test_get_policy_handle(tctx, p, LSA_POLICY_VIEW_LOCAL_INFORMATION,
296                                     &handle)) {
297                 return false;
298         }
299
300         qr.in.handle = handle;
301         qr.in.level = LSA_POLICY_INFO_DNS;
302         qr.out.info = info;
303         status = dcerpc_lsa_QueryInfoPolicy2_r(p->binding_handle, tctx, &qr);
304         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OK,
305                                       "QueryInfoPolicy2 failed");
306         if (!NT_STATUS_IS_OK(qr.out.result)) {
307                 torture_comment(tctx, "QueryInfoPolicy2 failed - %s\n",
308                                 nt_errstr(qr.out.result));
309                 return false;
310         }
311
312         cr.in.handle = handle;
313         cr.out.handle = &closed_handle;
314         status =  dcerpc_lsa_Close_r(p->binding_handle, tctx, &cr);
315         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OK,
316                                       "Close failed");
317         if (!NT_STATUS_IS_OK(cr.out.result)) {
318                 torture_comment(tctx, "Close failed - %s\n",
319                                 nt_errstr(cr.out.result));
320                 return false;
321         }
322
323         return true;
324 }
325
326 static bool delete_trusted_domain_by_sid(struct dcerpc_pipe *p,
327                                          struct torture_context *tctx,
328                                          struct dom_sid *domsid)
329 {
330         struct policy_handle *handle;
331         NTSTATUS status;
332         struct lsa_Close cr;
333         struct policy_handle closed_handle;
334         struct lsa_DeleteTrustedDomain dr;
335         bool ret = true;
336
337         torture_comment(tctx, "\nDeleting trusted domain.\n");
338
339         if (!test_get_policy_handle(tctx, p, LSA_POLICY_VIEW_LOCAL_INFORMATION,
340                                     &handle)) {
341                 return false;
342         }
343
344         dr.in.handle = handle;
345         dr.in.dom_sid = domsid;
346
347         torture_assert_ntstatus_ok(tctx,
348                                    dcerpc_lsa_DeleteTrustedDomain_r(p->binding_handle, tctx, &dr),
349                                    "DeleteTrustedDomain failed");
350         if (!NT_STATUS_IS_OK(dr.out.result)) {
351                 torture_comment(tctx, "DeleteTrustedDomain failed - %s\n",
352                                 nt_errstr(dr.out.result));
353                 return false;
354         }
355
356         cr.in.handle = handle;
357         cr.out.handle = &closed_handle;
358         status =  dcerpc_lsa_Close_r(p->binding_handle, tctx, &cr);
359         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_OK,
360                                       "Close failed");
361         if (!NT_STATUS_IS_OK(cr.out.result)) {
362                 torture_comment(tctx, "Close failed - %s\n",
363                                 nt_errstr(cr.out.result));
364                 ret = false;
365         }
366
367         return ret;
368 }
369
370 static const uint8_t my_blob[] = {
371 0xa3,0x0b,0x32,0x45,0x8b,0x84,0x3b,0x01,0x68,0xe8,0x2b,0xbb,0x00,0x13,0x69,0x1f,
372 0x10,0x35,0x72,0xa9,0x4f,0x77,0xb7,0xeb,0x59,0x08,0x07,0xc3,0xe8,0x17,0x00,0xc5,
373 0xf2,0xa9,0x6d,0xb7,0x69,0x45,0x63,0x20,0xcb,0x44,0x44,0x22,0x02,0xe3,0x28,0x84,
374 0x9b,0xd5,0x43,0x6f,0x8d,0x36,0x9b,0x9b,0x3b,0x31,0x86,0x84,0x8b,0xf2,0x36,0xd4,
375 0xe8,0xc4,0xee,0x90,0x0c,0xcb,0x3e,0x11,0x2f,0x86,0xfe,0x87,0x6d,0xce,0xae,0x0c,
376 0x83,0xfb,0x21,0x22,0x6d,0x7f,0x5e,0x08,0x71,0x1a,0x35,0xf4,0x5a,0x76,0x9b,0xf7,
377 0x54,0x62,0xa5,0x4c,0xcd,0xf6,0xa5,0xb0,0x0b,0xc7,0x79,0xe1,0x6f,0x85,0x16,0x6f,
378 0x82,0xdd,0x15,0x11,0x4c,0x9d,0x26,0x01,0x74,0x7e,0xbb,0xec,0x88,0x1d,0x71,0x9e,
379 0x5f,0xb2,0x9c,0xab,0x66,0x20,0x08,0x3d,0xae,0x07,0x2d,0xbb,0xa6,0xfb,0xec,0xcc,
380 0x51,0x58,0x48,0x47,0x38,0x3b,0x47,0x66,0xe8,0x17,0xfa,0x54,0x5c,0x95,0x73,0x29,
381 0xdf,0x7e,0x4a,0xb4,0x45,0x30,0xf7,0xbf,0xc0,0x56,0x6d,0x80,0xf6,0x11,0x56,0x93,
382 0xeb,0x97,0xd5,0x10,0xd6,0xd6,0xf7,0x23,0xc3,0xc0,0x93,0xa7,0x5c,0xa9,0xc0,0x81,
383 0x55,0x3d,0xec,0x03,0x31,0x7e,0x9d,0xf9,0xd0,0x9e,0xb5,0xc7,0xef,0xa8,0x54,0xf6,
384 0x9c,0xdc,0x0d,0xd4,0xd7,0xee,0x8d,0x5f,0xbd,0x89,0x48,0x3b,0x63,0xff,0xe8,0xca,
385 0x10,0x64,0x61,0xdf,0xfd,0x50,0xff,0x51,0xa0,0x2c,0xd7,0x8a,0xf1,0x13,0x02,0x02,
386 0x71,0xe9,0xff,0x0d,0x03,0x48,0xf8,0x08,0x8d,0xd5,0xe6,0x31,0x9f,0xf0,0x26,0x07,
387 0x91,0x6d,0xd3,0x01,0x91,0x92,0xc7,0x28,0x18,0x58,0xd8,0xf6,0x1b,0x97,0x8d,0xd0,
388 0xd2,0xa1,0x7c,0xae,0xc1,0xca,0xfe,0x20,0x91,0x1c,0x4d,0x15,0x89,0x29,0x37,0xd5,
389 0xf5,0xca,0x40,0x2b,0x03,0x8f,0x7b,0xc2,0x10,0xb4,0xd3,0xe8,0x14,0xb0,0x9b,0x5d,
390 0x85,0x30,0xe5,0x13,0x24,0xf7,0x78,0xec,0xbe,0x0b,0x9a,0x3f,0xb5,0x76,0xd9,0x0d,
391 0x49,0x64,0xa4,0xa7,0x33,0x88,0xdd,0xe9,0xe2,0x5f,0x04,0x51,0xdd,0x89,0xe2,0x68,
392 0x5b,0x5f,0x64,0x35,0xe3,0x23,0x4a,0x0e,0x09,0x15,0xcc,0x97,0x47,0xf4,0xc2,0x4f,
393 0x06,0xc3,0x96,0xa9,0x2f,0xb3,0xde,0x29,0x10,0xc7,0xf5,0x16,0xc5,0x3c,0x84,0xd2,
394 0x9b,0x6b,0xaa,0x54,0x59,0x8d,0x94,0xde,0xd1,0x75,0xb6,0x08,0x0d,0x7d,0xf1,0x18,
395 0xc8,0xf5,0xdf,0xaa,0xcd,0xec,0xab,0xb6,0xd1,0xcb,0xdb,0xe7,0x75,0x5d,0xbe,0x76,
396 0xea,0x1d,0x01,0xc8,0x0b,0x2d,0x32,0xe9,0xa8,0x65,0xbb,0x4a,0xcb,0x72,0xbc,0xda,
397 0x04,0x7f,0x82,0xfb,0x04,0xeb,0xd8,0xe1,0xb9,0xb1,0x1e,0xdc,0xb3,0x60,0xf3,0x55,
398 0x1e,0xcf,0x90,0x6a,0x15,0x74,0x4d,0xff,0xb4,0xc7,0xc9,0xc2,0x4f,0x67,0x9e,0xeb,
399 0x00,0x61,0x02,0xe3,0x9e,0x59,0x88,0x20,0xf1,0x0c,0xbe,0xe0,0x26,0x69,0x63,0x67,
400 0x72,0x3c,0x06,0x00,0x9e,0x4f,0xc7,0xa6,0x4d,0x6c,0xbe,0x68,0x8e,0xf4,0x32,0x36,
401 0x2e,0x5f,0xa6,0xcf,0xa7,0x19,0x40,0x2b,0xbd,0xa2,0x22,0x73,0xc4,0xb6,0xe3,0x86,
402 0x64,0xeb,0xb1,0xc7,0x45,0x7d,0xd6,0xd9,0x36,0xf1,0x04,0xd4,0x61,0xdc,0x41,0xb7,
403 0x01,0x00,0x00,0x00,0x0c,0x00,0x00,0x00,     0x30,0x00,0x00,0x00,     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
404 0x02,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0x31,0x00,0x32,0x00,0x33,0x00,0x34,0x00,
405 0x35,0x00,0x36,0x00,0x37,0x00,0x38,0x00,0x39,0x00,0x30,0x00,0x01,0x00,0x00,0x00,
406 0x0c,0x00,0x00,0x00,     0x30,0x00,0x00,0x00,     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
407 0x14,0x00,0x00,0x00,0x31,0x00,0x32,0x00,0x33,0x00,0x34,0x00,0x35,0x00,0x36,0x00,
408 0x37,0x00,0x38,0x00,0x39,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x00,0x00
409 };
410
411 static bool get_trust_domain_passwords_auth_blob(TALLOC_CTX *mem_ctx,
412                                                  const char *password,
413                                                  DATA_BLOB *auth_blob)
414 {
415         struct trustDomainPasswords auth_struct;
416         struct AuthenticationInformation *auth_info_array;
417         enum ndr_err_code ndr_err;
418         size_t converted_size;
419
420         generate_random_buffer(auth_struct.confounder,
421                                sizeof(auth_struct.confounder));
422
423         auth_info_array = talloc_array(mem_ctx,
424                                        struct AuthenticationInformation, 1);
425         if (auth_info_array == NULL) {
426                 return false;
427         }
428
429         auth_info_array[0].AuthType = TRUST_AUTH_TYPE_CLEAR;
430         if (!convert_string_talloc(mem_ctx, CH_UNIX, CH_UTF16, password,
431                                   strlen(password),
432                                   &auth_info_array[0].AuthInfo.clear.password,
433                                   &converted_size,
434                                   false)) {
435                 return false;
436         }
437
438         auth_info_array[0].AuthInfo.clear.size = converted_size;
439
440         auth_struct.outgoing.count = 1;
441         auth_struct.outgoing.current.count = 1;
442         auth_struct.outgoing.current.array = auth_info_array;
443         auth_struct.outgoing.previous.count = 0;
444         auth_struct.outgoing.previous.array = NULL;
445
446         auth_struct.incoming.count = 1;
447         auth_struct.incoming.current.count = 1;
448         auth_struct.incoming.current.array = auth_info_array;
449         auth_struct.incoming.previous.count = 0;
450         auth_struct.incoming.previous.array = NULL;
451
452         ndr_err = ndr_push_struct_blob(auth_blob, mem_ctx, &auth_struct,
453                                        (ndr_push_flags_fn_t)ndr_push_trustDomainPasswords);
454         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
455                 return false;
456         }
457
458         return true;
459 }
460
461 static bool test_validate_trust(struct torture_context *tctx,
462                                 struct dcerpc_binding *binding,
463                                 const char *trusting_dom_name,
464                                 const char *trusting_dom_dns_name,
465                                 const char *trusted_dom_name,
466                                 const char *trusted_dom_dns_name)
467 {
468         struct netr_ServerGetTrustInfo r;
469
470         struct netr_Authenticator a;
471         struct netr_Authenticator return_authenticator;
472         struct samr_Password new_owf_password;
473         struct samr_Password old_owf_password;
474         struct netr_TrustInfo *trust_info;
475
476         struct netlogon_creds_CredentialState *creds;
477
478         NTSTATUS status;
479         struct cli_credentials *credentials;
480         struct dcerpc_pipe *pipe;
481
482         struct netr_GetForestTrustInformation fr;
483         struct lsa_ForestTrustInformation *forest_trust_info;
484         int i;
485
486
487         credentials = cli_credentials_init(tctx);
488         if (credentials == NULL) {
489                 return false;
490         }
491
492         cli_credentials_set_username(credentials, trusted_dom_name,
493                                      CRED_SPECIFIED);
494         cli_credentials_set_domain(credentials, trusting_dom_name,
495                                    CRED_SPECIFIED);
496         cli_credentials_set_realm(credentials, trusting_dom_dns_name,
497                                   CRED_SPECIFIED);
498         cli_credentials_set_password(credentials, TPASS, CRED_SPECIFIED);
499         cli_credentials_set_workstation(credentials,
500                                         trusted_dom_name, CRED_SPECIFIED);
501         cli_credentials_set_secure_channel_type(credentials, SEC_CHAN_DOMAIN);
502
503         status = dcerpc_pipe_connect_b(tctx, &pipe, binding,
504                                        &ndr_table_netlogon, credentials,
505                                        tctx->ev, tctx->lp_ctx);
506
507         if (NT_STATUS_IS_ERR(status)) {
508                 torture_comment(tctx, "Failed to connect to remote server: %s  with %s - %s\n",
509                                 dcerpc_binding_string(tctx, binding),
510                                 cli_credentials_get_unparsed_name(credentials, tctx),
511                                 nt_errstr(status));
512                 return false;
513         }
514
515         if (!test_SetupCredentials3(pipe, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
516                                     credentials, &creds)) {
517                 torture_comment(tctx, "test_SetupCredentials3 failed.\n");
518                 return false;
519         }
520
521         netlogon_creds_client_authenticator(creds, &a);
522
523         r.in.server_name = talloc_asprintf(tctx, "\\\\%s",
524                                            dcerpc_server_name(pipe));
525         r.in.account_name = talloc_asprintf(tctx, "%s$", trusted_dom_name);
526         r.in.secure_channel_type = cli_credentials_get_secure_channel_type(credentials);
527         r.in.computer_name = trusted_dom_name;
528         r.in.credential = &a;
529
530         r.out.return_authenticator = &return_authenticator;
531         r.out.new_owf_password = &new_owf_password;
532         r.out.old_owf_password = &old_owf_password;
533         r.out.trust_info = &trust_info;
534
535         torture_assert_ntstatus_ok(tctx,
536                                    dcerpc_netr_ServerGetTrustInfo_r(pipe->binding_handle, tctx, &r),
537                                    "ServerGetTrustInfo failed");
538         torture_assert_ntstatus_ok(tctx, r.out.result,
539                                    "ServerGetTrustInfo failed");
540
541         if (trust_info->count != 1) {
542                 torture_comment(tctx, "Unexpected number of results, "
543                                       "expected %d, got %d.\n",
544                                       1, trust_info->count);
545                 return false;
546         }
547         if (trust_info->data[0] != LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
548                 torture_comment(tctx, "Unexpected result, "
549                                       "expected %d, got %d.\n",
550                                       LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE,
551                                       trust_info->data[0]);
552                 return false;
553         }
554
555         netlogon_creds_client_authenticator(creds, &a);
556
557         fr.in.server_name = talloc_asprintf(tctx, "\\\\%s",
558                                             dcerpc_server_name(pipe));
559         fr.in.computer_name = trusted_dom_name;
560         fr.in.credential = &a;
561         fr.in.flags = 0;
562         fr.out.return_authenticator = &return_authenticator;
563         fr.out.forest_trust_info = &forest_trust_info;
564
565         torture_assert_ntstatus_ok(tctx,
566                                    dcerpc_netr_GetForestTrustInformation_r(pipe->binding_handle, tctx, &fr),
567                                    "netr_GetForestTrustInformation failed");
568         if (NT_STATUS_IS_ERR(fr.out.result)) {
569                 torture_comment(tctx,
570                                 "netr_GetForestTrustInformation failed - %s.\n",
571                                 nt_errstr(fr.out.result));
572                 return false;
573         }
574
575         if (forest_trust_info->count != 2) {
576                 torture_comment(tctx, "Unexpected number of results, "
577                                       "expected %d, got %d.\n", 2,
578                                       forest_trust_info->count);
579                 return false;
580         }
581         for(i = 0; i < forest_trust_info->count; i++) {
582                 switch(forest_trust_info->entries[i]->type) {
583                         case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
584                                 if (strcmp(forest_trust_info->entries[i]->forest_trust_data.top_level_name.string, trusting_dom_dns_name) != 0) {
585                                         torture_comment(tctx, "Unexpected result, "
586                                                         "expected %s, got %s.\n",
587                                                         trusting_dom_dns_name,
588                                                         forest_trust_info->entries[i]->forest_trust_data.top_level_name.string);
589                                         return false;
590                                 }
591                                 break;
592                         case LSA_FOREST_TRUST_DOMAIN_INFO:
593                                 if (strcmp(forest_trust_info->entries[i]->forest_trust_data.domain_info.netbios_domain_name.string, trusting_dom_name) != 0) {
594                                         torture_comment(tctx, "Unexpected result, "
595                                                         "expected %s, got %s.\n",
596                                                         trusting_dom_dns_name,
597                                                         forest_trust_info->entries[i]->forest_trust_data.domain_info.netbios_domain_name.string);
598                                         return false;
599                                 }
600                                 if (strcmp(forest_trust_info->entries[i]->forest_trust_data.domain_info.dns_domain_name.string, trusting_dom_dns_name) != 0) {
601                                         torture_comment(tctx, "Unexpected result, "
602                                                         "expected %s, got %s.\n",
603                                                         trusting_dom_dns_name,
604                                                         forest_trust_info->entries[i]->forest_trust_data.domain_info.dns_domain_name.string);
605                                         return false;
606                                 }
607                                 break;
608                         default:
609                                 torture_comment(tctx, "Unexpected result type, "
610                                                 "expected %d|%d, got %d.\n",
611                                                 LSA_FOREST_TRUST_TOP_LEVEL_NAME,
612                                                 LSA_FOREST_TRUST_DOMAIN_INFO,
613                                                 forest_trust_info->entries[i]->type);
614                                 return false;
615                 }
616         }
617
618         return true;
619 }
620
621 static bool test_setup_trust(struct torture_context *tctx,
622                              struct dcerpc_pipe *p,
623                              const char *netbios_name,
624                              const char *dns_name,
625                              struct dom_sid *sid,
626                              DATA_BLOB *auth_blob)
627
628 {
629         DATA_BLOB session_key;
630         struct lsa_TrustDomainInfoAuthInfoInternal authinfo;
631         NTSTATUS status;
632
633         if (!check_name(p, tctx, netbios_name)) {
634                 return false;
635         }
636         if (!check_name(p, tctx, dns_name)) {
637                 return false;
638         }
639
640         status = dcerpc_fetch_session_key(p, &session_key);
641         if (!NT_STATUS_IS_OK(status)) {
642                 torture_comment(tctx, "dcerpc_fetch_session_key failed - %s\n",
643                                 nt_errstr(status));
644                 return false;
645         }
646
647         authinfo.auth_blob.data = talloc_memdup(tctx, auth_blob->data,
648                                                 auth_blob->length);
649         if (authinfo.auth_blob.data == NULL) {
650                 return false;
651         }
652         authinfo.auth_blob.size = auth_blob->length;
653
654         arcfour_crypt_blob(authinfo.auth_blob.data, authinfo.auth_blob.size,
655                            &session_key);
656
657         if (!test_create_trust_and_set_info(p, tctx, netbios_name,
658                                             dns_name, sid, &authinfo)) {
659                 return false;
660         }
661
662         return true;
663 }
664
665 static bool testcase_ForestTrusts(struct torture_context *tctx,
666                                   struct dcerpc_pipe *p)
667 {
668         bool ret = true;
669         const char *dom2_binding_string;
670         const char * dom2_cred_string;
671         NTSTATUS status;
672         struct dom_sid *domsid;
673         DATA_BLOB auth_blob;
674         struct dcerpc_binding *dom2_binding;
675         struct dcerpc_pipe *dom2_p;
676         struct cli_credentials *dom2_credentials;
677         union lsa_PolicyInformation *dom1_info_dns = NULL;
678         union lsa_PolicyInformation *dom2_info_dns = NULL;
679
680         torture_comment(tctx, "Testing Forest Trusts\n");
681
682         if (!get_trust_domain_passwords_auth_blob(tctx, TPASS, &auth_blob)) {
683                 torture_comment(tctx,
684                                 "get_trust_domain_passwords_auth_blob failed\n");
685                 return false;
686         }
687
688 #if 0
689         /* Use the following if get_trust_domain_passwords_auth_blob() cannot
690          * generate a usable blob due to errors in the IDL */
691         auth_blob.data = talloc_memdup(tctx, my_blob, sizeof(my_blob));
692         auth_blob.length = sizeof(my_blob);
693 #endif
694
695         domsid = dom_sid_parse_talloc(tctx, TEST_DOM_SID);
696         if (domsid == NULL) {
697                 return false;
698         }
699
700         if (!test_setup_trust(tctx, p, TEST_DOM, TEST_DOM_DNS, domsid,
701                               &auth_blob)) {
702                 ret = false;
703         }
704
705         if (!get_lsa_policy_info_dns(p, tctx, &dom1_info_dns)) {
706                 return false;
707         }
708
709         if (!test_validate_trust(tctx, p->binding,
710                                  dom1_info_dns->dns.name.string,
711                                  dom1_info_dns->dns.dns_domain.string,
712                                  TEST_DOM, TEST_DOM_DNS)) {
713                 ret = false;
714         }
715
716         if (!delete_trusted_domain_by_sid(p, tctx, domsid)) {
717                 ret = false;
718         }
719
720         dom2_binding_string = torture_setting_string(tctx,
721                                                      "Forest_Trust_Dom2_Binding",
722                                                      NULL);
723         if (dom2_binding_string == NULL) {
724                 return ret;
725         }
726
727         status = dcerpc_parse_binding(tctx, dom2_binding_string, &dom2_binding);
728         if (NT_STATUS_IS_ERR(status)) {
729                 DEBUG(0,("Failed to parse dcerpc binding '%s'\n",
730                          dom2_binding_string));
731                 return false;
732         }
733
734         dom2_cred_string = torture_setting_string(tctx,
735                                                   "Forest_Trust_Dom2_Creds",
736                                                   NULL);
737         if (dom2_cred_string == NULL) {
738                 return false;
739         }
740
741         dom2_credentials = cli_credentials_init(tctx);
742         if (dom2_credentials == NULL) {
743                 return false;
744         }
745
746         cli_credentials_parse_string(dom2_credentials, dom2_cred_string,
747                                      CRED_SPECIFIED);
748         cli_credentials_set_workstation(dom2_credentials,
749                                         TEST_MACHINE_NAME, CRED_SPECIFIED);
750
751         status = dcerpc_pipe_connect_b(tctx, &dom2_p, dom2_binding,
752                                        &ndr_table_lsarpc, dom2_credentials,
753                                        tctx->ev, tctx->lp_ctx);
754
755         if (NT_STATUS_IS_ERR(status)) {
756                 torture_comment(tctx, "Failed to connect to remote server: %s %s\n",
757                                 dcerpc_binding_string(tctx, dom2_binding),
758                                 nt_errstr(status));
759                 return false;
760         }
761
762         if (!get_lsa_policy_info_dns(dom2_p, tctx, &dom2_info_dns)) {
763                 return false;
764         }
765
766         if (strcasecmp(dom1_info_dns->dns.name.string,
767                        dom2_info_dns->dns.name.string) == 0 ||
768             strcasecmp(dom1_info_dns->dns.dns_domain.string,
769                        dom2_info_dns->dns.dns_domain.string) == 0)
770         {
771                 torture_comment(tctx, "Trusting and trusted domain have the "
772                                       "same name.\n");
773                 return false;
774         }
775
776         if (!test_setup_trust(tctx, p, dom2_info_dns->dns.name.string,
777                                dom2_info_dns->dns.dns_domain.string,
778                                dom2_info_dns->dns.sid, &auth_blob)) {
779                 ret = false;
780         }
781         if (!test_setup_trust(tctx, dom2_p, dom1_info_dns->dns.name.string,
782                               dom1_info_dns->dns.dns_domain.string,
783                               dom1_info_dns->dns.sid, &auth_blob)) {
784                 ret = false;
785         }
786
787         if (!test_validate_trust(tctx, p->binding,
788                                  dom1_info_dns->dns.name.string,
789                                  dom1_info_dns->dns.dns_domain.string,
790                                  dom2_info_dns->dns.name.string,
791                                  dom2_info_dns->dns.dns_domain.string)) {
792                 ret = false;
793         }
794
795         if (!test_validate_trust(tctx, dom2_p->binding,
796                                  dom2_info_dns->dns.name.string,
797                                  dom2_info_dns->dns.dns_domain.string,
798                                  dom1_info_dns->dns.name.string,
799                                  dom1_info_dns->dns.dns_domain.string)) {
800                 ret = false;
801         }
802
803         if (!delete_trusted_domain_by_sid(p, tctx, dom2_info_dns->dns.sid)) {
804                 ret = false;
805         }
806
807         if (!delete_trusted_domain_by_sid(dom2_p, tctx, dom1_info_dns->dns.sid)) {
808                 ret = false;
809         }
810
811         return ret;
812 }
813
814 /* By default this test creates a trust object in the destination server to a
815  * dummy domain. If a second server from a different domain is specified on the
816  * command line a trust is created between those two domains.
817  *
818  * Example:
819  * smbtorture ncacn_np:srv1.dom1.test[print] RPC-LSA-FOREST-TRUST \
820  *  -U 'dom1\testadm1%12345678' \
821  *  --option=torture:Forest_Trust_Dom2_Binding=ncacn_np:srv2.dom2.test[print]  \
822  *  --option=torture:Forest_Trust_Dom2_Creds='dom2\testadm2%12345678'
823  */
824
825 struct torture_suite *torture_rpc_lsa_forest_trust(TALLOC_CTX *mem_ctx)
826 {
827         struct torture_suite *suite;
828         struct torture_rpc_tcase *tcase;
829
830         suite = torture_suite_create(mem_ctx, "lsa.forest.trust");
831
832         tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa-forest-trust",
833                                                   &ndr_table_lsarpc);
834         torture_rpc_tcase_add_test(tcase, "ForestTrust", testcase_ForestTrusts);
835
836         return suite;
837 }