1 | /*
|
---|
2 | Samba Unix/Linux SMB client library
|
---|
3 | Distributed SMB/CIFS Server Management Utility
|
---|
4 | Copyright (C) 2011 Sumit Bose (sbose@redhat.com)
|
---|
5 |
|
---|
6 | This program is free software; you can redistribute it and/or modify
|
---|
7 | it under the terms of the GNU General Public License as published by
|
---|
8 | the Free Software Foundation; either version 3 of the License, or
|
---|
9 | (at your option) any later version.
|
---|
10 |
|
---|
11 | This program is distributed in the hope that it will be useful,
|
---|
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
14 | GNU General Public License for more details.
|
---|
15 |
|
---|
16 | You should have received a copy of the GNU General Public License
|
---|
17 | along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
---|
18 |
|
---|
19 |
|
---|
20 | #include "includes.h"
|
---|
21 | #include "utils/net.h"
|
---|
22 | #include "rpc_client/cli_pipe.h"
|
---|
23 | #include "rpc_client/cli_lsarpc.h"
|
---|
24 | #include "librpc/gen_ndr/ndr_drsblobs.h"
|
---|
25 | #include "../librpc/gen_ndr/ndr_lsa_c.h"
|
---|
26 | #include "../lib/crypto/crypto.h"
|
---|
27 | #include "../libcli/security/dom_sid.h"
|
---|
28 | #include "libsmb/libsmb.h"
|
---|
29 |
|
---|
30 |
|
---|
31 | #define ARG_OTHERSERVER "otherserver="
|
---|
32 | #define ARG_OTHERUSER "otheruser="
|
---|
33 | #define ARG_OTHERDOMAINSID "otherdomainsid="
|
---|
34 | #define ARG_OTHERDOMAIN "otherdomain="
|
---|
35 | #define ARG_OTHERNETBIOSDOMAIN "other_netbios_domain="
|
---|
36 | #define ARG_TRUSTPW "trustpw="
|
---|
37 |
|
---|
38 | enum trust_op {
|
---|
39 | TRUST_CREATE,
|
---|
40 | TRUST_DELETE
|
---|
41 | };
|
---|
42 |
|
---|
43 | struct other_dom_data {
|
---|
44 | char *host;
|
---|
45 | char *user_name;
|
---|
46 | char *domain_sid_str;
|
---|
47 | char *dns_domain_name;
|
---|
48 | char *domain_name;
|
---|
49 | };
|
---|
50 |
|
---|
51 | struct dom_data {
|
---|
52 | struct dom_sid *domsid;
|
---|
53 | char *dns_domain_name;
|
---|
54 | char *domain_name;
|
---|
55 | };
|
---|
56 |
|
---|
57 | static NTSTATUS close_handle(TALLOC_CTX *mem_ctx,
|
---|
58 | struct dcerpc_binding_handle *bind_hnd,
|
---|
59 | struct policy_handle *pol_hnd)
|
---|
60 | {
|
---|
61 | NTSTATUS status;
|
---|
62 | NTSTATUS result;
|
---|
63 |
|
---|
64 | status = dcerpc_lsa_Close(bind_hnd, mem_ctx, pol_hnd, &result);
|
---|
65 | if (!NT_STATUS_IS_OK(status)) {
|
---|
66 | DEBUG(0, ("dcerpc_lsa_Close failed with error [%s].\n",
|
---|
67 | nt_errstr(status)));
|
---|
68 | return status;
|
---|
69 | }
|
---|
70 | if (!NT_STATUS_IS_OK(result)) {
|
---|
71 | DEBUG(0, ("lsa close failed with error [%s].\n",
|
---|
72 | nt_errstr(result)));
|
---|
73 | return result;
|
---|
74 | }
|
---|
75 |
|
---|
76 | return NT_STATUS_OK;
|
---|
77 | }
|
---|
78 |
|
---|
79 | static NTSTATUS delete_trust(TALLOC_CTX *mem_ctx,
|
---|
80 | struct dcerpc_binding_handle *bind_hnd,
|
---|
81 | struct policy_handle *pol_hnd,
|
---|
82 | struct dom_sid *domsid)
|
---|
83 | {
|
---|
84 | NTSTATUS status;
|
---|
85 | struct lsa_DeleteTrustedDomain dr;
|
---|
86 |
|
---|
87 | dr.in.handle = pol_hnd;
|
---|
88 | dr.in.dom_sid = domsid;
|
---|
89 |
|
---|
90 | status = dcerpc_lsa_DeleteTrustedDomain_r(bind_hnd, mem_ctx, &dr);
|
---|
91 | if (!NT_STATUS_IS_OK(status)) {
|
---|
92 | DEBUG(0, ("dcerpc_lsa_DeleteTrustedDomain_r failed with [%s]\n",
|
---|
93 | nt_errstr(status)));
|
---|
94 | return status;
|
---|
95 | }
|
---|
96 | if (!NT_STATUS_IS_OK(dr.out.result)) {
|
---|
97 | DEBUG(0, ("DeleteTrustedDomain returned [%s]\n",
|
---|
98 | nt_errstr(dr.out.result)));
|
---|
99 | return dr.out.result;
|
---|
100 | }
|
---|
101 |
|
---|
102 | return NT_STATUS_OK;
|
---|
103 | }
|
---|
104 |
|
---|
105 | static NTSTATUS create_trust(TALLOC_CTX *mem_ctx,
|
---|
106 | struct dcerpc_binding_handle *bind_hnd,
|
---|
107 | struct policy_handle *pol_hnd,
|
---|
108 | const char *trust_name,
|
---|
109 | const char *trust_name_dns,
|
---|
110 | struct dom_sid *domsid,
|
---|
111 | struct lsa_TrustDomainInfoAuthInfoInternal *authinfo)
|
---|
112 | {
|
---|
113 | NTSTATUS status;
|
---|
114 | struct lsa_CreateTrustedDomainEx2 r;
|
---|
115 | struct lsa_TrustDomainInfoInfoEx trustinfo;
|
---|
116 | struct policy_handle trustdom_handle;
|
---|
117 |
|
---|
118 | trustinfo.sid = domsid;
|
---|
119 | trustinfo.netbios_name.string = trust_name;
|
---|
120 | trustinfo.domain_name.string = trust_name_dns;
|
---|
121 |
|
---|
122 | trustinfo.trust_direction = LSA_TRUST_DIRECTION_INBOUND |
|
---|
123 | LSA_TRUST_DIRECTION_OUTBOUND;
|
---|
124 |
|
---|
125 | trustinfo.trust_type = LSA_TRUST_TYPE_UPLEVEL;
|
---|
126 |
|
---|
127 | trustinfo.trust_attributes = LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE;
|
---|
128 |
|
---|
129 | r.in.policy_handle = pol_hnd;
|
---|
130 | r.in.info = &trustinfo;
|
---|
131 | r.in.auth_info = authinfo;
|
---|
132 | r.in.access_mask = LSA_TRUSTED_SET_POSIX | LSA_TRUSTED_SET_AUTH |
|
---|
133 | LSA_TRUSTED_QUERY_DOMAIN_NAME;
|
---|
134 | r.out.trustdom_handle = &trustdom_handle;
|
---|
135 |
|
---|
136 | status = dcerpc_lsa_CreateTrustedDomainEx2_r(bind_hnd, mem_ctx, &r);
|
---|
137 | if (!NT_STATUS_IS_OK(status)) {
|
---|
138 | DEBUG(0, ("dcerpc_lsa_CreateTrustedDomainEx2_r failed "
|
---|
139 | "with error [%s].\n", nt_errstr(status)));
|
---|
140 | return status;
|
---|
141 | }
|
---|
142 | if (!NT_STATUS_IS_OK(r.out.result)) {
|
---|
143 | DEBUG(0, ("CreateTrustedDomainEx2_r returned [%s].\n",
|
---|
144 | nt_errstr(r.out.result)));
|
---|
145 | return r.out.result;
|
---|
146 | }
|
---|
147 |
|
---|
148 | return NT_STATUS_OK;
|
---|
149 | }
|
---|
150 |
|
---|
151 | static NTSTATUS get_domain_info(TALLOC_CTX *mem_ctx,
|
---|
152 | struct dcerpc_binding_handle *bind_hdn,
|
---|
153 | struct policy_handle *pol_hnd,
|
---|
154 | struct dom_data *dom_data)
|
---|
155 | {
|
---|
156 | NTSTATUS status;
|
---|
157 | struct lsa_QueryInfoPolicy2 qr;
|
---|
158 |
|
---|
159 | qr.in.handle = pol_hnd;
|
---|
160 | qr.in.level = LSA_POLICY_INFO_DNS;
|
---|
161 |
|
---|
162 | status = dcerpc_lsa_QueryInfoPolicy2_r(bind_hdn, mem_ctx, &qr);
|
---|
163 | if (!NT_STATUS_IS_OK(status)) {
|
---|
164 | DEBUG(0, ("dcerpc_lsa_QueryInfoPolicy2_r failed "
|
---|
165 | "with error [%s].\n", nt_errstr(status)));
|
---|
166 | return status;
|
---|
167 | }
|
---|
168 |
|
---|
169 | if (!NT_STATUS_IS_OK(qr.out.result)) {
|
---|
170 | DEBUG(0, ("QueryInfoPolicy2 returned [%s].\n",
|
---|
171 | nt_errstr(qr.out.result)));
|
---|
172 | return qr.out.result;
|
---|
173 | }
|
---|
174 |
|
---|
175 | dom_data->domain_name = talloc_strdup(mem_ctx,
|
---|
176 | (*qr.out.info)->dns.name.string);
|
---|
177 | dom_data->dns_domain_name = talloc_strdup(mem_ctx,
|
---|
178 | (*qr.out.info)->dns.dns_domain.string);
|
---|
179 | dom_data->domsid = dom_sid_dup(mem_ctx, (*qr.out.info)->dns.sid);
|
---|
180 | if (dom_data->domain_name == NULL ||
|
---|
181 | dom_data->dns_domain_name == NULL ||
|
---|
182 | dom_data->domsid == NULL) {
|
---|
183 | DEBUG(0, ("Copying domain data failed.\n"));
|
---|
184 | return NT_STATUS_NO_MEMORY;
|
---|
185 | }
|
---|
186 |
|
---|
187 | DEBUG(0, ("Got the following domain info [%s][%s][%s].\n",
|
---|
188 | dom_data->domain_name, dom_data->dns_domain_name,
|
---|
189 | sid_string_talloc(mem_ctx, dom_data->domsid)));
|
---|
190 |
|
---|
191 | return NT_STATUS_OK;
|
---|
192 | }
|
---|
193 |
|
---|
194 | static NTSTATUS connect_and_get_info(TALLOC_CTX *mem_ctx,
|
---|
195 | struct net_context *net_ctx,
|
---|
196 | struct cli_state **cli,
|
---|
197 | struct rpc_pipe_client **pipe_hnd,
|
---|
198 | struct policy_handle *pol_hnd,
|
---|
199 | struct dom_data *dom_data)
|
---|
200 | {
|
---|
201 | NTSTATUS status;
|
---|
202 | NTSTATUS result;
|
---|
203 |
|
---|
204 | status = net_make_ipc_connection_ex(net_ctx, NULL, NULL, NULL,
|
---|
205 | NET_FLAGS_PDC, cli);
|
---|
206 | if (!NT_STATUS_IS_OK(status)) {
|
---|
207 | DEBUG(0, ("Failed to connect to [%s] with error [%s]\n",
|
---|
208 | net_ctx->opt_host, nt_errstr(status)));
|
---|
209 | return status;
|
---|
210 | }
|
---|
211 |
|
---|
212 | status = cli_rpc_pipe_open_noauth(*cli, &ndr_table_lsarpc.syntax_id, pipe_hnd);
|
---|
213 | if (!NT_STATUS_IS_OK(status)) {
|
---|
214 | DEBUG(0, ("Failed to initialise lsa pipe with error [%s]\n",
|
---|
215 | nt_errstr(status)));
|
---|
216 | return status;
|
---|
217 | }
|
---|
218 |
|
---|
219 | status = dcerpc_lsa_open_policy2((*pipe_hnd)->binding_handle,
|
---|
220 | mem_ctx,
|
---|
221 | (*pipe_hnd)->srv_name_slash,
|
---|
222 | false,
|
---|
223 | (LSA_POLICY_VIEW_LOCAL_INFORMATION |
|
---|
224 | LSA_POLICY_TRUST_ADMIN |
|
---|
225 | LSA_POLICY_CREATE_SECRET),
|
---|
226 | pol_hnd,
|
---|
227 | &result);
|
---|
228 | if (!NT_STATUS_IS_OK(status)) {
|
---|
229 | DEBUG(0, ("Failed to open policy handle with error [%s]\n",
|
---|
230 | nt_errstr(status)));
|
---|
231 | return status;
|
---|
232 | }
|
---|
233 | if (!NT_STATUS_IS_OK(result)) {
|
---|
234 | DEBUG(0, ("lsa_open_policy2 with error [%s]\n",
|
---|
235 | nt_errstr(result)));
|
---|
236 | return result;
|
---|
237 | }
|
---|
238 |
|
---|
239 | status = get_domain_info(mem_ctx, (*pipe_hnd)->binding_handle,
|
---|
240 | pol_hnd, dom_data);
|
---|
241 | if (!NT_STATUS_IS_OK(status)) {
|
---|
242 | DEBUG(0, ("get_domain_info failed with error [%s].\n",
|
---|
243 | nt_errstr(status)));
|
---|
244 | return status;
|
---|
245 | }
|
---|
246 |
|
---|
247 | return NT_STATUS_OK;
|
---|
248 | }
|
---|
249 |
|
---|
250 | static bool get_trust_domain_passwords_auth_blob(TALLOC_CTX *mem_ctx,
|
---|
251 | const char *password,
|
---|
252 | DATA_BLOB *auth_blob)
|
---|
253 | {
|
---|
254 | struct trustDomainPasswords auth_struct;
|
---|
255 | struct AuthenticationInformation *auth_info_array;
|
---|
256 | enum ndr_err_code ndr_err;
|
---|
257 | size_t converted_size;
|
---|
258 |
|
---|
259 | generate_random_buffer(auth_struct.confounder,
|
---|
260 | sizeof(auth_struct.confounder));
|
---|
261 |
|
---|
262 | auth_info_array = talloc_array(mem_ctx,
|
---|
263 | struct AuthenticationInformation, 1);
|
---|
264 | if (auth_info_array == NULL) {
|
---|
265 | return false;
|
---|
266 | }
|
---|
267 |
|
---|
268 | auth_info_array[0].AuthType = TRUST_AUTH_TYPE_CLEAR;
|
---|
269 | if (!convert_string_talloc(mem_ctx, CH_UNIX, CH_UTF16, password,
|
---|
270 | strlen(password),
|
---|
271 | &auth_info_array[0].AuthInfo.clear.password,
|
---|
272 | &converted_size, true)) {
|
---|
273 | return false;
|
---|
274 | }
|
---|
275 |
|
---|
276 | auth_info_array[0].AuthInfo.clear.size = converted_size;
|
---|
277 |
|
---|
278 | auth_struct.outgoing.count = 1;
|
---|
279 | auth_struct.outgoing.current.count = 1;
|
---|
280 | auth_struct.outgoing.current.array = auth_info_array;
|
---|
281 | auth_struct.outgoing.previous.count = 0;
|
---|
282 | auth_struct.outgoing.previous.array = NULL;
|
---|
283 |
|
---|
284 | auth_struct.incoming.count = 1;
|
---|
285 | auth_struct.incoming.current.count = 1;
|
---|
286 | auth_struct.incoming.current.array = auth_info_array;
|
---|
287 | auth_struct.incoming.previous.count = 0;
|
---|
288 | auth_struct.incoming.previous.array = NULL;
|
---|
289 |
|
---|
290 | ndr_err = ndr_push_struct_blob(auth_blob, mem_ctx, &auth_struct,
|
---|
291 | (ndr_push_flags_fn_t)ndr_push_trustDomainPasswords);
|
---|
292 | if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
|
---|
293 | return false;
|
---|
294 | }
|
---|
295 |
|
---|
296 | return true;
|
---|
297 | }
|
---|
298 |
|
---|
299 | static int parse_trust_args(TALLOC_CTX *mem_ctx, int argc, const char **argv, struct other_dom_data **_o, char **_trustpw)
|
---|
300 | {
|
---|
301 | size_t c;
|
---|
302 | struct other_dom_data *o = NULL;
|
---|
303 | char *trustpw = NULL;
|
---|
304 | int ret = EFAULT;
|
---|
305 |
|
---|
306 | if (argc == 0) {
|
---|
307 | return EINVAL;
|
---|
308 | }
|
---|
309 |
|
---|
310 | o = talloc_zero(mem_ctx, struct other_dom_data);
|
---|
311 | if (o == NULL) {
|
---|
312 | DEBUG(0, ("talloc_zero failed.\n"));
|
---|
313 | return ENOMEM;
|
---|
314 | }
|
---|
315 |
|
---|
316 | for (c = 0; c < argc; c++) {
|
---|
317 | if (strnequal(argv[c], ARG_OTHERSERVER, sizeof(ARG_OTHERSERVER)-1)) {
|
---|
318 | o->host = talloc_strdup(o, argv[c] + sizeof(ARG_OTHERSERVER)-1);
|
---|
319 | if (o->host == NULL) {
|
---|
320 | ret = ENOMEM;
|
---|
321 | goto failed;
|
---|
322 | }
|
---|
323 | } else if (strnequal(argv[c], ARG_OTHERUSER, sizeof(ARG_OTHERUSER)-1)) {
|
---|
324 | o->user_name = talloc_strdup(o, argv[c] + sizeof(ARG_OTHERUSER)-1);
|
---|
325 | if (o->user_name == NULL) {
|
---|
326 | ret = ENOMEM;
|
---|
327 | goto failed;
|
---|
328 | }
|
---|
329 | } else if (strnequal(argv[c], ARG_OTHERDOMAINSID, sizeof(ARG_OTHERDOMAINSID)-1)) {
|
---|
330 | o->domain_sid_str = talloc_strdup(o, argv[c] + sizeof(ARG_OTHERDOMAINSID)-1);
|
---|
331 | if (o->domain_sid_str == NULL) {
|
---|
332 | ret = ENOMEM;
|
---|
333 | goto failed;
|
---|
334 | }
|
---|
335 | } else if (strnequal(argv[c], ARG_OTHERDOMAIN, sizeof(ARG_OTHERDOMAIN)-1)) {
|
---|
336 | o->dns_domain_name = talloc_strdup(o, argv[c] + sizeof(ARG_OTHERDOMAIN)-1);
|
---|
337 | if (o->dns_domain_name == NULL) {
|
---|
338 | ret = ENOMEM;
|
---|
339 | goto failed;
|
---|
340 | }
|
---|
341 | } else if (strnequal(argv[c], ARG_OTHERNETBIOSDOMAIN, sizeof(ARG_OTHERNETBIOSDOMAIN)-1)) {
|
---|
342 | o->domain_name = talloc_strdup(o, argv[c] + sizeof(ARG_OTHERNETBIOSDOMAIN)-1);
|
---|
343 | if (o->domain_name == NULL) {
|
---|
344 | ret = ENOMEM;
|
---|
345 | goto failed;
|
---|
346 | }
|
---|
347 | } else if (strnequal(argv[c], ARG_TRUSTPW, sizeof(ARG_TRUSTPW)-1)) {
|
---|
348 | trustpw = talloc_strdup(mem_ctx, argv[c] + sizeof(ARG_TRUSTPW)-1);
|
---|
349 | if (trustpw == NULL) {
|
---|
350 | ret = ENOMEM;
|
---|
351 | goto failed;
|
---|
352 | }
|
---|
353 | } else {
|
---|
354 | DEBUG(0, ("Unsupported option [%s].\n", argv[c]));
|
---|
355 | ret = EINVAL;
|
---|
356 | goto failed;
|
---|
357 | }
|
---|
358 | }
|
---|
359 |
|
---|
360 | *_o = o;
|
---|
361 | *_trustpw = trustpw;
|
---|
362 |
|
---|
363 | return 0;
|
---|
364 |
|
---|
365 | failed:
|
---|
366 | talloc_free(o);
|
---|
367 | talloc_free(trustpw);
|
---|
368 | return ret;
|
---|
369 | }
|
---|
370 |
|
---|
371 | static void print_trust_delete_usage(void)
|
---|
372 | {
|
---|
373 | d_printf( "%s\n"
|
---|
374 | "net rpc trust delete [options]\n"
|
---|
375 | "\nOptions:\n"
|
---|
376 | "\totherserver=DC in other domain\n"
|
---|
377 | "\totheruser=Admin user in other domain\n"
|
---|
378 | "\totherdomainsid=SID of other domain\n"
|
---|
379 | "\nExamples:\n"
|
---|
380 | "\tnet rpc trust delete otherserver=oname otheruser=ouser -S lname -U luser\n"
|
---|
381 | "\tnet rpc trust delete otherdomainsid=S-... -S lname -U luser\n"
|
---|
382 | " %s\n",
|
---|
383 | _("Usage:"),
|
---|
384 | _("Remove trust between two domains"));
|
---|
385 | }
|
---|
386 |
|
---|
387 | static void print_trust_usage(void)
|
---|
388 | {
|
---|
389 | d_printf( "%s\n"
|
---|
390 | "net rpc trust create [options]\n"
|
---|
391 | "\nOptions:\n"
|
---|
392 | "\totherserver=DC in other domain\n"
|
---|
393 | "\totheruser=Admin user in other domain\n"
|
---|
394 | "\totherdomainsid=SID of other domain\n"
|
---|
395 | "\tother_netbios_domain=NetBIOS/short name of other domain\n"
|
---|
396 | "\totherdomain=Full/DNS name of other domain\n"
|
---|
397 | "\ttrustpw=Trust password\n"
|
---|
398 | "\nExamples:\n"
|
---|
399 | "\tnet rpc trust create otherserver=oname otheruser=ouser -S lname -U luser\n"
|
---|
400 | "\tnet rpc trust create otherdomainsid=S-... other_netbios_domain=odom otherdomain=odom.org trustpw=secret -S lname -U luser\n"
|
---|
401 | " %s\n",
|
---|
402 | _("Usage:"),
|
---|
403 | _("Create trust between two domains"));
|
---|
404 | }
|
---|
405 |
|
---|
406 | static int rpc_trust_common(struct net_context *net_ctx, int argc,
|
---|
407 | const char **argv, enum trust_op op)
|
---|
408 | {
|
---|
409 | TALLOC_CTX *mem_ctx;
|
---|
410 | NTSTATUS status;
|
---|
411 | int ret;
|
---|
412 | int success = -1;
|
---|
413 | struct cli_state *cli[2] = {NULL, NULL};
|
---|
414 | struct rpc_pipe_client *pipe_hnd[2] = {NULL, NULL};
|
---|
415 | struct policy_handle pol_hnd[2];
|
---|
416 | struct lsa_TrustDomainInfoAuthInfoInternal authinfo;
|
---|
417 | DATA_BLOB auth_blob;
|
---|
418 | char *trust_pw = NULL;
|
---|
419 | struct other_dom_data *other_dom_data;
|
---|
420 | struct net_context *other_net_ctx = NULL;
|
---|
421 | struct dom_data dom_data[2];
|
---|
422 | void (*usage)(void);
|
---|
423 |
|
---|
424 | switch (op) {
|
---|
425 | case TRUST_CREATE:
|
---|
426 | usage = print_trust_usage;
|
---|
427 | break;
|
---|
428 | case TRUST_DELETE:
|
---|
429 | usage = print_trust_delete_usage;
|
---|
430 | break;
|
---|
431 | default:
|
---|
432 | DEBUG(0, ("Unsupported trust operation.\n"));
|
---|
433 | return -1;
|
---|
434 | }
|
---|
435 |
|
---|
436 | if (net_ctx->display_usage) {
|
---|
437 | usage();
|
---|
438 | return 0;
|
---|
439 | }
|
---|
440 |
|
---|
441 | mem_ctx = talloc_init("trust op");
|
---|
442 | if (mem_ctx == NULL) {
|
---|
443 | DEBUG(0, ("talloc_init failed.\n"));
|
---|
444 | return -1;
|
---|
445 | }
|
---|
446 |
|
---|
447 | ret = parse_trust_args(mem_ctx, argc, argv, &other_dom_data, &trust_pw);
|
---|
448 | if (ret != 0) {
|
---|
449 | if (ret == EINVAL) {
|
---|
450 | usage();
|
---|
451 | } else {
|
---|
452 | DEBUG(0, ("Failed to parse arguments.\n"));
|
---|
453 | }
|
---|
454 | goto done;
|
---|
455 | }
|
---|
456 |
|
---|
457 | if (other_dom_data->host != 0) {
|
---|
458 | other_net_ctx = talloc_zero(other_dom_data, struct net_context);
|
---|
459 | if (other_net_ctx == NULL) {
|
---|
460 | DEBUG(0, ("talloc_zero failed.\n"));
|
---|
461 | goto done;
|
---|
462 | }
|
---|
463 |
|
---|
464 | other_net_ctx->opt_host = other_dom_data->host;
|
---|
465 | other_net_ctx->opt_user_name = other_dom_data->user_name;
|
---|
466 | } else {
|
---|
467 | dom_data[1].domsid = dom_sid_parse_talloc(mem_ctx,
|
---|
468 | other_dom_data->domain_sid_str);
|
---|
469 | dom_data[1].domain_name = other_dom_data->domain_name;
|
---|
470 | dom_data[1].dns_domain_name = other_dom_data->dns_domain_name;
|
---|
471 |
|
---|
472 | if (dom_data[1].domsid == NULL ||
|
---|
473 | (op == TRUST_CREATE &&
|
---|
474 | (dom_data[1].domain_name == NULL ||
|
---|
475 | dom_data[1].dns_domain_name == NULL))) {
|
---|
476 | DEBUG(0, ("Missing required argument.\n"));
|
---|
477 | usage();
|
---|
478 | goto done;
|
---|
479 | }
|
---|
480 | }
|
---|
481 |
|
---|
482 | status = connect_and_get_info(mem_ctx, net_ctx, &cli[0], &pipe_hnd[0],
|
---|
483 | &pol_hnd[0], &dom_data[0]);
|
---|
484 | if (!NT_STATUS_IS_OK(status)) {
|
---|
485 | DEBUG(0, ("connect_and_get_info failed with error [%s]\n",
|
---|
486 | nt_errstr(status)));
|
---|
487 | goto done;
|
---|
488 | }
|
---|
489 |
|
---|
490 | if (other_net_ctx != NULL) {
|
---|
491 | status = connect_and_get_info(mem_ctx, other_net_ctx,
|
---|
492 | &cli[1], &pipe_hnd[1],
|
---|
493 | &pol_hnd[1], &dom_data[1]);
|
---|
494 | if (!NT_STATUS_IS_OK(status)) {
|
---|
495 | DEBUG(0, ("connect_and_get_info failed with error [%s]\n",
|
---|
496 | nt_errstr(status)));
|
---|
497 | goto done;
|
---|
498 | }
|
---|
499 | }
|
---|
500 |
|
---|
501 | if (op == TRUST_CREATE) {
|
---|
502 | if (trust_pw == NULL) {
|
---|
503 | if (other_net_ctx == NULL) {
|
---|
504 | DEBUG(0, ("Missing either trustpw or otherhost.\n"));
|
---|
505 | goto done;
|
---|
506 | }
|
---|
507 |
|
---|
508 | DEBUG(0, ("Using random trust password.\n"));
|
---|
509 | /* FIXME: why only 8 characters work? Would it be possible to use a
|
---|
510 | * random binary password? */
|
---|
511 | trust_pw = generate_random_str(mem_ctx, 8);
|
---|
512 | if (trust_pw == NULL) {
|
---|
513 | DEBUG(0, ("generate_random_str failed.\n"));
|
---|
514 | goto done;
|
---|
515 | }
|
---|
516 | } else {
|
---|
517 | DEBUG(0, ("Using user provided password.\n"));
|
---|
518 | }
|
---|
519 |
|
---|
520 | if (!get_trust_domain_passwords_auth_blob(mem_ctx, trust_pw,
|
---|
521 | &auth_blob)) {
|
---|
522 | DEBUG(0, ("get_trust_domain_passwords_auth_blob failed\n"));
|
---|
523 | goto done;
|
---|
524 | }
|
---|
525 |
|
---|
526 | authinfo.auth_blob.data = (uint8_t *)talloc_memdup(
|
---|
527 | mem_ctx,
|
---|
528 | auth_blob.data,
|
---|
529 | auth_blob.length);
|
---|
530 | if (authinfo.auth_blob.data == NULL) {
|
---|
531 | goto done;
|
---|
532 | }
|
---|
533 | authinfo.auth_blob.size = auth_blob.length;
|
---|
534 |
|
---|
535 | arcfour_crypt_blob(authinfo.auth_blob.data,
|
---|
536 | authinfo.auth_blob.size,
|
---|
537 | &cli[0]->user_session_key);
|
---|
538 |
|
---|
539 | status = create_trust(mem_ctx, pipe_hnd[0]->binding_handle,
|
---|
540 | &pol_hnd[0],
|
---|
541 | dom_data[1].domain_name,
|
---|
542 | dom_data[1].dns_domain_name,
|
---|
543 | dom_data[1].domsid,
|
---|
544 | &authinfo);
|
---|
545 | if (!NT_STATUS_IS_OK(status)) {
|
---|
546 | DEBUG(0, ("create_trust failed with error [%s].\n",
|
---|
547 | nt_errstr(status)));
|
---|
548 | goto done;
|
---|
549 | }
|
---|
550 |
|
---|
551 | if (other_net_ctx != NULL) {
|
---|
552 | talloc_free(authinfo.auth_blob.data);
|
---|
553 | authinfo.auth_blob.data = (uint8_t *)talloc_memdup(
|
---|
554 | mem_ctx,
|
---|
555 | auth_blob.data,
|
---|
556 | auth_blob.length);
|
---|
557 | if (authinfo.auth_blob.data == NULL) {
|
---|
558 | goto done;
|
---|
559 | }
|
---|
560 | authinfo.auth_blob.size = auth_blob.length;
|
---|
561 |
|
---|
562 | arcfour_crypt_blob(authinfo.auth_blob.data,
|
---|
563 | authinfo.auth_blob.size,
|
---|
564 | &cli[1]->user_session_key);
|
---|
565 |
|
---|
566 | status = create_trust(mem_ctx,
|
---|
567 | pipe_hnd[1]->binding_handle,
|
---|
568 | &pol_hnd[1],
|
---|
569 | dom_data[0].domain_name,
|
---|
570 | dom_data[0].dns_domain_name,
|
---|
571 | dom_data[0].domsid, &authinfo);
|
---|
572 | if (!NT_STATUS_IS_OK(status)) {
|
---|
573 | DEBUG(0, ("create_trust failed with error [%s].\n",
|
---|
574 | nt_errstr(status)));
|
---|
575 | goto done;
|
---|
576 | }
|
---|
577 | }
|
---|
578 | } else if (op == TRUST_DELETE) {
|
---|
579 | status = delete_trust(mem_ctx, pipe_hnd[0]->binding_handle,
|
---|
580 | &pol_hnd[0], dom_data[1].domsid);
|
---|
581 | if (!NT_STATUS_IS_OK(status)) {
|
---|
582 | DEBUG(0, ("delete_trust failed with [%s].\n",
|
---|
583 | nt_errstr(status)));
|
---|
584 | goto done;
|
---|
585 | }
|
---|
586 |
|
---|
587 | if (other_net_ctx != NULL) {
|
---|
588 | status = delete_trust(mem_ctx,
|
---|
589 | pipe_hnd[1]->binding_handle,
|
---|
590 | &pol_hnd[1], dom_data[0].domsid);
|
---|
591 | if (!NT_STATUS_IS_OK(status)) {
|
---|
592 | DEBUG(0, ("delete_trust failed with [%s].\n",
|
---|
593 | nt_errstr(status)));
|
---|
594 | goto done;
|
---|
595 | }
|
---|
596 | }
|
---|
597 | }
|
---|
598 |
|
---|
599 | status = close_handle(mem_ctx, pipe_hnd[0]->binding_handle,
|
---|
600 | &pol_hnd[0]);
|
---|
601 | if (!NT_STATUS_IS_OK(status)) {
|
---|
602 | DEBUG(0, ("close_handle failed with error [%s].\n",
|
---|
603 | nt_errstr(status)));
|
---|
604 | goto done;
|
---|
605 | }
|
---|
606 |
|
---|
607 | if (other_net_ctx != NULL) {
|
---|
608 | status = close_handle(mem_ctx, pipe_hnd[1]->binding_handle,
|
---|
609 | &pol_hnd[1]);
|
---|
610 | if (!NT_STATUS_IS_OK(status)) {
|
---|
611 | DEBUG(0, ("close_handle failed with error [%s].\n",
|
---|
612 | nt_errstr(status)));
|
---|
613 | goto done;
|
---|
614 | }
|
---|
615 | }
|
---|
616 |
|
---|
617 | success = 0;
|
---|
618 |
|
---|
619 | done:
|
---|
620 | cli_shutdown(cli[0]);
|
---|
621 | cli_shutdown(cli[1]);
|
---|
622 | talloc_destroy(mem_ctx);
|
---|
623 | return success;
|
---|
624 | }
|
---|
625 |
|
---|
626 | static int rpc_trust_create(struct net_context *net_ctx, int argc,
|
---|
627 | const char **argv)
|
---|
628 | {
|
---|
629 | return rpc_trust_common(net_ctx, argc, argv, TRUST_CREATE);
|
---|
630 | }
|
---|
631 |
|
---|
632 | static int rpc_trust_delete(struct net_context *net_ctx, int argc,
|
---|
633 | const char **argv)
|
---|
634 | {
|
---|
635 | return rpc_trust_common(net_ctx, argc, argv, TRUST_DELETE);
|
---|
636 | }
|
---|
637 |
|
---|
638 | int net_rpc_trust(struct net_context *c, int argc, const char **argv)
|
---|
639 | {
|
---|
640 | struct functable func[] = {
|
---|
641 | {
|
---|
642 | "create",
|
---|
643 | rpc_trust_create,
|
---|
644 | NET_TRANSPORT_RPC,
|
---|
645 | N_("Create trusts"),
|
---|
646 | N_("net rpc trust create\n"
|
---|
647 | " Create trusts")
|
---|
648 | },
|
---|
649 | {
|
---|
650 | "delete",
|
---|
651 | rpc_trust_delete,
|
---|
652 | NET_TRANSPORT_RPC,
|
---|
653 | N_("Remove trusts"),
|
---|
654 | N_("net rpc trust delete\n"
|
---|
655 | " Remove trusts")
|
---|
656 | },
|
---|
657 | {NULL, NULL, 0, NULL, NULL}
|
---|
658 | };
|
---|
659 |
|
---|
660 | return net_run_function(c, argc, argv, "net rpc trust", func);
|
---|
661 | }
|
---|