Line data Source code
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 "../libcli/security/dom_sid.h"
27 : #include "libsmb/libsmb.h"
28 :
29 : #include "lib/crypto/gnutls_helpers.h"
30 : #include <gnutls/gnutls.h>
31 : #include <gnutls/crypto.h>
32 :
33 : #define ARG_OTHERSERVER "otherserver="
34 : #define ARG_OTHERUSER "otheruser="
35 : #define ARG_OTHERDOMAINSID "otherdomainsid="
36 : #define ARG_OTHERDOMAIN "otherdomain="
37 : #define ARG_OTHERNETBIOSDOMAIN "other_netbios_domain="
38 : #define ARG_TRUSTPW "trustpw="
39 :
40 : enum trust_op {
41 : TRUST_CREATE,
42 : TRUST_DELETE
43 : };
44 :
45 : struct other_dom_data {
46 : char *host;
47 : char *user_name;
48 : char *domain_sid_str;
49 : char *dns_domain_name;
50 : char *domain_name;
51 : };
52 :
53 : struct dom_data {
54 : struct dom_sid *domsid;
55 : char *dns_domain_name;
56 : char *domain_name;
57 : };
58 :
59 0 : static NTSTATUS close_handle(TALLOC_CTX *mem_ctx,
60 : struct dcerpc_binding_handle *bind_hnd,
61 : struct policy_handle *pol_hnd)
62 : {
63 0 : NTSTATUS status;
64 0 : NTSTATUS result;
65 :
66 0 : status = dcerpc_lsa_Close(bind_hnd, mem_ctx, pol_hnd, &result);
67 0 : if (!NT_STATUS_IS_OK(status)) {
68 0 : DEBUG(0, ("dcerpc_lsa_Close failed with error [%s].\n",
69 : nt_errstr(status)));
70 0 : return status;
71 : }
72 0 : if (!NT_STATUS_IS_OK(result)) {
73 0 : DEBUG(0, ("lsa close failed with error [%s].\n",
74 : nt_errstr(result)));
75 0 : return result;
76 : }
77 :
78 0 : return NT_STATUS_OK;
79 : }
80 :
81 0 : static NTSTATUS delete_trust(TALLOC_CTX *mem_ctx,
82 : struct dcerpc_binding_handle *bind_hnd,
83 : struct policy_handle *pol_hnd,
84 : struct dom_sid *domsid)
85 : {
86 0 : NTSTATUS status;
87 0 : struct lsa_DeleteTrustedDomain dr;
88 :
89 0 : dr.in.handle = pol_hnd;
90 0 : dr.in.dom_sid = domsid;
91 :
92 0 : status = dcerpc_lsa_DeleteTrustedDomain_r(bind_hnd, mem_ctx, &dr);
93 0 : if (!NT_STATUS_IS_OK(status)) {
94 0 : DEBUG(0, ("dcerpc_lsa_DeleteTrustedDomain_r failed with [%s]\n",
95 : nt_errstr(status)));
96 0 : return status;
97 : }
98 0 : if (!NT_STATUS_IS_OK(dr.out.result)) {
99 0 : DEBUG(0, ("DeleteTrustedDomain returned [%s]\n",
100 : nt_errstr(dr.out.result)));
101 0 : return dr.out.result;
102 : }
103 :
104 0 : return NT_STATUS_OK;
105 : }
106 :
107 0 : static NTSTATUS create_trust(TALLOC_CTX *mem_ctx,
108 : struct dcerpc_binding_handle *bind_hnd,
109 : struct policy_handle *pol_hnd,
110 : const char *trust_name,
111 : const char *trust_name_dns,
112 : struct dom_sid *domsid,
113 : struct lsa_TrustDomainInfoAuthInfoInternal *authinfo)
114 : {
115 0 : NTSTATUS status;
116 0 : struct lsa_CreateTrustedDomainEx2 r;
117 0 : struct lsa_TrustDomainInfoInfoEx trustinfo;
118 0 : struct policy_handle trustdom_handle;
119 :
120 0 : trustinfo.sid = domsid;
121 0 : trustinfo.netbios_name.string = trust_name;
122 0 : trustinfo.domain_name.string = trust_name_dns;
123 :
124 0 : trustinfo.trust_direction = LSA_TRUST_DIRECTION_INBOUND |
125 : LSA_TRUST_DIRECTION_OUTBOUND;
126 :
127 0 : trustinfo.trust_type = LSA_TRUST_TYPE_UPLEVEL;
128 :
129 0 : trustinfo.trust_attributes = LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE;
130 :
131 0 : r.in.policy_handle = pol_hnd;
132 0 : r.in.info = &trustinfo;
133 0 : r.in.auth_info_internal = authinfo;
134 0 : r.in.access_mask = LSA_TRUSTED_SET_POSIX | LSA_TRUSTED_SET_AUTH |
135 : LSA_TRUSTED_QUERY_DOMAIN_NAME;
136 0 : r.out.trustdom_handle = &trustdom_handle;
137 :
138 0 : status = dcerpc_lsa_CreateTrustedDomainEx2_r(bind_hnd, mem_ctx, &r);
139 0 : if (!NT_STATUS_IS_OK(status)) {
140 0 : DEBUG(0, ("dcerpc_lsa_CreateTrustedDomainEx2_r failed "
141 : "with error [%s].\n", nt_errstr(status)));
142 0 : return status;
143 : }
144 0 : if (!NT_STATUS_IS_OK(r.out.result)) {
145 0 : DEBUG(0, ("CreateTrustedDomainEx2_r returned [%s].\n",
146 : nt_errstr(r.out.result)));
147 0 : return r.out.result;
148 : }
149 :
150 0 : return NT_STATUS_OK;
151 : }
152 :
153 0 : static NTSTATUS get_domain_info(TALLOC_CTX *mem_ctx,
154 : struct dcerpc_binding_handle *bind_hdn,
155 : struct policy_handle *pol_hnd,
156 : struct dom_data *dom_data)
157 : {
158 0 : NTSTATUS status;
159 0 : struct lsa_QueryInfoPolicy2 qr;
160 0 : struct dom_sid_buf buf;
161 :
162 0 : qr.in.handle = pol_hnd;
163 0 : qr.in.level = LSA_POLICY_INFO_DNS;
164 :
165 0 : status = dcerpc_lsa_QueryInfoPolicy2_r(bind_hdn, mem_ctx, &qr);
166 0 : if (!NT_STATUS_IS_OK(status)) {
167 0 : DEBUG(0, ("dcerpc_lsa_QueryInfoPolicy2_r failed "
168 : "with error [%s].\n", nt_errstr(status)));
169 0 : return status;
170 : }
171 :
172 0 : if (!NT_STATUS_IS_OK(qr.out.result)) {
173 0 : DEBUG(0, ("QueryInfoPolicy2 returned [%s].\n",
174 : nt_errstr(qr.out.result)));
175 0 : return qr.out.result;
176 : }
177 :
178 0 : dom_data->domain_name = talloc_strdup(mem_ctx,
179 0 : (*qr.out.info)->dns.name.string);
180 0 : dom_data->dns_domain_name = talloc_strdup(mem_ctx,
181 0 : (*qr.out.info)->dns.dns_domain.string);
182 0 : dom_data->domsid = dom_sid_dup(mem_ctx, (*qr.out.info)->dns.sid);
183 0 : if (dom_data->domain_name == NULL ||
184 0 : dom_data->dns_domain_name == NULL ||
185 0 : dom_data->domsid == NULL) {
186 0 : DEBUG(0, ("Copying domain data failed.\n"));
187 0 : return NT_STATUS_NO_MEMORY;
188 : }
189 :
190 0 : DEBUG(0, ("Got the following domain info [%s][%s][%s].\n",
191 : dom_data->domain_name, dom_data->dns_domain_name,
192 : dom_sid_str_buf(dom_data->domsid, &buf)));
193 :
194 0 : return NT_STATUS_OK;
195 : }
196 :
197 0 : static NTSTATUS connect_and_get_info(TALLOC_CTX *mem_ctx,
198 : struct net_context *net_ctx,
199 : struct cli_state **cli,
200 : struct rpc_pipe_client **pipe_hnd,
201 : struct policy_handle *pol_hnd,
202 : struct dom_data *dom_data,
203 : DATA_BLOB *session_key)
204 : {
205 0 : NTSTATUS status;
206 0 : NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
207 0 : uint32_t out_version = 0;
208 0 : union lsa_revision_info out_revision_info = {
209 : .info1 = {
210 : .revision = 0,
211 : },
212 : };
213 :
214 0 : status = net_make_ipc_connection_ex(net_ctx, NULL, NULL, NULL,
215 : NET_FLAGS_PDC, cli);
216 0 : if (!NT_STATUS_IS_OK(status)) {
217 0 : DEBUG(0, ("Failed to connect to [%s] with error [%s]\n",
218 : net_ctx->opt_host, nt_errstr(status)));
219 0 : return status;
220 : }
221 :
222 0 : status = cli_rpc_pipe_open_noauth(*cli, &ndr_table_lsarpc, pipe_hnd);
223 0 : if (!NT_STATUS_IS_OK(status)) {
224 0 : DEBUG(0, ("Failed to initialise lsa pipe with error [%s]\n",
225 : nt_errstr(status)));
226 0 : return status;
227 : }
228 :
229 0 : status = dcerpc_lsa_open_policy_fallback(
230 0 : (*pipe_hnd)->binding_handle,
231 : mem_ctx,
232 0 : (*pipe_hnd)->srv_name_slash,
233 : false,
234 : LSA_POLICY_VIEW_LOCAL_INFORMATION |
235 : LSA_POLICY_TRUST_ADMIN |
236 : LSA_POLICY_CREATE_SECRET,
237 : &out_version,
238 : &out_revision_info,
239 : pol_hnd,
240 : &result);
241 0 : if (any_nt_status_not_ok(status, result, &status)) {
242 0 : DBG_ERR("Failed to open policy handle: %s\n",
243 : nt_errstr(result));
244 0 : return status;
245 : }
246 :
247 0 : status = get_domain_info(mem_ctx, (*pipe_hnd)->binding_handle,
248 : pol_hnd, dom_data);
249 0 : if (!NT_STATUS_IS_OK(status)) {
250 0 : DEBUG(0, ("get_domain_info failed with error [%s].\n",
251 : nt_errstr(status)));
252 0 : return status;
253 : }
254 :
255 0 : status = cli_get_session_key(mem_ctx, *pipe_hnd, session_key);
256 0 : if (!NT_STATUS_IS_OK(status)) {
257 0 : DEBUG(0,("Error getting session_key of LSA pipe. Error was %s\n",
258 : nt_errstr(status)));
259 0 : return status;
260 : }
261 :
262 0 : return NT_STATUS_OK;
263 : }
264 :
265 0 : static bool get_trust_domain_passwords_auth_blob(TALLOC_CTX *mem_ctx,
266 : const char *password,
267 : DATA_BLOB *auth_blob)
268 : {
269 0 : struct trustDomainPasswords auth_struct;
270 0 : struct AuthenticationInformation *auth_info_array;
271 0 : enum ndr_err_code ndr_err;
272 0 : size_t converted_size;
273 :
274 0 : generate_random_buffer(auth_struct.confounder,
275 : sizeof(auth_struct.confounder));
276 :
277 0 : auth_info_array = talloc_array(mem_ctx,
278 : struct AuthenticationInformation, 1);
279 0 : if (auth_info_array == NULL) {
280 0 : return false;
281 : }
282 :
283 0 : auth_info_array[0].AuthType = TRUST_AUTH_TYPE_CLEAR;
284 0 : if (!convert_string_talloc(mem_ctx, CH_UNIX, CH_UTF16, password,
285 : strlen(password),
286 0 : &auth_info_array[0].AuthInfo.clear.password,
287 : &converted_size)) {
288 0 : return false;
289 : }
290 :
291 0 : auth_info_array[0].AuthInfo.clear.size = converted_size;
292 :
293 0 : auth_struct.outgoing.count = 1;
294 0 : auth_struct.outgoing.current.count = 1;
295 0 : auth_struct.outgoing.current.array = auth_info_array;
296 0 : auth_struct.outgoing.previous.count = 0;
297 0 : auth_struct.outgoing.previous.array = NULL;
298 :
299 0 : auth_struct.incoming.count = 1;
300 0 : auth_struct.incoming.current.count = 1;
301 0 : auth_struct.incoming.current.array = auth_info_array;
302 0 : auth_struct.incoming.previous.count = 0;
303 0 : auth_struct.incoming.previous.array = NULL;
304 :
305 0 : ndr_err = ndr_push_struct_blob(auth_blob, mem_ctx, &auth_struct,
306 : (ndr_push_flags_fn_t)ndr_push_trustDomainPasswords);
307 0 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
308 0 : return false;
309 : }
310 :
311 0 : return true;
312 : }
313 :
314 0 : static int parse_trust_args(TALLOC_CTX *mem_ctx, int argc, const char **argv, struct other_dom_data **_o, char **_trustpw)
315 : {
316 0 : size_t c;
317 0 : struct other_dom_data *o = NULL;
318 0 : char *trustpw = NULL;
319 0 : int ret = EFAULT;
320 :
321 0 : if (argc == 0) {
322 0 : return EINVAL;
323 : }
324 :
325 0 : o = talloc_zero(mem_ctx, struct other_dom_data);
326 0 : if (o == NULL) {
327 0 : DEBUG(0, ("talloc_zero failed.\n"));
328 0 : return ENOMEM;
329 : }
330 :
331 0 : for (c = 0; c < argc; c++) {
332 0 : if (strnequal(argv[c], ARG_OTHERSERVER, sizeof(ARG_OTHERSERVER)-1)) {
333 0 : o->host = talloc_strdup(o, argv[c] + sizeof(ARG_OTHERSERVER)-1);
334 0 : if (o->host == NULL) {
335 0 : ret = ENOMEM;
336 0 : goto failed;
337 : }
338 0 : } else if (strnequal(argv[c], ARG_OTHERUSER, sizeof(ARG_OTHERUSER)-1)) {
339 0 : o->user_name = talloc_strdup(o, argv[c] + sizeof(ARG_OTHERUSER)-1);
340 0 : if (o->user_name == NULL) {
341 0 : ret = ENOMEM;
342 0 : goto failed;
343 : }
344 0 : } else if (strnequal(argv[c], ARG_OTHERDOMAINSID, sizeof(ARG_OTHERDOMAINSID)-1)) {
345 0 : o->domain_sid_str = talloc_strdup(o, argv[c] + sizeof(ARG_OTHERDOMAINSID)-1);
346 0 : if (o->domain_sid_str == NULL) {
347 0 : ret = ENOMEM;
348 0 : goto failed;
349 : }
350 0 : } else if (strnequal(argv[c], ARG_OTHERDOMAIN, sizeof(ARG_OTHERDOMAIN)-1)) {
351 0 : o->dns_domain_name = talloc_strdup(o, argv[c] + sizeof(ARG_OTHERDOMAIN)-1);
352 0 : if (o->dns_domain_name == NULL) {
353 0 : ret = ENOMEM;
354 0 : goto failed;
355 : }
356 0 : } else if (strnequal(argv[c], ARG_OTHERNETBIOSDOMAIN, sizeof(ARG_OTHERNETBIOSDOMAIN)-1)) {
357 0 : o->domain_name = talloc_strdup(o, argv[c] + sizeof(ARG_OTHERNETBIOSDOMAIN)-1);
358 0 : if (o->domain_name == NULL) {
359 0 : ret = ENOMEM;
360 0 : goto failed;
361 : }
362 0 : } else if (strnequal(argv[c], ARG_TRUSTPW, sizeof(ARG_TRUSTPW)-1)) {
363 0 : trustpw = talloc_strdup(mem_ctx, argv[c] + sizeof(ARG_TRUSTPW)-1);
364 0 : if (trustpw == NULL) {
365 0 : ret = ENOMEM;
366 0 : goto failed;
367 : }
368 : } else {
369 0 : DEBUG(0, ("Unsupported option [%s].\n", argv[c]));
370 0 : ret = EINVAL;
371 0 : goto failed;
372 : }
373 : }
374 :
375 0 : *_o = o;
376 0 : *_trustpw = trustpw;
377 :
378 0 : return 0;
379 :
380 0 : failed:
381 0 : talloc_free(o);
382 0 : talloc_free(trustpw);
383 0 : return ret;
384 : }
385 :
386 0 : static void print_trust_delete_usage(void)
387 : {
388 0 : d_printf( "%s\n"
389 : "net rpc trust delete [options]\n"
390 : "\nOptions:\n"
391 : "\totherserver=DC in other domain\n"
392 : "\totheruser=Admin user in other domain\n"
393 : "\totherdomainsid=SID of other domain\n"
394 : "\nExamples:\n"
395 : "\tnet rpc trust delete otherserver=oname otheruser=ouser -S lname -U luser\n"
396 : "\tnet rpc trust delete otherdomainsid=S-... -S lname -U luser\n"
397 : " %s\n",
398 : _("Usage:"),
399 : _("Remove trust between two domains"));
400 0 : }
401 :
402 0 : static void print_trust_usage(void)
403 : {
404 0 : d_printf( "%s\n"
405 : "net rpc trust create [options]\n"
406 : "\nOptions:\n"
407 : "\totherserver=DC in other domain\n"
408 : "\totheruser=Admin user in other domain\n"
409 : "\totherdomainsid=SID of other domain\n"
410 : "\tother_netbios_domain=NetBIOS/short name of other domain\n"
411 : "\totherdomain=Full/DNS name of other domain\n"
412 : "\ttrustpw=Trust password\n"
413 : "\nExamples:\n"
414 : "\tnet rpc trust create otherserver=oname otheruser=ouser -S lname -U luser\n"
415 : "\tnet rpc trust create otherdomainsid=S-... other_netbios_domain=odom otherdomain=odom.org trustpw=secret -S lname -U luser\n"
416 : " %s\n",
417 : _("Usage:"),
418 : _("Create trust between two domains"));
419 0 : }
420 :
421 0 : static int rpc_trust_common(struct net_context *net_ctx, int argc,
422 : const char **argv, enum trust_op op)
423 : {
424 0 : TALLOC_CTX *mem_ctx;
425 0 : NTSTATUS status;
426 0 : int ret;
427 0 : int success = -1;
428 0 : struct cli_state *cli[2] = {NULL, NULL};
429 0 : struct rpc_pipe_client *pipe_hnd[2] = {NULL, NULL};
430 0 : DATA_BLOB session_key[2];
431 0 : struct policy_handle pol_hnd[2];
432 0 : struct lsa_TrustDomainInfoAuthInfoInternal authinfo;
433 0 : DATA_BLOB auth_blob;
434 0 : char *trust_pw = NULL;
435 0 : struct other_dom_data *other_dom_data;
436 0 : struct net_context *other_net_ctx = NULL;
437 0 : struct dom_data dom_data[2];
438 0 : void (*usage)(void);
439 :
440 0 : ZERO_STRUCT(session_key);
441 :
442 0 : switch (op) {
443 0 : case TRUST_CREATE:
444 0 : usage = print_trust_usage;
445 0 : break;
446 0 : case TRUST_DELETE:
447 0 : usage = print_trust_delete_usage;
448 0 : break;
449 0 : default:
450 0 : DEBUG(0, ("Unsupported trust operation.\n"));
451 0 : return -1;
452 : }
453 :
454 0 : if (net_ctx->display_usage) {
455 0 : usage();
456 0 : return 0;
457 : }
458 :
459 0 : mem_ctx = talloc_init("trust op");
460 0 : if (mem_ctx == NULL) {
461 0 : DEBUG(0, ("talloc_init failed.\n"));
462 0 : return -1;
463 : }
464 :
465 0 : ret = parse_trust_args(mem_ctx, argc, argv, &other_dom_data, &trust_pw);
466 0 : if (ret != 0) {
467 0 : if (ret == EINVAL) {
468 0 : usage();
469 : } else {
470 0 : DEBUG(0, ("Failed to parse arguments.\n"));
471 : }
472 0 : goto done;
473 : }
474 :
475 0 : if (other_dom_data->host != 0) {
476 0 : other_net_ctx = talloc_zero(other_dom_data, struct net_context);
477 0 : if (other_net_ctx == NULL) {
478 0 : DEBUG(0, ("talloc_zero failed.\n"));
479 0 : goto done;
480 : }
481 :
482 0 : other_net_ctx->opt_host = other_dom_data->host;
483 0 : other_net_ctx->opt_user_name = other_dom_data->user_name;
484 0 : other_net_ctx->opt_user_specified = true;
485 : } else {
486 0 : dom_data[1].domsid = dom_sid_parse_talloc(mem_ctx,
487 0 : other_dom_data->domain_sid_str);
488 0 : dom_data[1].domain_name = other_dom_data->domain_name;
489 0 : dom_data[1].dns_domain_name = other_dom_data->dns_domain_name;
490 :
491 0 : if (dom_data[1].domsid == NULL ||
492 0 : (op == TRUST_CREATE &&
493 0 : (dom_data[1].domain_name == NULL ||
494 0 : dom_data[1].dns_domain_name == NULL))) {
495 0 : DEBUG(0, ("Missing required argument.\n"));
496 0 : usage();
497 0 : goto done;
498 : }
499 : }
500 :
501 0 : status = connect_and_get_info(mem_ctx, net_ctx, &cli[0], &pipe_hnd[0],
502 : &pol_hnd[0], &dom_data[0], &session_key[0]);
503 0 : if (!NT_STATUS_IS_OK(status)) {
504 0 : DEBUG(0, ("connect_and_get_info failed with error [%s]\n",
505 : nt_errstr(status)));
506 0 : goto done;
507 : }
508 :
509 0 : if (other_net_ctx != NULL) {
510 0 : status = connect_and_get_info(mem_ctx, other_net_ctx,
511 : &cli[1], &pipe_hnd[1],
512 : &pol_hnd[1], &dom_data[1],
513 : &session_key[1]);
514 0 : if (!NT_STATUS_IS_OK(status)) {
515 0 : DEBUG(0, ("connect_and_get_info failed with error [%s]\n",
516 : nt_errstr(status)));
517 0 : goto done;
518 : }
519 : }
520 :
521 0 : if (op == TRUST_CREATE) {
522 0 : gnutls_cipher_hd_t cipher_hnd = NULL;
523 0 : gnutls_datum_t enc_session_key = {
524 0 : .data = session_key[0].data,
525 0 : .size = session_key[0].length,
526 : };
527 0 : int rc;
528 :
529 0 : if (trust_pw == NULL) {
530 0 : if (other_net_ctx == NULL) {
531 0 : DEBUG(0, ("Missing either trustpw or otherhost.\n"));
532 0 : goto done;
533 : }
534 :
535 0 : DEBUG(0, ("Using random trust password.\n"));
536 0 : trust_pw = trust_pw_new_value(mem_ctx,
537 : SEC_CHAN_DOMAIN,
538 : SEC_DOMAIN);
539 0 : if (trust_pw == NULL) {
540 0 : DEBUG(0, ("generate_random_password failed.\n"));
541 0 : goto done;
542 : }
543 : } else {
544 0 : DEBUG(0, ("Using user provided password.\n"));
545 : }
546 :
547 0 : if (!get_trust_domain_passwords_auth_blob(mem_ctx, trust_pw,
548 : &auth_blob)) {
549 0 : DEBUG(0, ("get_trust_domain_passwords_auth_blob failed\n"));
550 0 : goto done;
551 : }
552 :
553 0 : authinfo.auth_blob.data = (uint8_t *)talloc_memdup(
554 : mem_ctx,
555 : auth_blob.data,
556 : auth_blob.length);
557 0 : if (authinfo.auth_blob.data == NULL) {
558 0 : goto done;
559 : }
560 0 : authinfo.auth_blob.size = auth_blob.length;
561 :
562 0 : rc = gnutls_cipher_init(&cipher_hnd,
563 : GNUTLS_CIPHER_ARCFOUR_128,
564 : &enc_session_key,
565 : NULL);
566 0 : if (rc < 0) {
567 0 : status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
568 0 : goto done;
569 : }
570 0 : rc = gnutls_cipher_encrypt(cipher_hnd,
571 0 : authinfo.auth_blob.data,
572 0 : authinfo.auth_blob.size);
573 0 : gnutls_cipher_deinit(cipher_hnd);
574 0 : if (rc < 0) {
575 0 : status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
576 0 : goto done;
577 : }
578 :
579 0 : status = create_trust(mem_ctx, pipe_hnd[0]->binding_handle,
580 : &pol_hnd[0],
581 0 : dom_data[1].domain_name,
582 0 : dom_data[1].dns_domain_name,
583 : dom_data[1].domsid,
584 : &authinfo);
585 0 : if (!NT_STATUS_IS_OK(status)) {
586 0 : DEBUG(0, ("create_trust failed with error [%s].\n",
587 : nt_errstr(status)));
588 0 : goto done;
589 : }
590 :
591 0 : if (other_net_ctx != NULL) {
592 0 : talloc_free(authinfo.auth_blob.data);
593 0 : authinfo.auth_blob.data = (uint8_t *)talloc_memdup(
594 : mem_ctx,
595 : auth_blob.data,
596 : auth_blob.length);
597 0 : if (authinfo.auth_blob.data == NULL) {
598 0 : goto done;
599 : }
600 0 : authinfo.auth_blob.size = auth_blob.length;
601 :
602 0 : enc_session_key = (gnutls_datum_t) {
603 0 : .data = session_key[1].data,
604 0 : .size = session_key[1].length,
605 : };
606 :
607 0 : rc = gnutls_cipher_init(&cipher_hnd,
608 : GNUTLS_CIPHER_ARCFOUR_128,
609 : &enc_session_key,
610 : NULL);
611 0 : if (rc < 0) {
612 0 : status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
613 0 : goto done;
614 : }
615 0 : rc = gnutls_cipher_encrypt(cipher_hnd,
616 0 : authinfo.auth_blob.data,
617 0 : authinfo.auth_blob.size);
618 0 : gnutls_cipher_deinit(cipher_hnd);
619 0 : if (rc < 0) {
620 0 : status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
621 0 : goto done;
622 : }
623 :
624 0 : status = create_trust(mem_ctx,
625 0 : pipe_hnd[1]->binding_handle,
626 : &pol_hnd[1],
627 0 : dom_data[0].domain_name,
628 0 : dom_data[0].dns_domain_name,
629 : dom_data[0].domsid, &authinfo);
630 0 : if (!NT_STATUS_IS_OK(status)) {
631 0 : DEBUG(0, ("create_trust failed with error [%s].\n",
632 : nt_errstr(status)));
633 0 : goto done;
634 : }
635 : }
636 0 : } else if (op == TRUST_DELETE) {
637 0 : status = delete_trust(mem_ctx, pipe_hnd[0]->binding_handle,
638 : &pol_hnd[0], dom_data[1].domsid);
639 0 : if (!NT_STATUS_IS_OK(status)) {
640 0 : DEBUG(0, ("delete_trust failed with [%s].\n",
641 : nt_errstr(status)));
642 0 : goto done;
643 : }
644 :
645 0 : if (other_net_ctx != NULL) {
646 0 : status = delete_trust(mem_ctx,
647 0 : pipe_hnd[1]->binding_handle,
648 : &pol_hnd[1], dom_data[0].domsid);
649 0 : if (!NT_STATUS_IS_OK(status)) {
650 0 : DEBUG(0, ("delete_trust failed with [%s].\n",
651 : nt_errstr(status)));
652 0 : goto done;
653 : }
654 : }
655 : }
656 :
657 0 : status = close_handle(mem_ctx, pipe_hnd[0]->binding_handle,
658 : &pol_hnd[0]);
659 0 : if (!NT_STATUS_IS_OK(status)) {
660 0 : DEBUG(0, ("close_handle failed with error [%s].\n",
661 : nt_errstr(status)));
662 0 : goto done;
663 : }
664 :
665 0 : if (other_net_ctx != NULL) {
666 0 : status = close_handle(mem_ctx, pipe_hnd[1]->binding_handle,
667 : &pol_hnd[1]);
668 0 : if (!NT_STATUS_IS_OK(status)) {
669 0 : DEBUG(0, ("close_handle failed with error [%s].\n",
670 : nt_errstr(status)));
671 0 : goto done;
672 : }
673 : }
674 :
675 0 : success = 0;
676 :
677 0 : done:
678 0 : data_blob_clear_free(&session_key[0]);
679 0 : data_blob_clear_free(&session_key[1]);
680 0 : cli_shutdown(cli[0]);
681 0 : cli_shutdown(cli[1]);
682 0 : talloc_destroy(mem_ctx);
683 0 : return success;
684 : }
685 :
686 0 : static int rpc_trust_create(struct net_context *net_ctx, int argc,
687 : const char **argv)
688 : {
689 0 : return rpc_trust_common(net_ctx, argc, argv, TRUST_CREATE);
690 : }
691 :
692 0 : static int rpc_trust_delete(struct net_context *net_ctx, int argc,
693 : const char **argv)
694 : {
695 0 : return rpc_trust_common(net_ctx, argc, argv, TRUST_DELETE);
696 : }
697 :
698 0 : int net_rpc_trust(struct net_context *c, int argc, const char **argv)
699 : {
700 0 : struct functable func[] = {
701 : {
702 : "create",
703 : rpc_trust_create,
704 : NET_TRANSPORT_RPC,
705 : N_("Create trusts"),
706 : N_("net rpc trust create\n"
707 : " Create trusts")
708 : },
709 : {
710 : "delete",
711 : rpc_trust_delete,
712 : NET_TRANSPORT_RPC,
713 : N_("Remove trusts"),
714 : N_("net rpc trust delete\n"
715 : " Remove trusts")
716 : },
717 : {NULL, NULL, 0, NULL, NULL}
718 : };
719 :
720 0 : return net_run_function(c, argc, argv, "net rpc trust", func);
721 : }
|