smbd: Make reopen_from_fsp() public
[samba4-gss.git] / source3 / utils / net_rpc_trust.c
blob4e57d7ce044e294a66eefc8b69a2a96d15ac6f2f
1 /*
2 Samba Unix/Linux SMB client library
3 Distributed SMB/CIFS Server Management Utility
4 Copyright (C) 2011 Sumit Bose (sbose@redhat.com)
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.
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.
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/>. */
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"
29 #include "lib/crypto/gnutls_helpers.h"
30 #include <gnutls/gnutls.h>
31 #include <gnutls/crypto.h>
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="
40 enum trust_op {
41 TRUST_CREATE,
42 TRUST_DELETE
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;
53 struct dom_data {
54 struct dom_sid *domsid;
55 char *dns_domain_name;
56 char *domain_name;
59 static NTSTATUS close_handle(TALLOC_CTX *mem_ctx,
60 struct dcerpc_binding_handle *bind_hnd,
61 struct policy_handle *pol_hnd)
63 NTSTATUS status;
64 NTSTATUS result;
66 status = dcerpc_lsa_Close(bind_hnd, mem_ctx, pol_hnd, &result);
67 if (!NT_STATUS_IS_OK(status)) {
68 DEBUG(0, ("dcerpc_lsa_Close failed with error [%s].\n",
69 nt_errstr(status)));
70 return status;
72 if (!NT_STATUS_IS_OK(result)) {
73 DEBUG(0, ("lsa close failed with error [%s].\n",
74 nt_errstr(result)));
75 return result;
78 return NT_STATUS_OK;
81 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)
86 NTSTATUS status;
87 struct lsa_DeleteTrustedDomain dr;
89 dr.in.handle = pol_hnd;
90 dr.in.dom_sid = domsid;
92 status = dcerpc_lsa_DeleteTrustedDomain_r(bind_hnd, mem_ctx, &dr);
93 if (!NT_STATUS_IS_OK(status)) {
94 DEBUG(0, ("dcerpc_lsa_DeleteTrustedDomain_r failed with [%s]\n",
95 nt_errstr(status)));
96 return status;
98 if (!NT_STATUS_IS_OK(dr.out.result)) {
99 DEBUG(0, ("DeleteTrustedDomain returned [%s]\n",
100 nt_errstr(dr.out.result)));
101 return dr.out.result;
104 return NT_STATUS_OK;
107 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)
115 NTSTATUS status;
116 struct lsa_CreateTrustedDomainEx2 r;
117 struct lsa_TrustDomainInfoInfoEx trustinfo;
118 struct policy_handle trustdom_handle;
119 bool is_nt4 = trust_name_dns == NULL;
121 if (!is_nt4) {
122 fprintf(stdout, "Creating AD trust\n");
123 trustinfo.trust_type = LSA_TRUST_TYPE_UPLEVEL;
124 trustinfo.trust_attributes = LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE;
125 } else {
126 fprintf(stdout, "Creating NT4 trust\n");
127 trustinfo.trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
128 trustinfo.trust_attributes = 0;
129 trust_name_dns = trust_name;
132 trustinfo.sid = domsid;
133 trustinfo.netbios_name.string = trust_name;
134 trustinfo.domain_name.string = trust_name_dns;
136 trustinfo.trust_direction = LSA_TRUST_DIRECTION_INBOUND |
137 LSA_TRUST_DIRECTION_OUTBOUND;
139 r.in.policy_handle = pol_hnd;
140 r.in.info = &trustinfo;
141 r.in.auth_info_internal = authinfo;
142 r.in.access_mask = LSA_TRUSTED_SET_POSIX | LSA_TRUSTED_SET_AUTH |
143 LSA_TRUSTED_QUERY_DOMAIN_NAME;
144 r.out.trustdom_handle = &trustdom_handle;
146 status = dcerpc_lsa_CreateTrustedDomainEx2_r(bind_hnd, mem_ctx, &r);
147 if (!NT_STATUS_IS_OK(status)) {
148 DEBUG(0, ("dcerpc_lsa_CreateTrustedDomainEx2_r failed "
149 "with error [%s].\n", nt_errstr(status)));
150 return status;
152 if (!NT_STATUS_IS_OK(r.out.result)) {
153 DEBUG(0, ("CreateTrustedDomainEx2_r returned [%s].\n",
154 nt_errstr(r.out.result)));
155 return r.out.result;
158 return NT_STATUS_OK;
161 static NTSTATUS get_domain_info(TALLOC_CTX *mem_ctx,
162 struct dcerpc_binding_handle *bind_hdn,
163 struct policy_handle *pol_hnd,
164 struct dom_data *dom_data)
166 NTSTATUS status;
167 struct lsa_QueryInfoPolicy2 qr;
168 struct dom_sid_buf buf;
170 qr.in.handle = pol_hnd;
171 qr.in.level = LSA_POLICY_INFO_DNS;
173 status = dcerpc_lsa_QueryInfoPolicy2_r(bind_hdn, mem_ctx, &qr);
174 if (!NT_STATUS_IS_OK(status)) {
175 DEBUG(0, ("dcerpc_lsa_QueryInfoPolicy2_r failed "
176 "with error [%s].\n", nt_errstr(status)));
177 return status;
180 if (!NT_STATUS_IS_OK(qr.out.result)) {
181 DEBUG(0, ("QueryInfoPolicy2 returned [%s].\n",
182 nt_errstr(qr.out.result)));
183 return qr.out.result;
186 dom_data->domain_name = talloc_strdup(mem_ctx,
187 (*qr.out.info)->dns.name.string);
188 dom_data->dns_domain_name = talloc_strdup(mem_ctx,
189 (*qr.out.info)->dns.dns_domain.string);
190 dom_data->domsid = dom_sid_dup(mem_ctx, (*qr.out.info)->dns.sid);
191 if (dom_data->domain_name == NULL ||
192 dom_data->dns_domain_name == NULL ||
193 dom_data->domsid == NULL) {
194 DEBUG(0, ("Copying domain data failed.\n"));
195 return NT_STATUS_NO_MEMORY;
198 DEBUG(0, ("Got the following domain info [%s][%s][%s].\n",
199 dom_data->domain_name, dom_data->dns_domain_name,
200 dom_sid_str_buf(dom_data->domsid, &buf)));
202 return NT_STATUS_OK;
205 static NTSTATUS connect_and_get_info(TALLOC_CTX *mem_ctx,
206 struct net_context *net_ctx,
207 struct cli_state **cli,
208 struct rpc_pipe_client **pipe_hnd,
209 struct policy_handle *pol_hnd,
210 struct dom_data *dom_data,
211 DATA_BLOB *session_key)
213 NTSTATUS status;
214 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
215 uint32_t out_version = 0;
216 union lsa_revision_info out_revision_info = {
217 .info1 = {
218 .revision = 0,
222 status = net_make_ipc_connection_ex(net_ctx, NULL, NULL, NULL,
223 NET_FLAGS_PDC, cli);
224 if (!NT_STATUS_IS_OK(status)) {
225 DEBUG(0, ("Failed to connect to [%s] with error [%s]\n",
226 net_ctx->opt_host, nt_errstr(status)));
227 return status;
230 status = cli_rpc_pipe_open_noauth(*cli, &ndr_table_lsarpc, pipe_hnd);
231 if (!NT_STATUS_IS_OK(status)) {
232 DEBUG(0, ("Failed to initialise lsa pipe with error [%s]\n",
233 nt_errstr(status)));
234 return status;
237 status = dcerpc_lsa_open_policy_fallback(
238 (*pipe_hnd)->binding_handle,
239 mem_ctx,
240 (*pipe_hnd)->srv_name_slash,
241 false,
242 LSA_POLICY_VIEW_LOCAL_INFORMATION |
243 LSA_POLICY_TRUST_ADMIN |
244 LSA_POLICY_CREATE_SECRET,
245 &out_version,
246 &out_revision_info,
247 pol_hnd,
248 &result);
249 if (any_nt_status_not_ok(status, result, &status)) {
250 DBG_ERR("Failed to open policy handle: %s\n",
251 nt_errstr(result));
252 return status;
255 status = get_domain_info(mem_ctx, (*pipe_hnd)->binding_handle,
256 pol_hnd, dom_data);
257 if (!NT_STATUS_IS_OK(status)) {
258 DEBUG(0, ("get_domain_info failed with error [%s].\n",
259 nt_errstr(status)));
260 return status;
263 status = dcerpc_binding_handle_transport_session_key(
264 (*pipe_hnd)->binding_handle, mem_ctx, session_key);
265 if (!NT_STATUS_IS_OK(status)) {
266 DEBUG(0,("Error getting session_key of LSA pipe. Error was %s\n",
267 nt_errstr(status)));
268 return status;
271 return NT_STATUS_OK;
274 static bool get_trust_domain_passwords_auth_blob(TALLOC_CTX *mem_ctx,
275 const char *password,
276 DATA_BLOB *auth_blob)
278 struct trustDomainPasswords auth_struct;
279 struct AuthenticationInformation *auth_info_array;
280 enum ndr_err_code ndr_err;
281 size_t converted_size;
283 generate_random_buffer(auth_struct.confounder,
284 sizeof(auth_struct.confounder));
286 auth_info_array = talloc_array(mem_ctx,
287 struct AuthenticationInformation, 1);
288 if (auth_info_array == NULL) {
289 return false;
292 auth_info_array[0].AuthType = TRUST_AUTH_TYPE_CLEAR;
293 if (!convert_string_talloc(mem_ctx, CH_UNIX, CH_UTF16, password,
294 strlen(password),
295 &auth_info_array[0].AuthInfo.clear.password,
296 &converted_size)) {
297 return false;
300 auth_info_array[0].AuthInfo.clear.size = converted_size;
302 auth_struct.outgoing.count = 1;
303 auth_struct.outgoing.current.count = 1;
304 auth_struct.outgoing.current.array = auth_info_array;
305 auth_struct.outgoing.previous.count = 0;
306 auth_struct.outgoing.previous.array = NULL;
308 auth_struct.incoming.count = 1;
309 auth_struct.incoming.current.count = 1;
310 auth_struct.incoming.current.array = auth_info_array;
311 auth_struct.incoming.previous.count = 0;
312 auth_struct.incoming.previous.array = NULL;
314 ndr_err = ndr_push_struct_blob(auth_blob, mem_ctx, &auth_struct,
315 (ndr_push_flags_fn_t)ndr_push_trustDomainPasswords);
316 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
317 return false;
320 return true;
323 static int parse_trust_args(TALLOC_CTX *mem_ctx, int argc, const char **argv, struct other_dom_data **_o, char **_trustpw)
325 size_t c;
326 struct other_dom_data *o = NULL;
327 char *trustpw = NULL;
328 int ret = EFAULT;
330 if (argc == 0) {
331 return EINVAL;
334 o = talloc_zero(mem_ctx, struct other_dom_data);
335 if (o == NULL) {
336 DEBUG(0, ("talloc_zero failed.\n"));
337 return ENOMEM;
340 for (c = 0; c < argc; c++) {
341 if (strnequal(argv[c], ARG_OTHERSERVER, sizeof(ARG_OTHERSERVER)-1)) {
342 o->host = talloc_strdup(o, argv[c] + sizeof(ARG_OTHERSERVER)-1);
343 if (o->host == NULL) {
344 ret = ENOMEM;
345 goto failed;
347 } else if (strnequal(argv[c], ARG_OTHERUSER, sizeof(ARG_OTHERUSER)-1)) {
348 o->user_name = talloc_strdup(o, argv[c] + sizeof(ARG_OTHERUSER)-1);
349 if (o->user_name == NULL) {
350 ret = ENOMEM;
351 goto failed;
353 } else if (strnequal(argv[c], ARG_OTHERDOMAINSID, sizeof(ARG_OTHERDOMAINSID)-1)) {
354 o->domain_sid_str = talloc_strdup(o, argv[c] + sizeof(ARG_OTHERDOMAINSID)-1);
355 if (o->domain_sid_str == NULL) {
356 ret = ENOMEM;
357 goto failed;
359 } else if (strnequal(argv[c], ARG_OTHERDOMAIN, sizeof(ARG_OTHERDOMAIN)-1)) {
360 o->dns_domain_name = talloc_strdup(o, argv[c] + sizeof(ARG_OTHERDOMAIN)-1);
361 if (o->dns_domain_name == NULL) {
362 ret = ENOMEM;
363 goto failed;
365 } else if (strnequal(argv[c], ARG_OTHERNETBIOSDOMAIN, sizeof(ARG_OTHERNETBIOSDOMAIN)-1)) {
366 o->domain_name = talloc_strdup(o, argv[c] + sizeof(ARG_OTHERNETBIOSDOMAIN)-1);
367 if (o->domain_name == NULL) {
368 ret = ENOMEM;
369 goto failed;
371 } else if (strnequal(argv[c], ARG_TRUSTPW, sizeof(ARG_TRUSTPW)-1)) {
372 trustpw = talloc_strdup(mem_ctx, argv[c] + sizeof(ARG_TRUSTPW)-1);
373 if (trustpw == NULL) {
374 ret = ENOMEM;
375 goto failed;
377 } else {
378 DEBUG(0, ("Unsupported option [%s].\n", argv[c]));
379 ret = EINVAL;
380 goto failed;
384 *_o = o;
385 *_trustpw = trustpw;
387 return 0;
389 failed:
390 talloc_free(o);
391 talloc_free(trustpw);
392 return ret;
395 static void print_trust_delete_usage(void)
397 d_printf( "%s\n"
398 "net rpc trust delete [options]\n"
399 "\nOptions:\n"
400 "\totherserver=DC in other domain\n"
401 "\totheruser=Admin user in other domain\n"
402 "\totherdomainsid=SID of other domain\n"
403 "\nExamples:\n"
404 "\tnet rpc trust delete otherserver=oname otheruser=ouser -S lname -U luser\n"
405 "\tnet rpc trust delete otherdomainsid=S-... -S lname -U luser\n"
406 " %s\n",
407 _("Usage:"),
408 _("Remove trust between two domains"));
411 static void print_trust_usage(void)
413 d_printf( "%s\n"
414 "net rpc trust create [options]\n"
415 "\nOptions:\n"
416 "\totherserver=DC in other domain\n"
417 "\totheruser=Admin user in other domain\n"
418 "\totherdomainsid=SID of other domain\n"
419 "\tother_netbios_domain=NetBIOS/short name of other domain\n"
420 "\totherdomain=Full/DNS name of other domain (if not used, create an NT4 trust)\n"
421 "\ttrustpw=Trust password\n"
422 "\nExamples:\n"
423 "\tnet rpc trust create otherserver=oname otheruser=ouser -S lname -U luser\n"
424 "\tnet rpc trust create otherdomainsid=S-... other_netbios_domain=odom otherdomain=odom.org trustpw=secret -S lname -U luser\n"
425 " %s\n",
426 _("Usage:"),
427 _("Create trust between two domains"));
430 static int rpc_trust_common(struct net_context *net_ctx, int argc,
431 const char **argv, enum trust_op op)
433 TALLOC_CTX *mem_ctx;
434 NTSTATUS status;
435 int ret;
436 int success = -1;
437 struct cli_state *cli[2] = {NULL, NULL};
438 struct rpc_pipe_client *pipe_hnd[2] = {NULL, NULL};
439 DATA_BLOB session_key[2];
440 struct policy_handle pol_hnd[2];
441 struct lsa_TrustDomainInfoAuthInfoInternal authinfo;
442 DATA_BLOB auth_blob;
443 char *trust_pw = NULL;
444 struct other_dom_data *other_dom_data;
445 struct net_context *other_net_ctx = NULL;
446 struct dom_data dom_data[2];
447 void (*usage)(void);
449 ZERO_STRUCT(session_key);
451 switch (op) {
452 case TRUST_CREATE:
453 usage = print_trust_usage;
454 break;
455 case TRUST_DELETE:
456 usage = print_trust_delete_usage;
457 break;
458 default:
459 DEBUG(0, ("Unsupported trust operation.\n"));
460 return -1;
463 if (net_ctx->display_usage) {
464 usage();
465 return 0;
468 mem_ctx = talloc_init("trust op");
469 if (mem_ctx == NULL) {
470 DEBUG(0, ("talloc_init failed.\n"));
471 return -1;
474 ret = parse_trust_args(mem_ctx, argc, argv, &other_dom_data, &trust_pw);
475 if (ret != 0) {
476 if (ret == EINVAL) {
477 usage();
478 } else {
479 DEBUG(0, ("Failed to parse arguments.\n"));
481 goto done;
484 if (other_dom_data->host != 0) {
485 other_net_ctx = talloc_zero(other_dom_data, struct net_context);
486 if (other_net_ctx == NULL) {
487 DEBUG(0, ("talloc_zero failed.\n"));
488 goto done;
491 other_net_ctx->opt_host = other_dom_data->host;
492 other_net_ctx->creds = cli_credentials_init(other_net_ctx);
493 cli_credentials_parse_string(other_net_ctx->creds,
494 other_dom_data->user_name,
495 CRED_SPECIFIED);
496 } else {
497 dom_data[1].domsid = dom_sid_parse_talloc(mem_ctx,
498 other_dom_data->domain_sid_str);
499 dom_data[1].domain_name = other_dom_data->domain_name;
500 dom_data[1].dns_domain_name = other_dom_data->dns_domain_name;
502 if (dom_data[1].dns_domain_name == NULL) {
503 fprintf(stdout, "No DNS domain name passed, "
504 "assuming NT4 trust!\n");
507 if (dom_data[1].domsid == NULL ||
508 (op == TRUST_CREATE &&
509 (dom_data[1].domain_name == NULL))) {
510 DEBUG(0, ("Missing required argument.\n"));
511 usage();
512 goto done;
516 status = connect_and_get_info(mem_ctx, net_ctx, &cli[0], &pipe_hnd[0],
517 &pol_hnd[0], &dom_data[0], &session_key[0]);
518 if (!NT_STATUS_IS_OK(status)) {
519 DEBUG(0, ("connect_and_get_info failed with error [%s]\n",
520 nt_errstr(status)));
521 goto done;
524 if (other_net_ctx != NULL) {
525 status = connect_and_get_info(mem_ctx, other_net_ctx,
526 &cli[1], &pipe_hnd[1],
527 &pol_hnd[1], &dom_data[1],
528 &session_key[1]);
529 if (!NT_STATUS_IS_OK(status)) {
530 DEBUG(0, ("connect_and_get_info failed with error [%s]\n",
531 nt_errstr(status)));
532 goto done;
536 if (op == TRUST_CREATE) {
537 gnutls_cipher_hd_t cipher_hnd = NULL;
538 gnutls_datum_t enc_session_key = {
539 .data = session_key[0].data,
540 .size = session_key[0].length,
542 int rc;
544 if (trust_pw == NULL) {
545 if (other_net_ctx == NULL) {
546 DEBUG(0, ("Missing either trustpw or otherhost.\n"));
547 goto done;
550 DEBUG(0, ("Using random trust password.\n"));
551 trust_pw = trust_pw_new_value(mem_ctx,
552 SEC_CHAN_DOMAIN,
553 SEC_DOMAIN);
554 if (trust_pw == NULL) {
555 DEBUG(0, ("generate_random_password failed.\n"));
556 goto done;
558 } else {
559 DEBUG(0, ("Using user provided password.\n"));
562 if (!get_trust_domain_passwords_auth_blob(mem_ctx, trust_pw,
563 &auth_blob)) {
564 DEBUG(0, ("get_trust_domain_passwords_auth_blob failed\n"));
565 goto done;
568 authinfo.auth_blob.data = (uint8_t *)talloc_memdup(
569 mem_ctx,
570 auth_blob.data,
571 auth_blob.length);
572 if (authinfo.auth_blob.data == NULL) {
573 goto done;
575 authinfo.auth_blob.size = auth_blob.length;
577 rc = gnutls_cipher_init(&cipher_hnd,
578 GNUTLS_CIPHER_ARCFOUR_128,
579 &enc_session_key,
580 NULL);
581 if (rc < 0) {
582 status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
583 goto done;
585 rc = gnutls_cipher_encrypt(cipher_hnd,
586 authinfo.auth_blob.data,
587 authinfo.auth_blob.size);
588 gnutls_cipher_deinit(cipher_hnd);
589 if (rc < 0) {
590 status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
591 goto done;
594 status = create_trust(mem_ctx, pipe_hnd[0]->binding_handle,
595 &pol_hnd[0],
596 dom_data[1].domain_name,
597 dom_data[1].dns_domain_name,
598 dom_data[1].domsid,
599 &authinfo);
600 if (!NT_STATUS_IS_OK(status)) {
601 DEBUG(0, ("create_trust failed with error [%s].\n",
602 nt_errstr(status)));
603 goto done;
606 if (other_net_ctx != NULL) {
607 talloc_free(authinfo.auth_blob.data);
608 authinfo.auth_blob.data = (uint8_t *)talloc_memdup(
609 mem_ctx,
610 auth_blob.data,
611 auth_blob.length);
612 if (authinfo.auth_blob.data == NULL) {
613 goto done;
615 authinfo.auth_blob.size = auth_blob.length;
617 enc_session_key = (gnutls_datum_t) {
618 .data = session_key[1].data,
619 .size = session_key[1].length,
622 rc = gnutls_cipher_init(&cipher_hnd,
623 GNUTLS_CIPHER_ARCFOUR_128,
624 &enc_session_key,
625 NULL);
626 if (rc < 0) {
627 status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
628 goto done;
630 rc = gnutls_cipher_encrypt(cipher_hnd,
631 authinfo.auth_blob.data,
632 authinfo.auth_blob.size);
633 gnutls_cipher_deinit(cipher_hnd);
634 if (rc < 0) {
635 status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
636 goto done;
639 status = create_trust(mem_ctx,
640 pipe_hnd[1]->binding_handle,
641 &pol_hnd[1],
642 dom_data[0].domain_name,
643 dom_data[0].dns_domain_name,
644 dom_data[0].domsid, &authinfo);
645 if (!NT_STATUS_IS_OK(status)) {
646 DEBUG(0, ("create_trust failed with error [%s].\n",
647 nt_errstr(status)));
648 goto done;
651 } else if (op == TRUST_DELETE) {
652 status = delete_trust(mem_ctx, pipe_hnd[0]->binding_handle,
653 &pol_hnd[0], dom_data[1].domsid);
654 if (!NT_STATUS_IS_OK(status)) {
655 DEBUG(0, ("delete_trust failed with [%s].\n",
656 nt_errstr(status)));
657 goto done;
660 if (other_net_ctx != NULL) {
661 status = delete_trust(mem_ctx,
662 pipe_hnd[1]->binding_handle,
663 &pol_hnd[1], dom_data[0].domsid);
664 if (!NT_STATUS_IS_OK(status)) {
665 DEBUG(0, ("delete_trust failed with [%s].\n",
666 nt_errstr(status)));
667 goto done;
672 status = close_handle(mem_ctx, pipe_hnd[0]->binding_handle,
673 &pol_hnd[0]);
674 if (!NT_STATUS_IS_OK(status)) {
675 DEBUG(0, ("close_handle failed with error [%s].\n",
676 nt_errstr(status)));
677 goto done;
680 if (other_net_ctx != NULL) {
681 status = close_handle(mem_ctx, pipe_hnd[1]->binding_handle,
682 &pol_hnd[1]);
683 if (!NT_STATUS_IS_OK(status)) {
684 DEBUG(0, ("close_handle failed with error [%s].\n",
685 nt_errstr(status)));
686 goto done;
690 success = 0;
692 done:
693 data_blob_clear_free(&session_key[0]);
694 data_blob_clear_free(&session_key[1]);
695 cli_shutdown(cli[0]);
696 cli_shutdown(cli[1]);
697 talloc_destroy(mem_ctx);
698 return success;
701 static int rpc_trust_create(struct net_context *net_ctx, int argc,
702 const char **argv)
704 return rpc_trust_common(net_ctx, argc, argv, TRUST_CREATE);
707 static int rpc_trust_delete(struct net_context *net_ctx, int argc,
708 const char **argv)
710 return rpc_trust_common(net_ctx, argc, argv, TRUST_DELETE);
713 int net_rpc_trust(struct net_context *c, int argc, const char **argv)
715 struct functable func[] = {
717 "create",
718 rpc_trust_create,
719 NET_TRANSPORT_RPC,
720 N_("Create trusts"),
721 N_("net rpc trust create\n"
722 " Create trusts")
725 "delete",
726 rpc_trust_delete,
727 NET_TRANSPORT_RPC,
728 N_("Remove trusts"),
729 N_("net rpc trust delete\n"
730 " Remove trusts")
732 {NULL, NULL, 0, NULL, NULL}
735 return net_run_function(c, argc, argv, "net rpc trust", func);