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