Line data Source code
1 : /*
2 : Samba Unix/Linux SMB client library
3 : Distributed SMB/CIFS Server Management Utility
4 : Copyright (C) 2001 Andrew Bartlett (abartlet@samba.org)
5 : Copyright (C) 2002 Jim McDonough (jmcd@us.ibm.com)
6 : Copyright (C) 2004,2008 Guenther Deschner (gd@samba.org)
7 : Copyright (C) 2005 Jeremy Allison (jra@samba.org)
8 : Copyright (C) 2006 Jelmer Vernooij (jelmer@samba.org)
9 :
10 : This program is free software; you can redistribute it and/or modify
11 : it under the terms of the GNU General Public License as published by
12 : the Free Software Foundation; either version 3 of the License, or
13 : (at your option) any later version.
14 :
15 : This program is distributed in the hope that it will be useful,
16 : but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 : GNU General Public License for more details.
19 :
20 : You should have received a copy of the GNU General Public License
21 : along with this program. If not, see <http://www.gnu.org/licenses/>. */
22 :
23 : #include "includes.h"
24 : #include "utils/net.h"
25 : #include "libsmb/namequery.h"
26 : #include "rpc_client/cli_pipe.h"
27 : #include "../libcli/auth/libcli_auth.h"
28 : #include "../librpc/gen_ndr/ndr_samr_c.h"
29 : #include "rpc_client/cli_samr.h"
30 : #include "rpc_client/init_samr.h"
31 : #include "../librpc/gen_ndr/ndr_lsa_c.h"
32 : #include "rpc_client/cli_lsarpc.h"
33 : #include "../librpc/gen_ndr/ndr_netlogon_c.h"
34 : #include "../librpc/gen_ndr/ndr_srvsvc_c.h"
35 : #include "../librpc/gen_ndr/ndr_spoolss.h"
36 : #include "../librpc/gen_ndr/ndr_initshutdown_c.h"
37 : #include "../librpc/gen_ndr/ndr_winreg_c.h"
38 : #include "secrets.h"
39 : #include "lib/netapi/netapi.h"
40 : #include "lib/netapi/netapi_net.h"
41 : #include "librpc/gen_ndr/libnet_join.h"
42 : #include "libnet/libnet_join.h"
43 : #include "rpc_client/init_lsa.h"
44 : #include "../libcli/security/security.h"
45 : #include "libsmb/libsmb.h"
46 : #include "clirap2.h"
47 : #include "nsswitch/libwbclient/wbclient.h"
48 : #include "passdb.h"
49 : #include "../libcli/smb/smbXcli_base.h"
50 : #include "libsmb/dsgetdcname.h"
51 : #include "lib/util/string_wrappers.h"
52 :
53 : static int net_mode_share;
54 : static NTSTATUS sync_files(struct copy_clistate *cp_clistate, const char *mask);
55 :
56 : /**
57 : * @file net_rpc.c
58 : *
59 : * @brief RPC based subcommands for the 'net' utility.
60 : *
61 : * This file should contain much of the functionality that used to
62 : * be found in rpcclient, except that the commands should change
63 : * less often, and the functionality should be sane (the user is not
64 : * expected to know a rid/sid before they conduct an operation etc.)
65 : *
66 : * @todo Perhaps eventually these should be split out into a number
67 : * of files, as this could get quite big.
68 : **/
69 :
70 :
71 : /**
72 : * Many of the RPC functions need the domain sid. This function gets
73 : * it at the start of every run
74 : *
75 : * @param cli A cli_state already connected to the remote machine
76 : *
77 : * @return The Domain SID of the remote machine.
78 : **/
79 :
80 140 : NTSTATUS net_get_remote_domain_sid(struct cli_state *cli, TALLOC_CTX *mem_ctx,
81 : struct dom_sid **domain_sid,
82 : const char **domain_name)
83 : {
84 140 : struct rpc_pipe_client *lsa_pipe = NULL;
85 : struct policy_handle pol;
86 : NTSTATUS status, result;
87 140 : union lsa_PolicyInformation *info = NULL;
88 : struct dcerpc_binding_handle *b;
89 :
90 140 : status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc,
91 : &lsa_pipe);
92 140 : if (!NT_STATUS_IS_OK(status)) {
93 0 : d_fprintf(stderr, _("Could not initialise lsa pipe\n"));
94 0 : return status;
95 : }
96 :
97 140 : b = lsa_pipe->binding_handle;
98 :
99 140 : status = rpccli_lsa_open_policy(lsa_pipe, mem_ctx, false,
100 : SEC_FLAG_MAXIMUM_ALLOWED,
101 : &pol);
102 140 : if (!NT_STATUS_IS_OK(status)) {
103 0 : d_fprintf(stderr, "open_policy %s: %s\n",
104 : _("failed"),
105 : nt_errstr(status));
106 0 : return status;
107 : }
108 :
109 140 : status = dcerpc_lsa_QueryInfoPolicy(b, mem_ctx,
110 : &pol,
111 : LSA_POLICY_INFO_ACCOUNT_DOMAIN,
112 : &info,
113 : &result);
114 140 : if (any_nt_status_not_ok(status, result, &status)) {
115 0 : d_fprintf(stderr, "lsaquery %s: %s\n",
116 : _("failed"),
117 : nt_errstr(status));
118 0 : return status;
119 : }
120 :
121 140 : *domain_name = info->account_domain.name.string;
122 140 : *domain_sid = info->account_domain.sid;
123 :
124 140 : dcerpc_lsa_Close(b, mem_ctx, &pol, &result);
125 140 : TALLOC_FREE(lsa_pipe);
126 :
127 140 : return NT_STATUS_OK;
128 : }
129 :
130 : /**
131 : * Run a single RPC command, from start to finish.
132 : *
133 : * @param pipe_name the pipe to connect to (usually a PIPE_ constant)
134 : * @param conn_flag a NET_FLAG_ combination. Passed to
135 : * net_make_ipc_connection.
136 : * @param argc Standard main() style argc.
137 : * @param argv Standard main() style argv. Initial components are already
138 : * stripped.
139 : * @return A shell status integer (0 for success).
140 : */
141 :
142 140 : int run_rpc_command(struct net_context *c,
143 : struct cli_state *cli_arg,
144 : const struct ndr_interface_table *table,
145 : int conn_flags,
146 : rpc_command_fn fn,
147 : int argc,
148 : const char **argv)
149 : {
150 140 : struct cli_state *cli = NULL;
151 140 : struct rpc_pipe_client *pipe_hnd = NULL;
152 : TALLOC_CTX *mem_ctx;
153 : NTSTATUS nt_status;
154 : struct dom_sid *domain_sid;
155 : const char *domain_name;
156 140 : int ret = -1;
157 :
158 : /* make use of cli_state handed over as an argument, if possible */
159 140 : if (!cli_arg) {
160 140 : nt_status = net_make_ipc_connection(c, conn_flags, &cli);
161 140 : if (!NT_STATUS_IS_OK(nt_status)) {
162 0 : DEBUG(1, ("failed to make ipc connection: %s\n",
163 : nt_errstr(nt_status)));
164 0 : return -1;
165 : }
166 : } else {
167 0 : cli = cli_arg;
168 : }
169 :
170 140 : if (!cli) {
171 0 : return -1;
172 : }
173 :
174 : /* Create mem_ctx */
175 :
176 140 : if (!(mem_ctx = talloc_init("run_rpc_command"))) {
177 0 : DEBUG(0, ("talloc_init() failed\n"));
178 0 : goto fail;
179 : }
180 :
181 140 : nt_status = net_get_remote_domain_sid(cli, mem_ctx, &domain_sid,
182 : &domain_name);
183 140 : if (!NT_STATUS_IS_OK(nt_status)) {
184 0 : goto fail;
185 : }
186 :
187 140 : if (!(conn_flags & NET_FLAGS_NO_PIPE)) {
188 140 : if (lp_client_schannel()
189 140 : && (ndr_syntax_id_equal(&table->syntax_id,
190 0 : &ndr_table_netlogon.syntax_id))) {
191 : const char *remote_name =
192 0 : smbXcli_conn_remote_name(cli->conn);
193 : const struct sockaddr_storage *remote_sockaddr =
194 0 : smbXcli_conn_remote_sockaddr(cli->conn);
195 :
196 : /* Always try and create an schannel netlogon pipe. */
197 0 : TALLOC_FREE(c->netlogon_creds);
198 0 : nt_status = cli_rpc_pipe_open_schannel(
199 : cli, c->msg_ctx, table, NCACN_NP,
200 : domain_name,
201 : remote_name,
202 : remote_sockaddr,
203 : &pipe_hnd, c, &c->netlogon_creds);
204 0 : if (!NT_STATUS_IS_OK(nt_status)) {
205 0 : DEBUG(0, ("Could not initialise schannel netlogon pipe. Error was %s\n",
206 : nt_errstr(nt_status) ));
207 0 : goto fail;
208 : }
209 : } else {
210 140 : if (conn_flags & NET_FLAGS_SEAL) {
211 0 : nt_status = cli_rpc_pipe_open_with_creds(
212 : cli, table,
213 0 : (conn_flags & NET_FLAGS_TCP) ?
214 : NCACN_IP_TCP : NCACN_NP,
215 : DCERPC_AUTH_TYPE_NTLMSSP,
216 : DCERPC_AUTH_LEVEL_PRIVACY,
217 0 : smbXcli_conn_remote_name(cli->conn),
218 0 : smbXcli_conn_remote_sockaddr(cli->conn),
219 : c->creds, &pipe_hnd);
220 : } else {
221 140 : nt_status = cli_rpc_pipe_open_noauth(
222 : cli, table,
223 : &pipe_hnd);
224 : }
225 140 : if (!NT_STATUS_IS_OK(nt_status)) {
226 0 : DEBUG(0, ("Could not initialise pipe %s. Error was %s\n",
227 : table->name,
228 : nt_errstr(nt_status) ));
229 0 : goto fail;
230 : }
231 : }
232 : }
233 :
234 140 : nt_status = fn(c, domain_sid, domain_name, cli, pipe_hnd, mem_ctx, argc, argv);
235 :
236 140 : if (!NT_STATUS_IS_OK(nt_status)) {
237 0 : DEBUG(1, ("rpc command function failed! (%s)\n", nt_errstr(nt_status)));
238 : } else {
239 140 : ret = 0;
240 140 : DEBUG(5, ("rpc command function succeeded\n"));
241 : }
242 :
243 140 : if (!(conn_flags & NET_FLAGS_NO_PIPE)) {
244 140 : if (pipe_hnd) {
245 140 : TALLOC_FREE(pipe_hnd);
246 : }
247 : }
248 :
249 0 : fail:
250 : /* close the connection only if it was opened here */
251 140 : if (!cli_arg) {
252 140 : cli_shutdown(cli);
253 : }
254 :
255 140 : talloc_destroy(mem_ctx);
256 140 : return ret;
257 : }
258 :
259 : /**
260 : * Force a change of the trust account password.
261 : *
262 : * All parameters are provided by the run_rpc_command function, except for
263 : * argc, argv which are passed through.
264 : *
265 : * @param domain_sid The domain sid acquired from the remote server.
266 : * @param cli A cli_state connected to the server.
267 : * @param mem_ctx Talloc context, destroyed on completion of the function.
268 : * @param argc Standard main() style argc.
269 : * @param argv Standard main() style argv. Initial components are already
270 : * stripped.
271 : *
272 : * @return Normal NTSTATUS return.
273 : **/
274 :
275 0 : static NTSTATUS rpc_changetrustpw_internals(struct net_context *c,
276 : const struct dom_sid *domain_sid,
277 : const char *domain_name,
278 : struct cli_state *cli,
279 : struct rpc_pipe_client *pipe_hnd,
280 : TALLOC_CTX *mem_ctx,
281 : int argc,
282 : const char **argv)
283 : {
284 : NTSTATUS status;
285 0 : const char *dcname = NULL;
286 :
287 0 : if (cli == NULL) {
288 0 : return NT_STATUS_INTERNAL_ERROR;
289 : }
290 :
291 0 : dcname = smbXcli_conn_remote_name(cli->conn);
292 :
293 0 : status = trust_pw_change(c->netlogon_creds,
294 : c->msg_ctx,
295 : pipe_hnd->binding_handle,
296 : c->opt_target_workgroup,
297 : dcname,
298 : true); /* force */
299 0 : if (!NT_STATUS_IS_OK(status)) {
300 0 : d_fprintf(stderr, _("Failed to change machine account password: %s\n"),
301 : nt_errstr(status));
302 0 : return status;
303 : }
304 :
305 0 : return NT_STATUS_OK;
306 : }
307 :
308 : /**
309 : * Force a change of the trust account password.
310 : *
311 : * @param argc Standard main() style argc.
312 : * @param argv Standard main() style argv. Initial components are already
313 : * stripped.
314 : *
315 : * @return A shell status integer (0 for success).
316 : **/
317 :
318 0 : int net_rpc_changetrustpw(struct net_context *c, int argc, const char **argv)
319 : {
320 0 : int conn_flags = NET_FLAGS_PDC;
321 :
322 0 : if (!c->opt_user_specified && !c->opt_kerberos) {
323 0 : conn_flags |= NET_FLAGS_ANONYMOUS;
324 : }
325 :
326 0 : if (c->display_usage) {
327 0 : d_printf( "%s\n"
328 : "net rpc changetrustpw\n"
329 : " %s\n",
330 : _("Usage:"),
331 : _("Change the machine trust password"));
332 0 : return 0;
333 : }
334 :
335 0 : return run_rpc_command(c, NULL, &ndr_table_netlogon,
336 : conn_flags,
337 : rpc_changetrustpw_internals,
338 : argc, argv);
339 : }
340 :
341 : /**
342 : * Join a domain, the old way. This function exists to allow
343 : * the message to be displayed when oldjoin was explicitly
344 : * requested, but not when it was implied by "net rpc join".
345 : *
346 : * This uses 'machinename' as the initial password, and changes it.
347 : *
348 : * The password should be created with 'server manager' or equiv first.
349 : *
350 : * @param argc Standard main() style argc.
351 : * @param argv Standard main() style argv. Initial components are already
352 : * stripped.
353 : *
354 : * @return A shell status integer (0 for success).
355 : **/
356 :
357 1 : static int net_rpc_oldjoin(struct net_context *c, int argc, const char **argv)
358 : {
359 1 : struct libnet_JoinCtx *r = NULL;
360 : TALLOC_CTX *mem_ctx;
361 : WERROR werr;
362 1 : const char *domain = lp_workgroup(); /* FIXME */
363 1 : bool modify_config = lp_config_backend_is_registry();
364 : enum netr_SchannelType sec_chan_type;
365 1 : char *pw = NULL;
366 :
367 1 : if (c->display_usage) {
368 0 : d_printf("Usage:\n"
369 : "net rpc oldjoin\n"
370 : " Join a domain the old way\n");
371 0 : return 0;
372 : }
373 :
374 1 : net_warn_member_options();
375 :
376 1 : mem_ctx = talloc_init("net_rpc_oldjoin");
377 1 : if (!mem_ctx) {
378 0 : return -1;
379 : }
380 :
381 1 : werr = libnet_init_JoinCtx(mem_ctx, &r);
382 1 : if (!W_ERROR_IS_OK(werr)) {
383 0 : goto fail;
384 : }
385 :
386 : /*
387 : check what type of join - if the user wants to join as
388 : a BDC, the server must agree that we are a BDC.
389 : */
390 1 : if (argc >= 0) {
391 1 : sec_chan_type = get_sec_channel_type(argv[0]);
392 : } else {
393 0 : sec_chan_type = get_sec_channel_type(NULL);
394 : }
395 :
396 1 : if (!c->msg_ctx) {
397 0 : d_fprintf(stderr, _("Could not initialise message context. "
398 : "Try running as root\n"));
399 0 : werr = WERR_ACCESS_DENIED;
400 0 : goto fail;
401 : }
402 :
403 1 : pw = talloc_strndup(r, lp_netbios_name(), 14);
404 1 : if (pw == NULL) {
405 0 : werr = WERR_NOT_ENOUGH_MEMORY;
406 0 : goto fail;
407 : }
408 :
409 1 : r->in.msg_ctx = c->msg_ctx;
410 1 : r->in.domain_name = domain;
411 1 : r->in.secure_channel_type = sec_chan_type;
412 1 : r->in.dc_name = c->opt_host;
413 1 : r->in.admin_account = "";
414 1 : r->in.admin_password = strlower_talloc(r, pw);
415 1 : if (r->in.admin_password == NULL) {
416 0 : werr = WERR_NOT_ENOUGH_MEMORY;
417 0 : goto fail;
418 : }
419 1 : r->in.debug = true;
420 1 : r->in.modify_config = modify_config;
421 1 : r->in.join_flags = WKSSVC_JOIN_FLAGS_JOIN_TYPE |
422 : WKSSVC_JOIN_FLAGS_JOIN_UNSECURE |
423 : WKSSVC_JOIN_FLAGS_MACHINE_PWD_PASSED;
424 :
425 1 : werr = libnet_Join(mem_ctx, r);
426 1 : if (!W_ERROR_IS_OK(werr)) {
427 1 : goto fail;
428 : }
429 :
430 : /* Check the short name of the domain */
431 :
432 0 : if (!modify_config && !strequal(lp_workgroup(), r->out.netbios_domain_name)) {
433 0 : d_printf("The workgroup in %s does not match the short\n", get_dyn_CONFIGFILE());
434 0 : d_printf("domain name obtained from the server.\n");
435 0 : d_printf("Using the name [%s] from the server.\n", r->out.netbios_domain_name);
436 0 : d_printf("You should set \"workgroup = %s\" in %s.\n",
437 0 : r->out.netbios_domain_name, get_dyn_CONFIGFILE());
438 : }
439 :
440 0 : d_printf("Using short domain name -- %s\n", r->out.netbios_domain_name);
441 :
442 0 : if (r->out.dns_domain_name) {
443 0 : d_printf("Joined '%s' to realm '%s'\n", r->in.machine_name,
444 0 : r->out.dns_domain_name);
445 : } else {
446 0 : d_printf("Joined '%s' to domain '%s'\n", r->in.machine_name,
447 0 : r->out.netbios_domain_name);
448 : }
449 :
450 : /* print out informative error string in case there is one */
451 0 : if (r->out.error_string != NULL) {
452 0 : d_printf("%s\n", r->out.error_string);
453 : }
454 :
455 0 : TALLOC_FREE(mem_ctx);
456 :
457 0 : return 0;
458 :
459 1 : fail:
460 1 : if (c->opt_flags & NET_FLAGS_EXPECT_FALLBACK) {
461 1 : goto cleanup;
462 : }
463 :
464 : /* issue an overall failure message at the end. */
465 0 : d_fprintf(stderr, _("Failed to join domain: %s\n"),
466 0 : r && r->out.error_string ? r->out.error_string :
467 0 : get_friendly_werror_msg(werr));
468 :
469 1 : cleanup:
470 1 : TALLOC_FREE(mem_ctx);
471 :
472 1 : return -1;
473 : }
474 :
475 : /**
476 : * check that a join is OK
477 : *
478 : * @return A shell status integer (0 for success)
479 : *
480 : **/
481 8 : int net_rpc_testjoin(struct net_context *c, int argc, const char **argv)
482 : {
483 : NTSTATUS status;
484 : TALLOC_CTX *mem_ctx;
485 8 : const char *domain = c->opt_target_workgroup;
486 8 : const char *dc = c->opt_host;
487 :
488 8 : if (c->display_usage) {
489 0 : d_printf("Usage\n"
490 : "net rpc testjoin\n"
491 : " Test if a join is OK\n");
492 0 : return 0;
493 : }
494 :
495 8 : net_warn_member_options();
496 :
497 8 : mem_ctx = talloc_init("net_rpc_testjoin");
498 8 : if (!mem_ctx) {
499 0 : return -1;
500 : }
501 :
502 8 : if (!dc) {
503 : struct netr_DsRGetDCNameInfo *info;
504 :
505 8 : if (!c->msg_ctx) {
506 0 : d_fprintf(stderr, _("Could not initialise message context. "
507 : "Try running as root\n"));
508 0 : talloc_destroy(mem_ctx);
509 0 : return -1;
510 : }
511 :
512 8 : status = dsgetdcname(mem_ctx,
513 : c->msg_ctx,
514 : domain,
515 : NULL,
516 : NULL,
517 : DS_RETURN_DNS_NAME,
518 : &info);
519 8 : if (!NT_STATUS_IS_OK(status)) {
520 0 : talloc_destroy(mem_ctx);
521 0 : return -1;
522 : }
523 :
524 8 : dc = strip_hostname(info->dc_unc);
525 : }
526 :
527 : /* Display success or failure */
528 8 : status = libnet_join_ok(c->msg_ctx,
529 : c->opt_workgroup,
530 : dc,
531 8 : c->opt_kerberos);
532 8 : if (!NT_STATUS_IS_OK(status)) {
533 0 : fprintf(stderr,"Join to domain '%s' is not valid: %s\n",
534 : domain, nt_errstr(status));
535 0 : talloc_destroy(mem_ctx);
536 0 : return -1;
537 : }
538 :
539 8 : printf("Join to '%s' is OK\n",domain);
540 8 : talloc_destroy(mem_ctx);
541 :
542 8 : return 0;
543 : }
544 :
545 : /**
546 : * Join a domain using the administrator username and password
547 : *
548 : * @param argc Standard main() style argc
549 : * @param argc Standard main() style argv. Initial components are already
550 : * stripped. Currently not used.
551 : * @return A shell status integer (0 for success)
552 : *
553 : **/
554 :
555 1 : static int net_rpc_join_newstyle(struct net_context *c, int argc, const char **argv)
556 : {
557 1 : struct libnet_JoinCtx *r = NULL;
558 : TALLOC_CTX *mem_ctx;
559 : WERROR werr;
560 1 : const char *domain = lp_workgroup(); /* FIXME */
561 1 : bool modify_config = lp_config_backend_is_registry();
562 : enum netr_SchannelType sec_chan_type;
563 :
564 1 : if (c->display_usage) {
565 0 : d_printf("Usage:\n"
566 : "net rpc join\n"
567 : " Join a domain the new way\n");
568 0 : return 0;
569 : }
570 :
571 1 : net_warn_member_options();
572 :
573 1 : mem_ctx = talloc_init("net_rpc_join_newstyle");
574 1 : if (!mem_ctx) {
575 0 : return -1;
576 : }
577 :
578 1 : werr = libnet_init_JoinCtx(mem_ctx, &r);
579 1 : if (!W_ERROR_IS_OK(werr)) {
580 0 : goto fail;
581 : }
582 :
583 : /*
584 : check what type of join - if the user wants to join as
585 : a BDC, the server must agree that we are a BDC.
586 : */
587 1 : if (argc >= 0) {
588 1 : sec_chan_type = get_sec_channel_type(argv[0]);
589 : } else {
590 0 : sec_chan_type = get_sec_channel_type(NULL);
591 : }
592 :
593 1 : if (!c->msg_ctx) {
594 0 : d_fprintf(stderr, _("Could not initialise message context. "
595 : "Try running as root\n"));
596 0 : werr = WERR_ACCESS_DENIED;
597 0 : goto fail;
598 : }
599 :
600 1 : r->in.msg_ctx = c->msg_ctx;
601 1 : r->in.domain_name = domain;
602 1 : r->in.secure_channel_type = sec_chan_type;
603 1 : r->in.dc_name = c->opt_host;
604 1 : r->in.admin_account = c->opt_user_name;
605 1 : r->in.admin_password = net_prompt_pass(c, c->opt_user_name);
606 1 : r->in.debug = true;
607 1 : r->in.use_kerberos = c->opt_kerberos;
608 1 : r->in.modify_config = modify_config;
609 1 : r->in.join_flags = WKSSVC_JOIN_FLAGS_JOIN_TYPE |
610 : WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE |
611 : WKSSVC_JOIN_FLAGS_DOMAIN_JOIN_IF_JOINED;
612 :
613 1 : werr = libnet_Join(mem_ctx, r);
614 1 : if (!W_ERROR_IS_OK(werr)) {
615 0 : goto fail;
616 : }
617 :
618 : /* Check the short name of the domain */
619 :
620 1 : if (!modify_config && !strequal(lp_workgroup(), r->out.netbios_domain_name)) {
621 0 : d_printf("The workgroup in %s does not match the short\n", get_dyn_CONFIGFILE());
622 0 : d_printf("domain name obtained from the server.\n");
623 0 : d_printf("Using the name [%s] from the server.\n", r->out.netbios_domain_name);
624 0 : d_printf("You should set \"workgroup = %s\" in %s.\n",
625 0 : r->out.netbios_domain_name, get_dyn_CONFIGFILE());
626 : }
627 :
628 1 : d_printf("Using short domain name -- %s\n", r->out.netbios_domain_name);
629 :
630 1 : if (r->out.dns_domain_name) {
631 0 : d_printf("Joined '%s' to realm '%s'\n", r->in.machine_name,
632 0 : r->out.dns_domain_name);
633 : } else {
634 1 : d_printf("Joined '%s' to domain '%s'\n", r->in.machine_name,
635 1 : r->out.netbios_domain_name);
636 : }
637 :
638 : /* print out informative error string in case there is one */
639 1 : if (r->out.error_string != NULL) {
640 0 : d_printf("%s\n", r->out.error_string);
641 : }
642 :
643 1 : TALLOC_FREE(mem_ctx);
644 :
645 1 : return 0;
646 :
647 0 : fail:
648 : /* issue an overall failure message at the end. */
649 0 : d_printf("Failed to join domain: %s\n",
650 0 : r && r->out.error_string ? r->out.error_string :
651 0 : get_friendly_werror_msg(werr));
652 :
653 0 : TALLOC_FREE(mem_ctx);
654 :
655 0 : return -1;
656 : }
657 :
658 : /**
659 : * 'net rpc join' entrypoint.
660 : * @param argc Standard main() style argc.
661 : * @param argv Standard main() style argv. Initial components are already
662 : * stripped
663 : *
664 : * Main 'net_rpc_join()' (where the admin username/password is used) is
665 : * in net_rpc_join.c.
666 : * Try to just change the password, but if that doesn't work, use/prompt
667 : * for a username/password.
668 : **/
669 :
670 1 : int net_rpc_join(struct net_context *c, int argc, const char **argv)
671 : {
672 : int ret;
673 :
674 1 : if (c->display_usage) {
675 0 : d_printf("%s\n%s",
676 : _("Usage:"),
677 : _("net rpc join -U <username>[%%password] <type>\n"
678 : " Join a domain\n"
679 : " username\tName of the admin user"
680 : " password\tPassword of the admin user, will "
681 : "prompt if not specified\n"
682 : " type\tCan be one of the following:\n"
683 : "\t\tMEMBER\tJoin as member server (default)\n"
684 : "\t\tBDC\tJoin as BDC\n"
685 : "\t\tPDC\tJoin as PDC\n"));
686 0 : return 0;
687 : }
688 :
689 1 : if (lp_server_role() == ROLE_STANDALONE) {
690 0 : d_printf(_("cannot join as standalone machine\n"));
691 0 : return -1;
692 : }
693 :
694 1 : net_warn_member_options();
695 :
696 1 : if (strlen(lp_netbios_name()) > 15) {
697 0 : d_printf(_("Our netbios name can be at most 15 chars long, "
698 : "\"%s\" is %u chars long\n"),
699 0 : lp_netbios_name(), (unsigned int)strlen(lp_netbios_name()));
700 0 : return -1;
701 : }
702 :
703 1 : c->opt_flags |= NET_FLAGS_EXPECT_FALLBACK;
704 1 : ret = net_rpc_oldjoin(c, argc, argv);
705 1 : c->opt_flags &= ~NET_FLAGS_EXPECT_FALLBACK;
706 1 : if (ret == 0) {
707 0 : return 0;
708 : }
709 :
710 1 : return net_rpc_join_newstyle(c, argc, argv);
711 : }
712 :
713 : /**
714 : * display info about a rpc domain
715 : *
716 : * All parameters are provided by the run_rpc_command function, except for
717 : * argc, argv which are passed through.
718 : *
719 : * @param domain_sid The domain sid acquired from the remote server
720 : * @param cli A cli_state connected to the server.
721 : * @param mem_ctx Talloc context, destroyed on completion of the function.
722 : * @param argc Standard main() style argc.
723 : * @param argv Standard main() style argv. Initial components are already
724 : * stripped.
725 : *
726 : * @return Normal NTSTATUS return.
727 : **/
728 :
729 0 : NTSTATUS rpc_info_internals(struct net_context *c,
730 : const struct dom_sid *domain_sid,
731 : const char *domain_name,
732 : struct cli_state *cli,
733 : struct rpc_pipe_client *pipe_hnd,
734 : TALLOC_CTX *mem_ctx,
735 : int argc,
736 : const char **argv)
737 : {
738 : struct policy_handle connect_pol, domain_pol;
739 : NTSTATUS status, result;
740 0 : union samr_DomainInfo *info = NULL;
741 0 : struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
742 :
743 : /* Get sam policy handle */
744 0 : status = dcerpc_samr_Connect2(b, mem_ctx,
745 0 : pipe_hnd->desthost,
746 : MAXIMUM_ALLOWED_ACCESS,
747 : &connect_pol,
748 : &result);
749 0 : if (!NT_STATUS_IS_OK(status)) {
750 0 : d_fprintf(stderr, _("Could not connect to SAM: %s\n"),
751 : nt_errstr(status));
752 0 : goto done;
753 : }
754 :
755 0 : if (!NT_STATUS_IS_OK(result)) {
756 0 : status = result;
757 0 : d_fprintf(stderr, _("Could not connect to SAM: %s\n"),
758 : nt_errstr(result));
759 0 : goto done;
760 : }
761 :
762 : /* Get domain policy handle */
763 0 : status = dcerpc_samr_OpenDomain(b, mem_ctx,
764 : &connect_pol,
765 : MAXIMUM_ALLOWED_ACCESS,
766 : discard_const_p(struct dom_sid2, domain_sid),
767 : &domain_pol,
768 : &result);
769 0 : if (!NT_STATUS_IS_OK(status)) {
770 0 : d_fprintf(stderr, _("Could not open domain: %s\n"),
771 : nt_errstr(status));
772 0 : goto done;
773 : }
774 0 : if (!NT_STATUS_IS_OK(result)) {
775 0 : status = result;
776 0 : d_fprintf(stderr, _("Could not open domain: %s\n"),
777 : nt_errstr(result));
778 0 : goto done;
779 : }
780 :
781 0 : status = dcerpc_samr_QueryDomainInfo(b, mem_ctx,
782 : &domain_pol,
783 : 2,
784 : &info,
785 : &result);
786 0 : if (!NT_STATUS_IS_OK(status)) {
787 0 : goto done;
788 : }
789 0 : status = result;
790 0 : if (NT_STATUS_IS_OK(result)) {
791 : struct dom_sid_buf sid_str;
792 :
793 0 : d_printf(_("Domain Name: %s\n"),
794 0 : info->general.domain_name.string);
795 0 : d_printf(_("Domain SID: %s\n"),
796 : dom_sid_str_buf(domain_sid, &sid_str));
797 0 : d_printf(_("Sequence number: %llu\n"),
798 0 : (unsigned long long)info->general.sequence_num);
799 0 : d_printf(_("Num users: %u\n"), info->general.num_users);
800 0 : d_printf(_("Num domain groups: %u\n"),info->general.num_groups);
801 0 : d_printf(_("Num local groups: %u\n"),info->general.num_aliases);
802 : }
803 :
804 0 : done:
805 0 : return status;
806 : }
807 :
808 : /**
809 : * 'net rpc info' entrypoint.
810 : * @param argc Standard main() style argc.
811 : * @param argv Standard main() style argv. Initial components are already
812 : * stripped.
813 : **/
814 :
815 0 : int net_rpc_info(struct net_context *c, int argc, const char **argv)
816 : {
817 0 : if (c->display_usage) {
818 0 : d_printf( "%s\n"
819 : "net rpc info\n"
820 : " %s\n",
821 : _("Usage:"),
822 : _("Display information about the domain"));
823 0 : return 0;
824 : }
825 :
826 0 : net_warn_member_options();
827 :
828 0 : return run_rpc_command(c, NULL, &ndr_table_samr,
829 : NET_FLAGS_PDC, rpc_info_internals,
830 : argc, argv);
831 : }
832 :
833 : /**
834 : * Fetch domain SID into the local secrets.tdb.
835 : *
836 : * All parameters are provided by the run_rpc_command function, except for
837 : * argc, argv which are passed through.
838 : *
839 : * @param domain_sid The domain sid acquired from the remote server.
840 : * @param cli A cli_state connected to the server.
841 : * @param mem_ctx Talloc context, destroyed on completion of the function.
842 : * @param argc Standard main() style argc.
843 : * @param argv Standard main() style argv. Initial components are already
844 : * stripped.
845 : *
846 : * @return Normal NTSTATUS return.
847 : **/
848 :
849 0 : static NTSTATUS rpc_getsid_internals(struct net_context *c,
850 : const struct dom_sid *domain_sid,
851 : const char *domain_name,
852 : struct cli_state *cli,
853 : struct rpc_pipe_client *pipe_hnd,
854 : TALLOC_CTX *mem_ctx,
855 : int argc,
856 : const char **argv)
857 : {
858 : struct dom_sid_buf sid_str;
859 :
860 0 : d_printf(_("Storing SID %s for Domain %s in secrets.tdb\n"),
861 : dom_sid_str_buf(domain_sid, &sid_str),
862 : domain_name);
863 :
864 0 : if (!secrets_store_domain_sid(domain_name, domain_sid)) {
865 0 : DEBUG(0,("Can't store domain SID\n"));
866 0 : return NT_STATUS_UNSUCCESSFUL;
867 : }
868 :
869 0 : return NT_STATUS_OK;
870 : }
871 :
872 : /**
873 : * 'net rpc getsid' entrypoint.
874 : * @param argc Standard main() style argc.
875 : * @param argv Standard main() style argv. Initial components are already
876 : * stripped.
877 : **/
878 :
879 0 : int net_rpc_getsid(struct net_context *c, int argc, const char **argv)
880 : {
881 0 : int conn_flags = NET_FLAGS_PDC;
882 :
883 0 : if (!c->opt_user_specified && !c->opt_kerberos) {
884 0 : conn_flags |= NET_FLAGS_ANONYMOUS;
885 : }
886 :
887 0 : if (c->display_usage) {
888 0 : d_printf( "%s\n"
889 : "net rpc getsid\n"
890 : " %s\n",
891 : _("Usage:"),
892 : _("Fetch domain SID into local secrets.tdb"));
893 0 : return 0;
894 : }
895 :
896 0 : return run_rpc_command(c, NULL, &ndr_table_samr,
897 : conn_flags,
898 : rpc_getsid_internals,
899 : argc, argv);
900 : }
901 :
902 : /****************************************************************************/
903 :
904 : /**
905 : * Basic usage function for 'net rpc user'.
906 : * @param argc Standard main() style argc.
907 : * @param argv Standard main() style argv. Initial components are already
908 : * stripped.
909 : **/
910 :
911 0 : static int rpc_user_usage(struct net_context *c, int argc, const char **argv)
912 : {
913 0 : return net_user_usage(c, argc, argv);
914 : }
915 :
916 : /**
917 : * Add a new user to a remote RPC server.
918 : *
919 : * @param argc Standard main() style argc.
920 : * @param argv Standard main() style argv. Initial components are already
921 : * stripped.
922 : *
923 : * @return A shell status integer (0 for success).
924 : **/
925 :
926 2 : static int rpc_user_add(struct net_context *c, int argc, const char **argv)
927 : {
928 : NET_API_STATUS status;
929 : struct USER_INFO_1 info1;
930 2 : uint32_t parm_error = 0;
931 :
932 2 : if (argc < 1 || c->display_usage) {
933 0 : rpc_user_usage(c, argc, argv);
934 0 : return 0;
935 : }
936 :
937 2 : ZERO_STRUCT(info1);
938 :
939 2 : info1.usri1_name = argv[0];
940 2 : if (argc == 2) {
941 2 : info1.usri1_password = argv[1];
942 : }
943 :
944 2 : status = NetUserAdd(c->opt_host, 1, (uint8_t *)&info1, &parm_error);
945 :
946 2 : if (status != 0) {
947 0 : d_fprintf(stderr,_("Failed to add user '%s' with error: %s.\n"),
948 : argv[0], libnetapi_get_error_string(c->netapi_ctx,
949 : status));
950 0 : return -1;
951 : } else {
952 2 : d_printf(_("Added user '%s'.\n"), argv[0]);
953 : }
954 :
955 2 : return 0;
956 : }
957 :
958 : /**
959 : * Rename a user on a remote RPC server.
960 : *
961 : * @param argc Standard main() style argc.
962 : * @param argv Standard main() style argv. Initial components are already
963 : * stripped.
964 : *
965 : * @return A shell status integer (0 for success).
966 : **/
967 :
968 0 : static int rpc_user_rename(struct net_context *c, int argc, const char **argv)
969 : {
970 : NET_API_STATUS status;
971 : struct USER_INFO_0 u0;
972 0 : uint32_t parm_err = 0;
973 :
974 0 : if (argc != 2 || c->display_usage) {
975 0 : rpc_user_usage(c, argc, argv);
976 0 : return 0;
977 : }
978 :
979 0 : u0.usri0_name = argv[1];
980 :
981 0 : status = NetUserSetInfo(c->opt_host, argv[0],
982 : 0, (uint8_t *)&u0, &parm_err);
983 0 : if (status) {
984 0 : d_fprintf(stderr,
985 0 : _("Failed to rename user from %s to %s - %s\n"),
986 0 : argv[0], argv[1],
987 : libnetapi_get_error_string(c->netapi_ctx, status));
988 : } else {
989 0 : d_printf(_("Renamed user from %s to %s\n"), argv[0], argv[1]);
990 : }
991 :
992 0 : return status;
993 : }
994 :
995 : /**
996 : * Set a user's primary group
997 : *
998 : * @param argc Standard main() style argc.
999 : * @param argv Standard main() style argv. Initial components are already
1000 : * stripped.
1001 : *
1002 : * @return A shell status integer (0 for success).
1003 : **/
1004 :
1005 0 : static int rpc_user_setprimarygroup(struct net_context *c, int argc,
1006 : const char **argv)
1007 : {
1008 : NET_API_STATUS status;
1009 : uint8_t *buffer;
1010 : struct GROUP_INFO_2 *g2;
1011 : struct USER_INFO_1051 u1051;
1012 0 : uint32_t parm_err = 0;
1013 :
1014 0 : if (argc != 2 || c->display_usage) {
1015 0 : rpc_user_usage(c, argc, argv);
1016 0 : return 0;
1017 : }
1018 :
1019 0 : status = NetGroupGetInfo(c->opt_host, argv[1], 2, &buffer);
1020 0 : if (status) {
1021 0 : d_fprintf(stderr, _("Failed to find group name %s -- %s\n"),
1022 0 : argv[1],
1023 : libnetapi_get_error_string(c->netapi_ctx, status));
1024 0 : return status;
1025 : }
1026 0 : g2 = (struct GROUP_INFO_2 *)buffer;
1027 :
1028 0 : u1051.usri1051_primary_group_id = g2->grpi2_group_id;
1029 :
1030 0 : NetApiBufferFree(buffer);
1031 :
1032 0 : status = NetUserSetInfo(c->opt_host, argv[0], 1051,
1033 : (uint8_t *)&u1051, &parm_err);
1034 0 : if (status) {
1035 0 : d_fprintf(stderr,
1036 0 : _("Failed to set user's primary group %s to %s - "
1037 0 : "%s\n"), argv[0], argv[1],
1038 : libnetapi_get_error_string(c->netapi_ctx, status));
1039 : } else {
1040 0 : d_printf(_("Set primary group of user %s to %s\n"), argv[0],
1041 0 : argv[1]);
1042 : }
1043 0 : return status;
1044 : }
1045 :
1046 : /**
1047 : * Delete a user from a remote RPC server.
1048 : *
1049 : * @param argc Standard main() style argc.
1050 : * @param argv Standard main() style argv. Initial components are already
1051 : * stripped.
1052 : *
1053 : * @return A shell status integer (0 for success).
1054 : **/
1055 :
1056 2 : static int rpc_user_delete(struct net_context *c, int argc, const char **argv)
1057 : {
1058 : NET_API_STATUS status;
1059 :
1060 2 : if (argc < 1 || c->display_usage) {
1061 0 : rpc_user_usage(c, argc, argv);
1062 0 : return 0;
1063 : }
1064 :
1065 2 : status = NetUserDel(c->opt_host, argv[0]);
1066 :
1067 2 : if (status != 0) {
1068 0 : d_fprintf(stderr, _("Failed to delete user '%s' with: %s.\n"),
1069 : argv[0],
1070 : libnetapi_get_error_string(c->netapi_ctx, status));
1071 0 : return -1;
1072 : } else {
1073 2 : d_printf(_("Deleted user '%s'.\n"), argv[0]);
1074 : }
1075 :
1076 2 : return 0;
1077 : }
1078 :
1079 : /**
1080 : * Set a user's password on a remote RPC server.
1081 : *
1082 : * @param argc Standard main() style argc.
1083 : * @param argv Standard main() style argv. Initial components are already
1084 : * stripped.
1085 : *
1086 : * @return A shell status integer (0 for success).
1087 : **/
1088 :
1089 0 : static int rpc_user_password(struct net_context *c, int argc, const char **argv)
1090 : {
1091 : NET_API_STATUS status;
1092 0 : char *prompt = NULL;
1093 : struct USER_INFO_1003 u1003;
1094 0 : uint32_t parm_err = 0;
1095 : int ret;
1096 :
1097 0 : if (argc < 1 || c->display_usage) {
1098 0 : rpc_user_usage(c, argc, argv);
1099 0 : return 0;
1100 : }
1101 :
1102 0 : if (argv[1]) {
1103 0 : u1003.usri1003_password = argv[1];
1104 : } else {
1105 0 : char pwd[256] = {0};
1106 0 : ret = asprintf(&prompt, _("Enter new password for %s:"),
1107 : argv[0]);
1108 0 : if (ret == -1) {
1109 0 : return -1;
1110 : }
1111 :
1112 0 : ret = samba_getpass(prompt, pwd, sizeof(pwd), false, false);
1113 0 : SAFE_FREE(prompt);
1114 0 : if (ret < 0) {
1115 0 : return -1;
1116 : }
1117 :
1118 0 : u1003.usri1003_password = talloc_strdup(c, pwd);
1119 0 : if (u1003.usri1003_password == NULL) {
1120 0 : return -1;
1121 : }
1122 : }
1123 :
1124 0 : status = NetUserSetInfo(c->opt_host, argv[0], 1003, (uint8_t *)&u1003, &parm_err);
1125 :
1126 : /* Display results */
1127 0 : if (status != 0) {
1128 0 : d_fprintf(stderr,
1129 0 : _("Failed to set password for '%s' with error: %s.\n"),
1130 : argv[0], libnetapi_get_error_string(c->netapi_ctx,
1131 : status));
1132 0 : return -1;
1133 : }
1134 :
1135 0 : return 0;
1136 : }
1137 :
1138 : /**
1139 : * List a user's groups from a remote RPC server.
1140 : *
1141 : * @param argc Standard main() style argc.
1142 : * @param argv Standard main() style argv. Initial components are already
1143 : * stripped.
1144 : *
1145 : * @return A shell status integer (0 for success)
1146 : **/
1147 :
1148 0 : static int rpc_user_info(struct net_context *c, int argc, const char **argv)
1149 :
1150 : {
1151 : NET_API_STATUS status;
1152 0 : struct GROUP_USERS_INFO_0 *u0 = NULL;
1153 0 : uint32_t entries_read = 0;
1154 0 : uint32_t total_entries = 0;
1155 : uint32_t i;
1156 :
1157 :
1158 0 : if (argc < 1 || c->display_usage) {
1159 0 : rpc_user_usage(c, argc, argv);
1160 0 : return 0;
1161 : }
1162 :
1163 0 : status = NetUserGetGroups(c->opt_host,
1164 : argv[0],
1165 : 0,
1166 : (uint8_t **)(void *)&u0,
1167 : (uint32_t)-1,
1168 : &entries_read,
1169 : &total_entries);
1170 0 : if (status != 0) {
1171 0 : d_fprintf(stderr,
1172 0 : _("Failed to get groups for '%s' with error: %s.\n"),
1173 : argv[0], libnetapi_get_error_string(c->netapi_ctx,
1174 : status));
1175 0 : return -1;
1176 : }
1177 :
1178 0 : for (i=0; i < entries_read; i++) {
1179 0 : printf("%s\n", u0->grui0_name);
1180 0 : u0++;
1181 : }
1182 :
1183 0 : return 0;
1184 : }
1185 :
1186 : /**
1187 : * List users on a remote RPC server.
1188 : *
1189 : * All parameters are provided by the run_rpc_command function, except for
1190 : * argc, argv which are passed through.
1191 : *
1192 : * @param domain_sid The domain sid acquired from the remote server.
1193 : * @param cli A cli_state connected to the server.
1194 : * @param mem_ctx Talloc context, destroyed on completion of the function.
1195 : * @param argc Standard main() style argc.
1196 : * @param argv Standard main() style argv. Initial components are already
1197 : * stripped.
1198 : *
1199 : * @return Normal NTSTATUS return.
1200 : **/
1201 :
1202 0 : static int rpc_user_list(struct net_context *c, int argc, const char **argv)
1203 : {
1204 : NET_API_STATUS status;
1205 0 : uint32_t start_idx=0, num_entries, i, loop_count = 0;
1206 0 : struct NET_DISPLAY_USER *info = NULL;
1207 0 : void *buffer = NULL;
1208 :
1209 : /* Query domain users */
1210 0 : if (c->opt_long_list_entries)
1211 0 : d_printf(_("\nUser name Comment"
1212 : "\n-----------------------------\n"));
1213 : do {
1214 : uint32_t max_entries, max_size;
1215 :
1216 0 : dcerpc_get_query_dispinfo_params(
1217 : loop_count, &max_entries, &max_size);
1218 :
1219 0 : status = NetQueryDisplayInformation(c->opt_host,
1220 : 1,
1221 : start_idx,
1222 : max_entries,
1223 : max_size,
1224 : &num_entries,
1225 : &buffer);
1226 0 : if (status != 0 && status != ERROR_MORE_DATA) {
1227 0 : return status;
1228 : }
1229 :
1230 0 : info = (struct NET_DISPLAY_USER *)buffer;
1231 :
1232 0 : for (i = 0; i < num_entries; i++) {
1233 :
1234 0 : if (c->opt_long_list_entries)
1235 0 : printf("%-21.21s %s\n", info->usri1_name,
1236 : info->usri1_comment);
1237 : else
1238 0 : printf("%s\n", info->usri1_name);
1239 0 : info++;
1240 : }
1241 :
1242 0 : NetApiBufferFree(buffer);
1243 :
1244 0 : loop_count++;
1245 0 : start_idx += num_entries;
1246 :
1247 0 : } while (status == ERROR_MORE_DATA);
1248 :
1249 0 : return status;
1250 : }
1251 :
1252 : /**
1253 : * 'net rpc user' entrypoint.
1254 : * @param argc Standard main() style argc.
1255 : * @param argv Standard main() style argv. Initial components are already
1256 : * stripped.
1257 : **/
1258 :
1259 4 : int net_rpc_user(struct net_context *c, int argc, const char **argv)
1260 : {
1261 : NET_API_STATUS status;
1262 :
1263 4 : struct functable func[] = {
1264 : {
1265 : "add",
1266 : rpc_user_add,
1267 : NET_TRANSPORT_RPC,
1268 : N_("Add specified user"),
1269 : N_("net rpc user add\n"
1270 : " Add specified user")
1271 : },
1272 : {
1273 : "info",
1274 : rpc_user_info,
1275 : NET_TRANSPORT_RPC,
1276 : N_("List domain groups of user"),
1277 : N_("net rpc user info\n"
1278 : " List domain groups of user")
1279 : },
1280 : {
1281 : "delete",
1282 : rpc_user_delete,
1283 : NET_TRANSPORT_RPC,
1284 : N_("Remove specified user"),
1285 : N_("net rpc user delete\n"
1286 : " Remove specified user")
1287 : },
1288 : {
1289 : "password",
1290 : rpc_user_password,
1291 : NET_TRANSPORT_RPC,
1292 : N_("Change user password"),
1293 : N_("net rpc user password\n"
1294 : " Change user password")
1295 : },
1296 : {
1297 : "rename",
1298 : rpc_user_rename,
1299 : NET_TRANSPORT_RPC,
1300 : N_("Rename specified user"),
1301 : N_("net rpc user rename\n"
1302 : " Rename specified user")
1303 : },
1304 : {
1305 : "setprimarygroup",
1306 : rpc_user_setprimarygroup,
1307 : NET_TRANSPORT_RPC,
1308 : "Set a user's primary group",
1309 : "net rpc user setprimarygroup\n"
1310 : " Set a user's primary group"
1311 : },
1312 : {NULL, NULL, 0, NULL, NULL}
1313 : };
1314 :
1315 4 : status = libnetapi_net_init(&c->netapi_ctx);
1316 4 : if (status != 0) {
1317 0 : return -1;
1318 : }
1319 :
1320 4 : status = libnetapi_set_creds(c->netapi_ctx, c->creds);
1321 4 : if (status != 0) {
1322 0 : return -1;
1323 : }
1324 :
1325 4 : if (argc == 0) {
1326 0 : if (c->display_usage) {
1327 0 : d_printf( "%s\n"
1328 : "net rpc user\n"
1329 : " %s\n",
1330 : _("Usage:"),
1331 : _("List all users"));
1332 0 : net_display_usage_from_functable(func);
1333 0 : return 0;
1334 : }
1335 :
1336 0 : return rpc_user_list(c, argc, argv);
1337 : }
1338 :
1339 4 : return net_run_function(c, argc, argv, "net rpc user", func);
1340 : }
1341 :
1342 0 : static NTSTATUS rpc_sh_user_list(struct net_context *c,
1343 : TALLOC_CTX *mem_ctx,
1344 : struct rpc_sh_ctx *ctx,
1345 : struct rpc_pipe_client *pipe_hnd,
1346 : int argc, const char **argv)
1347 : {
1348 0 : return werror_to_ntstatus(W_ERROR(rpc_user_list(c, argc, argv)));
1349 : }
1350 :
1351 0 : static NTSTATUS rpc_sh_user_info(struct net_context *c,
1352 : TALLOC_CTX *mem_ctx,
1353 : struct rpc_sh_ctx *ctx,
1354 : struct rpc_pipe_client *pipe_hnd,
1355 : int argc, const char **argv)
1356 : {
1357 0 : return werror_to_ntstatus(W_ERROR(rpc_user_info(c, argc, argv)));
1358 : }
1359 :
1360 0 : static NTSTATUS rpc_sh_handle_user(struct net_context *c,
1361 : TALLOC_CTX *mem_ctx,
1362 : struct rpc_sh_ctx *ctx,
1363 : struct rpc_pipe_client *pipe_hnd,
1364 : int argc, const char **argv,
1365 : NTSTATUS (*fn)(
1366 : struct net_context *c,
1367 : TALLOC_CTX *mem_ctx,
1368 : struct rpc_sh_ctx *ctx,
1369 : struct rpc_pipe_client *pipe_hnd,
1370 : struct policy_handle *user_hnd,
1371 : int argc, const char **argv))
1372 : {
1373 : struct policy_handle connect_pol, domain_pol, user_pol;
1374 : NTSTATUS status, result;
1375 : struct dom_sid sid;
1376 : uint32_t rid;
1377 : enum lsa_SidType type;
1378 0 : struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
1379 :
1380 0 : if (argc == 0) {
1381 0 : d_fprintf(stderr, "%s %s <username>\n", _("Usage:"),
1382 : ctx->whoami);
1383 0 : return NT_STATUS_INVALID_PARAMETER;
1384 : }
1385 :
1386 0 : ZERO_STRUCT(connect_pol);
1387 0 : ZERO_STRUCT(domain_pol);
1388 0 : ZERO_STRUCT(user_pol);
1389 :
1390 0 : status = net_rpc_lookup_name(c, mem_ctx, ctx->cli,
1391 : argv[0], NULL, NULL, &sid, &type);
1392 0 : if (!NT_STATUS_IS_OK(status)) {
1393 0 : d_fprintf(stderr, _("Could not lookup %s: %s\n"), argv[0],
1394 : nt_errstr(status));
1395 0 : goto done;
1396 : }
1397 :
1398 0 : if (type != SID_NAME_USER) {
1399 0 : d_fprintf(stderr, _("%s is a %s, not a user\n"), argv[0],
1400 : sid_type_lookup(type));
1401 0 : status = NT_STATUS_NO_SUCH_USER;
1402 0 : goto done;
1403 : }
1404 :
1405 0 : if (!sid_peek_check_rid(ctx->domain_sid, &sid, &rid)) {
1406 0 : d_fprintf(stderr, _("%s is not in our domain\n"), argv[0]);
1407 0 : status = NT_STATUS_NO_SUCH_USER;
1408 0 : goto done;
1409 : }
1410 :
1411 0 : status = dcerpc_samr_Connect2(b, mem_ctx,
1412 0 : pipe_hnd->desthost,
1413 : MAXIMUM_ALLOWED_ACCESS,
1414 : &connect_pol,
1415 : &result);
1416 0 : if (!NT_STATUS_IS_OK(status)) {
1417 0 : goto done;
1418 : }
1419 0 : if (!NT_STATUS_IS_OK(result)) {
1420 0 : status = result;
1421 0 : goto done;
1422 : }
1423 :
1424 0 : status = dcerpc_samr_OpenDomain(b, mem_ctx,
1425 : &connect_pol,
1426 : MAXIMUM_ALLOWED_ACCESS,
1427 : ctx->domain_sid,
1428 : &domain_pol,
1429 : &result);
1430 0 : if (!NT_STATUS_IS_OK(status)) {
1431 0 : goto done;
1432 : }
1433 0 : if (!NT_STATUS_IS_OK(result)) {
1434 0 : status = result;
1435 0 : goto done;
1436 : }
1437 :
1438 0 : status = dcerpc_samr_OpenUser(b, mem_ctx,
1439 : &domain_pol,
1440 : MAXIMUM_ALLOWED_ACCESS,
1441 : rid,
1442 : &user_pol,
1443 : &result);
1444 0 : if (!NT_STATUS_IS_OK(status)) {
1445 0 : goto done;
1446 : }
1447 0 : if (!NT_STATUS_IS_OK(result)) {
1448 0 : status = result;
1449 0 : goto done;
1450 : }
1451 :
1452 0 : status = fn(c, mem_ctx, ctx, pipe_hnd, &user_pol, argc-1, argv+1);
1453 :
1454 0 : done:
1455 0 : if (is_valid_policy_hnd(&user_pol)) {
1456 0 : dcerpc_samr_Close(b, mem_ctx, &user_pol, &result);
1457 : }
1458 0 : if (is_valid_policy_hnd(&domain_pol)) {
1459 0 : dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
1460 : }
1461 0 : if (is_valid_policy_hnd(&connect_pol)) {
1462 0 : dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1463 : }
1464 0 : return status;
1465 : }
1466 :
1467 0 : static NTSTATUS rpc_sh_user_show_internals(struct net_context *c,
1468 : TALLOC_CTX *mem_ctx,
1469 : struct rpc_sh_ctx *ctx,
1470 : struct rpc_pipe_client *pipe_hnd,
1471 : struct policy_handle *user_hnd,
1472 : int argc, const char **argv)
1473 : {
1474 : NTSTATUS status, result;
1475 0 : union samr_UserInfo *info = NULL;
1476 0 : struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
1477 :
1478 0 : if (argc != 0) {
1479 0 : d_fprintf(stderr, "%s %s show <username>\n", _("Usage:"),
1480 : ctx->whoami);
1481 0 : return NT_STATUS_INVALID_PARAMETER;
1482 : }
1483 :
1484 0 : status = dcerpc_samr_QueryUserInfo(b, mem_ctx,
1485 : user_hnd,
1486 : 21,
1487 : &info,
1488 : &result);
1489 0 : if (!NT_STATUS_IS_OK(status)) {
1490 0 : return status;
1491 : }
1492 0 : if (!NT_STATUS_IS_OK(result)) {
1493 0 : return result;
1494 : }
1495 :
1496 0 : d_printf(_("user rid: %d, group rid: %d\n"),
1497 0 : info->info21.rid,
1498 0 : info->info21.primary_gid);
1499 :
1500 0 : return result;
1501 : }
1502 :
1503 0 : static NTSTATUS rpc_sh_user_show(struct net_context *c,
1504 : TALLOC_CTX *mem_ctx,
1505 : struct rpc_sh_ctx *ctx,
1506 : struct rpc_pipe_client *pipe_hnd,
1507 : int argc, const char **argv)
1508 : {
1509 0 : return rpc_sh_handle_user(c, mem_ctx, ctx, pipe_hnd, argc, argv,
1510 : rpc_sh_user_show_internals);
1511 : }
1512 :
1513 : #define FETCHSTR(name, rec) \
1514 : do { if (strequal(ctx->thiscmd, name)) { \
1515 : oldval = talloc_strdup(mem_ctx, info->info21.rec.string); } \
1516 : } while (0);
1517 :
1518 : #define SETSTR(name, rec, flag) \
1519 : do { if (strequal(ctx->thiscmd, name)) { \
1520 : init_lsa_String(&(info->info21.rec), argv[0]); \
1521 : info->info21.fields_present |= SAMR_FIELD_##flag; } \
1522 : } while (0);
1523 :
1524 0 : static NTSTATUS rpc_sh_user_str_edit_internals(struct net_context *c,
1525 : TALLOC_CTX *mem_ctx,
1526 : struct rpc_sh_ctx *ctx,
1527 : struct rpc_pipe_client *pipe_hnd,
1528 : struct policy_handle *user_hnd,
1529 : int argc, const char **argv)
1530 : {
1531 : NTSTATUS status, result;
1532 : const char *username;
1533 0 : const char *oldval = "";
1534 0 : union samr_UserInfo *info = NULL;
1535 0 : struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
1536 :
1537 0 : if (argc > 1) {
1538 0 : d_fprintf(stderr, "%s %s <username> [new value|NULL]\n",
1539 : _("Usage:"), ctx->whoami);
1540 0 : return NT_STATUS_INVALID_PARAMETER;
1541 : }
1542 :
1543 0 : status = dcerpc_samr_QueryUserInfo(b, mem_ctx,
1544 : user_hnd,
1545 : 21,
1546 : &info,
1547 : &result);
1548 0 : if (!NT_STATUS_IS_OK(status)) {
1549 0 : return status;
1550 : }
1551 0 : if (!NT_STATUS_IS_OK(result)) {
1552 0 : return result;
1553 : }
1554 :
1555 0 : username = talloc_strdup(mem_ctx, info->info21.account_name.string);
1556 :
1557 0 : FETCHSTR("fullname", full_name);
1558 0 : FETCHSTR("homedir", home_directory);
1559 0 : FETCHSTR("homedrive", home_drive);
1560 0 : FETCHSTR("logonscript", logon_script);
1561 0 : FETCHSTR("profilepath", profile_path);
1562 0 : FETCHSTR("description", description);
1563 :
1564 0 : if (argc == 0) {
1565 0 : d_printf(_("%s's %s: [%s]\n"), username, ctx->thiscmd, oldval);
1566 0 : goto done;
1567 : }
1568 :
1569 0 : if (strcmp(argv[0], "NULL") == 0) {
1570 0 : argv[0] = "";
1571 : }
1572 :
1573 0 : ZERO_STRUCT(info->info21);
1574 :
1575 0 : SETSTR("fullname", full_name, FULL_NAME);
1576 0 : SETSTR("homedir", home_directory, HOME_DIRECTORY);
1577 0 : SETSTR("homedrive", home_drive, HOME_DRIVE);
1578 0 : SETSTR("logonscript", logon_script, LOGON_SCRIPT);
1579 0 : SETSTR("profilepath", profile_path, PROFILE_PATH);
1580 0 : SETSTR("description", description, DESCRIPTION);
1581 :
1582 0 : status = dcerpc_samr_SetUserInfo(b, mem_ctx,
1583 : user_hnd,
1584 : 21,
1585 : info,
1586 : &result);
1587 0 : if (!NT_STATUS_IS_OK(status)) {
1588 0 : return status;
1589 : }
1590 :
1591 0 : status = result;
1592 :
1593 0 : d_printf(_("Set %s's %s from [%s] to [%s]\n"), username,
1594 : ctx->thiscmd, oldval, argv[0]);
1595 :
1596 0 : done:
1597 :
1598 0 : return status;
1599 : }
1600 :
1601 : #define HANDLEFLG(name, rec) \
1602 : do { if (strequal(ctx->thiscmd, name)) { \
1603 : oldval = (oldflags & ACB_##rec) ? "yes" : "no"; \
1604 : if (newval) { \
1605 : newflags = oldflags | ACB_##rec; \
1606 : } else { \
1607 : newflags = oldflags & ~ACB_##rec; \
1608 : } } } while (0);
1609 :
1610 0 : static NTSTATUS rpc_sh_user_str_edit(struct net_context *c,
1611 : TALLOC_CTX *mem_ctx,
1612 : struct rpc_sh_ctx *ctx,
1613 : struct rpc_pipe_client *pipe_hnd,
1614 : int argc, const char **argv)
1615 : {
1616 0 : return rpc_sh_handle_user(c, mem_ctx, ctx, pipe_hnd, argc, argv,
1617 : rpc_sh_user_str_edit_internals);
1618 : }
1619 :
1620 0 : static NTSTATUS rpc_sh_user_flag_edit_internals(struct net_context *c,
1621 : TALLOC_CTX *mem_ctx,
1622 : struct rpc_sh_ctx *ctx,
1623 : struct rpc_pipe_client *pipe_hnd,
1624 : struct policy_handle *user_hnd,
1625 : int argc, const char **argv)
1626 : {
1627 : NTSTATUS status, result;
1628 : const char *username;
1629 0 : const char *oldval = "unknown";
1630 : uint32_t oldflags, newflags;
1631 : bool newval;
1632 0 : union samr_UserInfo *info = NULL;
1633 0 : struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
1634 :
1635 0 : if ((argc > 1) ||
1636 0 : ((argc == 1) && !strequal(argv[0], "yes") &&
1637 0 : !strequal(argv[0], "no"))) {
1638 : /* TRANSATORS: The yes|no here are program keywords. Please do
1639 : not translate. */
1640 0 : d_fprintf(stderr, _("Usage: %s <username> [yes|no]\n"),
1641 : ctx->whoami);
1642 0 : return NT_STATUS_INVALID_PARAMETER;
1643 : }
1644 :
1645 0 : newval = strequal(argv[0], "yes");
1646 :
1647 0 : status = dcerpc_samr_QueryUserInfo(b, mem_ctx,
1648 : user_hnd,
1649 : 21,
1650 : &info,
1651 : &result);
1652 0 : if (!NT_STATUS_IS_OK(status)) {
1653 0 : return status;
1654 : }
1655 0 : if (!NT_STATUS_IS_OK(result)) {
1656 0 : return result;
1657 : }
1658 :
1659 0 : username = talloc_strdup(mem_ctx, info->info21.account_name.string);
1660 0 : oldflags = info->info21.acct_flags;
1661 0 : newflags = info->info21.acct_flags;
1662 :
1663 0 : HANDLEFLG("disabled", DISABLED);
1664 0 : HANDLEFLG("pwnotreq", PWNOTREQ);
1665 0 : HANDLEFLG("autolock", AUTOLOCK);
1666 0 : HANDLEFLG("pwnoexp", PWNOEXP);
1667 :
1668 0 : if (argc == 0) {
1669 0 : d_printf(_("%s's %s flag: %s\n"), username, ctx->thiscmd,
1670 : oldval);
1671 0 : goto done;
1672 : }
1673 :
1674 0 : ZERO_STRUCT(info->info21);
1675 :
1676 0 : info->info21.acct_flags = newflags;
1677 0 : info->info21.fields_present = SAMR_FIELD_ACCT_FLAGS;
1678 :
1679 0 : status = dcerpc_samr_SetUserInfo(b, mem_ctx,
1680 : user_hnd,
1681 : 21,
1682 : info,
1683 : &result);
1684 0 : if (!NT_STATUS_IS_OK(status)) {
1685 0 : goto done;
1686 : }
1687 0 : status = result;
1688 0 : if (NT_STATUS_IS_OK(result)) {
1689 0 : d_printf(_("Set %s's %s flag from [%s] to [%s]\n"), username,
1690 : ctx->thiscmd, oldval, argv[0]);
1691 : }
1692 :
1693 0 : done:
1694 :
1695 0 : return status;
1696 : }
1697 :
1698 0 : static NTSTATUS rpc_sh_user_flag_edit(struct net_context *c,
1699 : TALLOC_CTX *mem_ctx,
1700 : struct rpc_sh_ctx *ctx,
1701 : struct rpc_pipe_client *pipe_hnd,
1702 : int argc, const char **argv)
1703 : {
1704 0 : return rpc_sh_handle_user(c, mem_ctx, ctx, pipe_hnd, argc, argv,
1705 : rpc_sh_user_flag_edit_internals);
1706 : }
1707 :
1708 0 : struct rpc_sh_cmd *net_rpc_user_edit_cmds(struct net_context *c,
1709 : TALLOC_CTX *mem_ctx,
1710 : struct rpc_sh_ctx *ctx)
1711 : {
1712 : static struct rpc_sh_cmd cmds[] = {
1713 :
1714 : { "fullname", NULL, &ndr_table_samr, rpc_sh_user_str_edit,
1715 : N_("Show/Set a user's full name") },
1716 :
1717 : { "homedir", NULL, &ndr_table_samr, rpc_sh_user_str_edit,
1718 : N_("Show/Set a user's home directory") },
1719 :
1720 : { "homedrive", NULL, &ndr_table_samr, rpc_sh_user_str_edit,
1721 : N_("Show/Set a user's home drive") },
1722 :
1723 : { "logonscript", NULL, &ndr_table_samr, rpc_sh_user_str_edit,
1724 : N_("Show/Set a user's logon script") },
1725 :
1726 : { "profilepath", NULL, &ndr_table_samr, rpc_sh_user_str_edit,
1727 : N_("Show/Set a user's profile path") },
1728 :
1729 : { "description", NULL, &ndr_table_samr, rpc_sh_user_str_edit,
1730 : N_("Show/Set a user's description") },
1731 :
1732 : { "disabled", NULL, &ndr_table_samr, rpc_sh_user_flag_edit,
1733 : N_("Show/Set whether a user is disabled") },
1734 :
1735 : { "autolock", NULL, &ndr_table_samr, rpc_sh_user_flag_edit,
1736 : N_("Show/Set whether a user locked out") },
1737 :
1738 : { "pwnotreq", NULL, &ndr_table_samr, rpc_sh_user_flag_edit,
1739 : N_("Show/Set whether a user does not need a password") },
1740 :
1741 : { "pwnoexp", NULL, &ndr_table_samr, rpc_sh_user_flag_edit,
1742 : N_("Show/Set whether a user's password does not expire") },
1743 :
1744 : { NULL, NULL, 0, NULL, NULL }
1745 : };
1746 :
1747 0 : return cmds;
1748 : }
1749 :
1750 0 : struct rpc_sh_cmd *net_rpc_user_cmds(struct net_context *c,
1751 : TALLOC_CTX *mem_ctx,
1752 : struct rpc_sh_ctx *ctx)
1753 : {
1754 : static struct rpc_sh_cmd cmds[] = {
1755 :
1756 : { "list", NULL, &ndr_table_samr, rpc_sh_user_list,
1757 : N_("List available users") },
1758 :
1759 : { "info", NULL, &ndr_table_samr, rpc_sh_user_info,
1760 : N_("List the domain groups a user is member of") },
1761 :
1762 : { "show", NULL, &ndr_table_samr, rpc_sh_user_show,
1763 : N_("Show info about a user") },
1764 :
1765 : { "edit", net_rpc_user_edit_cmds, 0, NULL,
1766 : N_("Show/Modify a user's fields") },
1767 :
1768 : { NULL, NULL, 0, NULL, NULL }
1769 : };
1770 :
1771 0 : return cmds;
1772 : }
1773 :
1774 : /****************************************************************************/
1775 :
1776 : /**
1777 : * Basic usage function for 'net rpc group'.
1778 : * @param argc Standard main() style argc.
1779 : * @param argv Standard main() style argv. Initial components are already
1780 : * stripped.
1781 : **/
1782 :
1783 0 : static int rpc_group_usage(struct net_context *c, int argc, const char **argv)
1784 : {
1785 0 : return net_group_usage(c, argc, argv);
1786 : }
1787 :
1788 : /**
1789 : * Delete group on a remote RPC server.
1790 : *
1791 : * All parameters are provided by the run_rpc_command function, except for
1792 : * argc, argv which are passed through.
1793 : *
1794 : * @param domain_sid The domain sid acquired from the remote server.
1795 : * @param cli A cli_state connected to the server.
1796 : * @param mem_ctx Talloc context, destroyed on completion of the function.
1797 : * @param argc Standard main() style argc.
1798 : * @param argv Standard main() style argv. Initial components are already
1799 : * stripped.
1800 : *
1801 : * @return Normal NTSTATUS return.
1802 : **/
1803 :
1804 70 : static NTSTATUS rpc_group_delete_internals(struct net_context *c,
1805 : const struct dom_sid *domain_sid,
1806 : const char *domain_name,
1807 : struct cli_state *cli,
1808 : struct rpc_pipe_client *pipe_hnd,
1809 : TALLOC_CTX *mem_ctx,
1810 : int argc,
1811 : const char **argv)
1812 : {
1813 : struct policy_handle connect_pol, domain_pol, group_pol, user_pol;
1814 70 : bool group_is_primary = false;
1815 : NTSTATUS status, result;
1816 : uint32_t group_rid;
1817 70 : struct samr_RidAttrArray *rids = NULL;
1818 : /* char **names; */
1819 : uint32_t i;
1820 : /* struct samr_RidWithAttribute *user_gids; */
1821 70 : struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
1822 :
1823 : struct samr_Ids group_rids, name_types;
1824 : struct lsa_String lsa_acct_name;
1825 70 : union samr_UserInfo *info = NULL;
1826 :
1827 70 : if (argc < 1 || c->display_usage) {
1828 0 : rpc_group_usage(c, argc,argv);
1829 0 : return NT_STATUS_OK; /* ok? */
1830 : }
1831 :
1832 70 : status = dcerpc_samr_Connect2(b, mem_ctx,
1833 70 : pipe_hnd->desthost,
1834 : MAXIMUM_ALLOWED_ACCESS,
1835 : &connect_pol,
1836 : &result);
1837 70 : if (!NT_STATUS_IS_OK(status)) {
1838 0 : d_fprintf(stderr, _("Request samr_Connect2 failed\n"));
1839 0 : goto done;
1840 : }
1841 :
1842 70 : if (!NT_STATUS_IS_OK(result)) {
1843 0 : status = result;
1844 0 : d_fprintf(stderr, _("Request samr_Connect2 failed\n"));
1845 0 : goto done;
1846 : }
1847 :
1848 70 : status = dcerpc_samr_OpenDomain(b, mem_ctx,
1849 : &connect_pol,
1850 : MAXIMUM_ALLOWED_ACCESS,
1851 : discard_const_p(struct dom_sid2, domain_sid),
1852 : &domain_pol,
1853 : &result);
1854 70 : if (!NT_STATUS_IS_OK(status)) {
1855 0 : d_fprintf(stderr, _("Request open_domain failed\n"));
1856 0 : goto done;
1857 : }
1858 :
1859 70 : if (!NT_STATUS_IS_OK(result)) {
1860 0 : status = result;
1861 0 : d_fprintf(stderr, _("Request open_domain failed\n"));
1862 0 : goto done;
1863 : }
1864 :
1865 70 : init_lsa_String(&lsa_acct_name, argv[0]);
1866 :
1867 70 : status = dcerpc_samr_LookupNames(b, mem_ctx,
1868 : &domain_pol,
1869 : 1,
1870 : &lsa_acct_name,
1871 : &group_rids,
1872 : &name_types,
1873 : &result);
1874 70 : if (!NT_STATUS_IS_OK(status)) {
1875 0 : d_fprintf(stderr, _("Lookup of '%s' failed\n"),argv[0]);
1876 0 : goto done;
1877 : }
1878 :
1879 70 : if (!NT_STATUS_IS_OK(result)) {
1880 0 : status = result;
1881 0 : d_fprintf(stderr, _("Lookup of '%s' failed\n"),argv[0]);
1882 0 : goto done;
1883 : }
1884 70 : if (group_rids.count != 1) {
1885 0 : status = NT_STATUS_INVALID_NETWORK_RESPONSE;
1886 0 : goto done;
1887 : }
1888 70 : if (name_types.count != 1) {
1889 0 : status = NT_STATUS_INVALID_NETWORK_RESPONSE;
1890 0 : goto done;
1891 : }
1892 :
1893 70 : switch (name_types.ids[0])
1894 : {
1895 70 : case SID_NAME_DOM_GRP:
1896 70 : status = dcerpc_samr_OpenGroup(b, mem_ctx,
1897 : &domain_pol,
1898 : MAXIMUM_ALLOWED_ACCESS,
1899 70 : group_rids.ids[0],
1900 : &group_pol,
1901 : &result);
1902 70 : if (!NT_STATUS_IS_OK(status)) {
1903 0 : d_fprintf(stderr, _("Request open_group failed"));
1904 0 : goto done;
1905 : }
1906 :
1907 70 : if (!NT_STATUS_IS_OK(result)) {
1908 0 : status = result;
1909 0 : d_fprintf(stderr, _("Request open_group failed"));
1910 0 : goto done;
1911 : }
1912 :
1913 70 : group_rid = group_rids.ids[0];
1914 :
1915 70 : status = dcerpc_samr_QueryGroupMember(b, mem_ctx,
1916 : &group_pol,
1917 : &rids,
1918 : &result);
1919 70 : if (!NT_STATUS_IS_OK(status)) {
1920 0 : d_fprintf(stderr,
1921 0 : _("Unable to query group members of %s"),
1922 : argv[0]);
1923 0 : goto done;
1924 : }
1925 :
1926 70 : if (!NT_STATUS_IS_OK(result)) {
1927 0 : status = result;
1928 0 : d_fprintf(stderr,
1929 0 : _("Unable to query group members of %s"),
1930 : argv[0]);
1931 0 : goto done;
1932 : }
1933 :
1934 70 : if (c->opt_verbose) {
1935 0 : d_printf(
1936 0 : _("Domain Group %s (rid: %d) has %d members\n"),
1937 0 : argv[0],group_rid, rids->count);
1938 : }
1939 :
1940 : /* Check if group is anyone's primary group */
1941 140 : for (i = 0; i < rids->count; i++)
1942 : {
1943 70 : status = dcerpc_samr_OpenUser(b, mem_ctx,
1944 : &domain_pol,
1945 : MAXIMUM_ALLOWED_ACCESS,
1946 70 : rids->rids[i],
1947 : &user_pol,
1948 : &result);
1949 70 : if (!NT_STATUS_IS_OK(status)) {
1950 0 : d_fprintf(stderr,
1951 0 : _("Unable to open group member %d\n"),
1952 0 : rids->rids[i]);
1953 0 : goto done;
1954 : }
1955 :
1956 70 : if (!NT_STATUS_IS_OK(result)) {
1957 0 : status = result;
1958 0 : d_fprintf(stderr,
1959 0 : _("Unable to open group member %d\n"),
1960 0 : rids->rids[i]);
1961 0 : goto done;
1962 : }
1963 :
1964 70 : status = dcerpc_samr_QueryUserInfo(b, mem_ctx,
1965 : &user_pol,
1966 : 21,
1967 : &info,
1968 : &result);
1969 70 : if (!NT_STATUS_IS_OK(status)) {
1970 0 : d_fprintf(stderr,
1971 0 : _("Unable to lookup userinfo for group "
1972 : "member %d\n"),
1973 0 : rids->rids[i]);
1974 0 : goto done;
1975 : }
1976 :
1977 70 : if (!NT_STATUS_IS_OK(result)) {
1978 0 : status = result;
1979 0 : d_fprintf(stderr,
1980 0 : _("Unable to lookup userinfo for group "
1981 : "member %d\n"),
1982 0 : rids->rids[i]);
1983 0 : goto done;
1984 : }
1985 :
1986 70 : if (info->info21.primary_gid == group_rid) {
1987 0 : if (c->opt_verbose) {
1988 0 : d_printf(_("Group is primary group "
1989 : "of %s\n"),
1990 0 : info->info21.account_name.string);
1991 : }
1992 0 : group_is_primary = true;
1993 : }
1994 :
1995 70 : dcerpc_samr_Close(b, mem_ctx, &user_pol, &result);
1996 : }
1997 :
1998 70 : if (group_is_primary) {
1999 0 : d_fprintf(stderr, _("Unable to delete group because "
2000 : "some of it's members have it as primary "
2001 : "group\n"));
2002 0 : status = NT_STATUS_MEMBERS_PRIMARY_GROUP;
2003 0 : goto done;
2004 : }
2005 :
2006 : /* remove all group members */
2007 140 : for (i = 0; i < rids->count; i++)
2008 : {
2009 70 : if (c->opt_verbose)
2010 0 : d_printf(_("Remove group member %d..."),
2011 0 : rids->rids[i]);
2012 70 : status = dcerpc_samr_DeleteGroupMember(b, mem_ctx,
2013 : &group_pol,
2014 70 : rids->rids[i],
2015 : &result);
2016 70 : if (!NT_STATUS_IS_OK(status)) {
2017 0 : goto done;
2018 : }
2019 70 : status = result;
2020 70 : if (NT_STATUS_IS_OK(result)) {
2021 70 : if (c->opt_verbose)
2022 0 : d_printf(_("ok\n"));
2023 : } else {
2024 0 : if (c->opt_verbose)
2025 0 : d_printf("%s\n", _("failed"));
2026 0 : goto done;
2027 : }
2028 : }
2029 :
2030 70 : status = dcerpc_samr_DeleteDomainGroup(b, mem_ctx,
2031 : &group_pol,
2032 : &result);
2033 70 : if (!NT_STATUS_IS_OK(status)) {
2034 0 : break;
2035 : }
2036 :
2037 70 : status = result;
2038 :
2039 70 : break;
2040 : /* removing a local group is easier... */
2041 0 : case SID_NAME_ALIAS:
2042 0 : status = dcerpc_samr_OpenAlias(b, mem_ctx,
2043 : &domain_pol,
2044 : MAXIMUM_ALLOWED_ACCESS,
2045 0 : group_rids.ids[0],
2046 : &group_pol,
2047 : &result);
2048 0 : if (!NT_STATUS_IS_OK(status)) {
2049 0 : d_fprintf(stderr, _("Request open_alias failed\n"));
2050 0 : goto done;
2051 : }
2052 0 : if (!NT_STATUS_IS_OK(result)) {
2053 0 : status = result;
2054 0 : d_fprintf(stderr, _("Request open_alias failed\n"));
2055 0 : goto done;
2056 : }
2057 :
2058 0 : status = dcerpc_samr_DeleteDomAlias(b, mem_ctx,
2059 : &group_pol,
2060 : &result);
2061 0 : if (!NT_STATUS_IS_OK(status)) {
2062 0 : break;
2063 : }
2064 :
2065 0 : status = result;
2066 :
2067 0 : break;
2068 0 : default:
2069 0 : d_fprintf(stderr, _("%s is of type %s. This command is only "
2070 : "for deleting local or global groups\n"),
2071 0 : argv[0],sid_type_lookup(name_types.ids[0]));
2072 0 : status = NT_STATUS_UNSUCCESSFUL;
2073 0 : goto done;
2074 : }
2075 :
2076 70 : if (NT_STATUS_IS_OK(status)) {
2077 70 : if (c->opt_verbose)
2078 0 : d_printf(_("Deleted %s '%s'\n"),
2079 0 : sid_type_lookup(name_types.ids[0]), argv[0]);
2080 : } else {
2081 0 : d_fprintf(stderr, _("Deleting of %s failed: %s\n"), argv[0],
2082 : get_friendly_nt_error_msg(status));
2083 : }
2084 :
2085 70 : done:
2086 70 : return status;
2087 :
2088 : }
2089 :
2090 70 : static int rpc_group_delete(struct net_context *c, int argc, const char **argv)
2091 : {
2092 70 : return run_rpc_command(c, NULL, &ndr_table_samr, 0,
2093 : rpc_group_delete_internals, argc,argv);
2094 : }
2095 :
2096 70 : static int rpc_group_add_internals(struct net_context *c, int argc, const char **argv)
2097 : {
2098 : NET_API_STATUS status;
2099 : struct GROUP_INFO_1 info1;
2100 70 : uint32_t parm_error = 0;
2101 :
2102 70 : if (argc != 1 || c->display_usage) {
2103 0 : rpc_group_usage(c, argc, argv);
2104 0 : return 0;
2105 : }
2106 :
2107 70 : ZERO_STRUCT(info1);
2108 :
2109 70 : info1.grpi1_name = argv[0];
2110 70 : if (c->opt_comment && strlen(c->opt_comment) > 0) {
2111 0 : info1.grpi1_comment = c->opt_comment;
2112 : }
2113 :
2114 70 : status = NetGroupAdd(c->opt_host, 1, (uint8_t *)&info1, &parm_error);
2115 :
2116 70 : if (status != 0) {
2117 0 : d_fprintf(stderr,
2118 0 : _("Failed to add group '%s' with error: %s.\n"),
2119 : argv[0], libnetapi_get_error_string(c->netapi_ctx,
2120 : status));
2121 0 : return -1;
2122 : } else {
2123 70 : d_printf(_("Added group '%s'.\n"), argv[0]);
2124 : }
2125 :
2126 70 : return 0;
2127 : }
2128 :
2129 0 : static int rpc_alias_add_internals(struct net_context *c, int argc, const char **argv)
2130 : {
2131 : NET_API_STATUS status;
2132 : struct LOCALGROUP_INFO_1 info1;
2133 0 : uint32_t parm_error = 0;
2134 :
2135 0 : if (argc != 1 || c->display_usage) {
2136 0 : rpc_group_usage(c, argc, argv);
2137 0 : return 0;
2138 : }
2139 :
2140 0 : ZERO_STRUCT(info1);
2141 :
2142 0 : info1.lgrpi1_name = argv[0];
2143 0 : if (c->opt_comment && strlen(c->opt_comment) > 0) {
2144 0 : info1.lgrpi1_comment = c->opt_comment;
2145 : }
2146 :
2147 0 : status = NetLocalGroupAdd(c->opt_host, 1, (uint8_t *)&info1, &parm_error);
2148 :
2149 0 : if (status != 0) {
2150 0 : d_fprintf(stderr,
2151 0 : _("Failed to add alias '%s' with error: %s.\n"),
2152 : argv[0], libnetapi_get_error_string(c->netapi_ctx,
2153 : status));
2154 0 : return -1;
2155 : } else {
2156 0 : d_printf(_("Added alias '%s'.\n"), argv[0]);
2157 : }
2158 :
2159 0 : return 0;
2160 : }
2161 :
2162 70 : static int rpc_group_add(struct net_context *c, int argc, const char **argv)
2163 : {
2164 70 : if (c->opt_localgroup)
2165 0 : return rpc_alias_add_internals(c, argc, argv);
2166 :
2167 70 : return rpc_group_add_internals(c, argc, argv);
2168 : }
2169 :
2170 70 : static NTSTATUS get_sid_from_name(struct cli_state *cli,
2171 : TALLOC_CTX *mem_ctx,
2172 : const char *name,
2173 : struct dom_sid *sid,
2174 : enum lsa_SidType *type)
2175 : {
2176 70 : struct dom_sid *sids = NULL;
2177 70 : enum lsa_SidType *types = NULL;
2178 70 : struct rpc_pipe_client *pipe_hnd = NULL;
2179 : struct policy_handle lsa_pol;
2180 : NTSTATUS status, result;
2181 : struct dcerpc_binding_handle *b;
2182 :
2183 70 : status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc,
2184 : &pipe_hnd);
2185 70 : if (!NT_STATUS_IS_OK(status)) {
2186 0 : goto done;
2187 : }
2188 :
2189 70 : b = pipe_hnd->binding_handle;
2190 :
2191 70 : status = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, false,
2192 : SEC_FLAG_MAXIMUM_ALLOWED, &lsa_pol);
2193 :
2194 70 : if (!NT_STATUS_IS_OK(status)) {
2195 0 : goto done;
2196 : }
2197 :
2198 70 : status = rpccli_lsa_lookup_names(pipe_hnd, mem_ctx, &lsa_pol, 1,
2199 : &name, NULL, 1, &sids, &types);
2200 :
2201 70 : if (NT_STATUS_IS_OK(status)) {
2202 70 : sid_copy(sid, &sids[0]);
2203 70 : *type = types[0];
2204 : }
2205 :
2206 70 : dcerpc_lsa_Close(b, mem_ctx, &lsa_pol, &result);
2207 :
2208 70 : done:
2209 70 : if (pipe_hnd) {
2210 70 : TALLOC_FREE(pipe_hnd);
2211 : }
2212 :
2213 70 : if (!NT_STATUS_IS_OK(status) && (strncasecmp_m(name, "S-", 2) == 0)) {
2214 :
2215 : /* Try as S-1-5-whatever */
2216 :
2217 : struct dom_sid tmp_sid;
2218 :
2219 0 : if (string_to_sid(&tmp_sid, name)) {
2220 0 : sid_copy(sid, &tmp_sid);
2221 0 : *type = SID_NAME_UNKNOWN;
2222 0 : status = NT_STATUS_OK;
2223 : }
2224 : }
2225 :
2226 70 : return status;
2227 : }
2228 :
2229 70 : static NTSTATUS rpc_add_groupmem(struct rpc_pipe_client *pipe_hnd,
2230 : TALLOC_CTX *mem_ctx,
2231 : const struct dom_sid *group_sid,
2232 : const char *member)
2233 : {
2234 : struct policy_handle connect_pol, domain_pol;
2235 : NTSTATUS status, result;
2236 : uint32_t group_rid;
2237 : struct policy_handle group_pol;
2238 70 : struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
2239 :
2240 : struct samr_Ids rids, rid_types;
2241 : struct lsa_String lsa_acct_name;
2242 :
2243 : struct dom_sid sid;
2244 :
2245 70 : sid_copy(&sid, group_sid);
2246 :
2247 70 : if (!sid_split_rid(&sid, &group_rid)) {
2248 0 : return NT_STATUS_UNSUCCESSFUL;
2249 : }
2250 :
2251 : /* Get sam policy handle */
2252 70 : status = dcerpc_samr_Connect2(b, mem_ctx,
2253 70 : pipe_hnd->desthost,
2254 : MAXIMUM_ALLOWED_ACCESS,
2255 : &connect_pol,
2256 : &result);
2257 70 : if (!NT_STATUS_IS_OK(status)) {
2258 0 : return status;
2259 : }
2260 70 : if (!NT_STATUS_IS_OK(result)) {
2261 0 : return result;
2262 : }
2263 :
2264 : /* Get domain policy handle */
2265 70 : status = dcerpc_samr_OpenDomain(b, mem_ctx,
2266 : &connect_pol,
2267 : MAXIMUM_ALLOWED_ACCESS,
2268 : &sid,
2269 : &domain_pol,
2270 : &result);
2271 70 : if (!NT_STATUS_IS_OK(status)) {
2272 0 : return status;
2273 : }
2274 70 : if (!NT_STATUS_IS_OK(result)) {
2275 0 : return result;
2276 : }
2277 :
2278 70 : init_lsa_String(&lsa_acct_name, member);
2279 :
2280 70 : status = dcerpc_samr_LookupNames(b, mem_ctx,
2281 : &domain_pol,
2282 : 1,
2283 : &lsa_acct_name,
2284 : &rids,
2285 : &rid_types,
2286 : &result);
2287 70 : if (!NT_STATUS_IS_OK(status)) {
2288 0 : d_fprintf(stderr, _("Could not lookup up group member %s\n"),
2289 : member);
2290 0 : goto done;
2291 : }
2292 :
2293 70 : if (!NT_STATUS_IS_OK(result)) {
2294 0 : status = result;
2295 0 : d_fprintf(stderr, _("Could not lookup up group member %s\n"),
2296 : member);
2297 0 : goto done;
2298 : }
2299 70 : if (rids.count != 1) {
2300 0 : status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2301 0 : goto done;
2302 : }
2303 70 : if (rid_types.count != 1) {
2304 0 : status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2305 0 : goto done;
2306 : }
2307 :
2308 70 : status = dcerpc_samr_OpenGroup(b, mem_ctx,
2309 : &domain_pol,
2310 : MAXIMUM_ALLOWED_ACCESS,
2311 : group_rid,
2312 : &group_pol,
2313 : &result);
2314 70 : if (!NT_STATUS_IS_OK(status)) {
2315 0 : goto done;
2316 : }
2317 :
2318 70 : if (!NT_STATUS_IS_OK(result)) {
2319 0 : status = result;
2320 0 : goto done;
2321 : }
2322 :
2323 70 : status = dcerpc_samr_AddGroupMember(b, mem_ctx,
2324 : &group_pol,
2325 70 : rids.ids[0],
2326 : 0x0005, /* unknown flags */
2327 : &result);
2328 70 : if (!NT_STATUS_IS_OK(status)) {
2329 0 : goto done;
2330 : }
2331 :
2332 70 : status = result;
2333 :
2334 70 : done:
2335 70 : dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2336 70 : return status;
2337 : }
2338 :
2339 0 : static NTSTATUS rpc_add_aliasmem(struct rpc_pipe_client *pipe_hnd,
2340 : struct cli_state *cli,
2341 : TALLOC_CTX *mem_ctx,
2342 : const struct dom_sid *alias_sid,
2343 : const char *member)
2344 : {
2345 : struct policy_handle connect_pol, domain_pol;
2346 : NTSTATUS status, result;
2347 : uint32_t alias_rid;
2348 : struct policy_handle alias_pol;
2349 0 : struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
2350 :
2351 : struct dom_sid member_sid;
2352 : enum lsa_SidType member_type;
2353 :
2354 : struct dom_sid sid;
2355 :
2356 0 : sid_copy(&sid, alias_sid);
2357 :
2358 0 : if (!sid_split_rid(&sid, &alias_rid)) {
2359 0 : return NT_STATUS_UNSUCCESSFUL;
2360 : }
2361 :
2362 0 : result = get_sid_from_name(cli, mem_ctx,
2363 : member, &member_sid, &member_type);
2364 :
2365 0 : if (!NT_STATUS_IS_OK(result)) {
2366 0 : d_fprintf(stderr, _("Could not lookup up group member %s\n"),
2367 : member);
2368 0 : return result;
2369 : }
2370 :
2371 : /* Get sam policy handle */
2372 0 : status = dcerpc_samr_Connect2(b, mem_ctx,
2373 0 : pipe_hnd->desthost,
2374 : MAXIMUM_ALLOWED_ACCESS,
2375 : &connect_pol,
2376 : &result);
2377 0 : if (!NT_STATUS_IS_OK(status)) {
2378 0 : goto done;
2379 : }
2380 0 : if (!NT_STATUS_IS_OK(result)) {
2381 0 : status = result;
2382 0 : goto done;
2383 : }
2384 :
2385 : /* Get domain policy handle */
2386 0 : status = dcerpc_samr_OpenDomain(b, mem_ctx,
2387 : &connect_pol,
2388 : MAXIMUM_ALLOWED_ACCESS,
2389 : &sid,
2390 : &domain_pol,
2391 : &result);
2392 0 : if (!NT_STATUS_IS_OK(status)) {
2393 0 : goto done;
2394 : }
2395 0 : if (!NT_STATUS_IS_OK(result)) {
2396 0 : status = result;
2397 0 : goto done;
2398 : }
2399 :
2400 0 : status = dcerpc_samr_OpenAlias(b, mem_ctx,
2401 : &domain_pol,
2402 : MAXIMUM_ALLOWED_ACCESS,
2403 : alias_rid,
2404 : &alias_pol,
2405 : &result);
2406 0 : if (!NT_STATUS_IS_OK(status)) {
2407 0 : return status;
2408 : }
2409 0 : if (!NT_STATUS_IS_OK(result)) {
2410 0 : return result;
2411 : }
2412 :
2413 0 : status = dcerpc_samr_AddAliasMember(b, mem_ctx,
2414 : &alias_pol,
2415 : &member_sid,
2416 : &result);
2417 0 : if (!NT_STATUS_IS_OK(status)) {
2418 0 : return status;
2419 : }
2420 :
2421 0 : status = result;
2422 :
2423 0 : done:
2424 0 : dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2425 0 : return status;
2426 : }
2427 :
2428 70 : static NTSTATUS rpc_group_addmem_internals(struct net_context *c,
2429 : const struct dom_sid *domain_sid,
2430 : const char *domain_name,
2431 : struct cli_state *cli,
2432 : struct rpc_pipe_client *pipe_hnd,
2433 : TALLOC_CTX *mem_ctx,
2434 : int argc,
2435 : const char **argv)
2436 : {
2437 : struct dom_sid group_sid;
2438 : enum lsa_SidType group_type;
2439 :
2440 70 : if (argc != 2 || c->display_usage) {
2441 0 : d_printf("%s\n%s",
2442 : _("Usage:"),
2443 : _("net rpc group addmem <group> <member>\n"
2444 : " Add a member to a group\n"
2445 : " group\tGroup to add member to\n"
2446 : " member\tMember to add to group\n"));
2447 0 : return NT_STATUS_UNSUCCESSFUL;
2448 : }
2449 :
2450 70 : if (!NT_STATUS_IS_OK(get_sid_from_name(cli, mem_ctx, argv[0],
2451 : &group_sid, &group_type))) {
2452 0 : d_fprintf(stderr, _("Could not lookup group name %s\n"),
2453 : argv[0]);
2454 0 : return NT_STATUS_UNSUCCESSFUL;
2455 : }
2456 :
2457 70 : if (group_type == SID_NAME_DOM_GRP) {
2458 70 : NTSTATUS result = rpc_add_groupmem(pipe_hnd, mem_ctx,
2459 70 : &group_sid, argv[1]);
2460 :
2461 70 : if (!NT_STATUS_IS_OK(result)) {
2462 0 : d_fprintf(stderr, _("Could not add %s to %s: %s\n"),
2463 0 : argv[1], argv[0], nt_errstr(result));
2464 : }
2465 70 : return result;
2466 : }
2467 :
2468 0 : if (group_type == SID_NAME_ALIAS) {
2469 0 : NTSTATUS result = rpc_add_aliasmem(pipe_hnd, cli, mem_ctx,
2470 0 : &group_sid, argv[1]);
2471 :
2472 0 : if (!NT_STATUS_IS_OK(result)) {
2473 0 : d_fprintf(stderr, _("Could not add %s to %s: %s\n"),
2474 0 : argv[1], argv[0], nt_errstr(result));
2475 : }
2476 0 : return result;
2477 : }
2478 :
2479 0 : d_fprintf(stderr, _("Can only add members to global or local groups "
2480 : "which %s is not\n"), argv[0]);
2481 :
2482 0 : return NT_STATUS_UNSUCCESSFUL;
2483 : }
2484 :
2485 70 : static int rpc_group_addmem(struct net_context *c, int argc, const char **argv)
2486 : {
2487 70 : return run_rpc_command(c, NULL, &ndr_table_samr, 0,
2488 : rpc_group_addmem_internals,
2489 : argc, argv);
2490 : }
2491 :
2492 0 : static NTSTATUS rpc_del_groupmem(struct net_context *c,
2493 : struct rpc_pipe_client *pipe_hnd,
2494 : TALLOC_CTX *mem_ctx,
2495 : const struct dom_sid *group_sid,
2496 : const char *member)
2497 : {
2498 : struct policy_handle connect_pol, domain_pol;
2499 : NTSTATUS status, result;
2500 : uint32_t group_rid;
2501 : struct policy_handle group_pol;
2502 0 : struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
2503 :
2504 : struct samr_Ids rids, rid_types;
2505 : struct lsa_String lsa_acct_name;
2506 :
2507 : struct dom_sid sid;
2508 :
2509 0 : sid_copy(&sid, group_sid);
2510 :
2511 0 : if (!sid_split_rid(&sid, &group_rid))
2512 0 : return NT_STATUS_UNSUCCESSFUL;
2513 :
2514 : /* Get sam policy handle */
2515 0 : status = dcerpc_samr_Connect2(b, mem_ctx,
2516 0 : pipe_hnd->desthost,
2517 : MAXIMUM_ALLOWED_ACCESS,
2518 : &connect_pol,
2519 : &result);
2520 0 : if (!NT_STATUS_IS_OK(status)) {
2521 0 : return status;
2522 : }
2523 0 : if (!NT_STATUS_IS_OK(result)) {
2524 0 : return result;
2525 : }
2526 :
2527 :
2528 : /* Get domain policy handle */
2529 0 : status = dcerpc_samr_OpenDomain(b, mem_ctx,
2530 : &connect_pol,
2531 : MAXIMUM_ALLOWED_ACCESS,
2532 : &sid,
2533 : &domain_pol,
2534 : &result);
2535 0 : if (!NT_STATUS_IS_OK(status)) {
2536 0 : return status;
2537 : }
2538 0 : if (!NT_STATUS_IS_OK(result)) {
2539 0 : return result;
2540 : }
2541 :
2542 0 : init_lsa_String(&lsa_acct_name, member);
2543 :
2544 0 : status = dcerpc_samr_LookupNames(b, mem_ctx,
2545 : &domain_pol,
2546 : 1,
2547 : &lsa_acct_name,
2548 : &rids,
2549 : &rid_types,
2550 : &result);
2551 0 : if (!NT_STATUS_IS_OK(status)) {
2552 0 : d_fprintf(stderr, _("Could not lookup up group member %s\n"),
2553 : member);
2554 0 : goto done;
2555 : }
2556 :
2557 0 : if (!NT_STATUS_IS_OK(result)) {
2558 0 : status = result;
2559 0 : d_fprintf(stderr, _("Could not lookup up group member %s\n"),
2560 : member);
2561 0 : goto done;
2562 : }
2563 0 : if (rids.count != 1) {
2564 0 : status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2565 0 : goto done;
2566 : }
2567 0 : if (rid_types.count != 1) {
2568 0 : status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2569 0 : goto done;
2570 : }
2571 :
2572 0 : status = dcerpc_samr_OpenGroup(b, mem_ctx,
2573 : &domain_pol,
2574 : MAXIMUM_ALLOWED_ACCESS,
2575 : group_rid,
2576 : &group_pol,
2577 : &result);
2578 0 : if (!NT_STATUS_IS_OK(status)) {
2579 0 : goto done;
2580 : }
2581 0 : if (!NT_STATUS_IS_OK(result)) {
2582 0 : status = result;
2583 0 : goto done;
2584 : }
2585 :
2586 0 : status = dcerpc_samr_DeleteGroupMember(b, mem_ctx,
2587 : &group_pol,
2588 0 : rids.ids[0],
2589 : &result);
2590 0 : if (!NT_STATUS_IS_OK(status)) {
2591 0 : goto done;
2592 : }
2593 :
2594 0 : status = result;
2595 0 : done:
2596 0 : dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2597 0 : return status;
2598 : }
2599 :
2600 0 : static NTSTATUS rpc_del_aliasmem(struct rpc_pipe_client *pipe_hnd,
2601 : struct cli_state *cli,
2602 : TALLOC_CTX *mem_ctx,
2603 : const struct dom_sid *alias_sid,
2604 : const char *member)
2605 : {
2606 : struct policy_handle connect_pol, domain_pol;
2607 : NTSTATUS status, result;
2608 : uint32_t alias_rid;
2609 : struct policy_handle alias_pol;
2610 0 : struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
2611 :
2612 : struct dom_sid member_sid;
2613 : enum lsa_SidType member_type;
2614 :
2615 : struct dom_sid sid;
2616 :
2617 0 : sid_copy(&sid, alias_sid);
2618 :
2619 0 : if (!sid_split_rid(&sid, &alias_rid))
2620 0 : return NT_STATUS_UNSUCCESSFUL;
2621 :
2622 0 : result = get_sid_from_name(cli, mem_ctx,
2623 : member, &member_sid, &member_type);
2624 :
2625 0 : if (!NT_STATUS_IS_OK(result)) {
2626 0 : d_fprintf(stderr, _("Could not lookup up group member %s\n"),
2627 : member);
2628 0 : return result;
2629 : }
2630 :
2631 : /* Get sam policy handle */
2632 0 : status = dcerpc_samr_Connect2(b, mem_ctx,
2633 0 : pipe_hnd->desthost,
2634 : MAXIMUM_ALLOWED_ACCESS,
2635 : &connect_pol,
2636 : &result);
2637 0 : if (!NT_STATUS_IS_OK(status)) {
2638 0 : goto done;
2639 : }
2640 0 : if (!NT_STATUS_IS_OK(result)) {
2641 0 : status = result;
2642 0 : goto done;
2643 : }
2644 :
2645 : /* Get domain policy handle */
2646 0 : status = dcerpc_samr_OpenDomain(b, mem_ctx,
2647 : &connect_pol,
2648 : MAXIMUM_ALLOWED_ACCESS,
2649 : &sid,
2650 : &domain_pol,
2651 : &result);
2652 0 : if (!NT_STATUS_IS_OK(status)) {
2653 0 : goto done;
2654 : }
2655 0 : if (!NT_STATUS_IS_OK(result)) {
2656 0 : status = result;
2657 0 : goto done;
2658 : }
2659 :
2660 0 : status = dcerpc_samr_OpenAlias(b, mem_ctx,
2661 : &domain_pol,
2662 : MAXIMUM_ALLOWED_ACCESS,
2663 : alias_rid,
2664 : &alias_pol,
2665 : &result);
2666 0 : if (!NT_STATUS_IS_OK(status)) {
2667 0 : return status;
2668 : }
2669 :
2670 0 : if (!NT_STATUS_IS_OK(result)) {
2671 0 : return result;
2672 : }
2673 :
2674 0 : status = dcerpc_samr_DeleteAliasMember(b, mem_ctx,
2675 : &alias_pol,
2676 : &member_sid,
2677 : &result);
2678 :
2679 0 : if (!NT_STATUS_IS_OK(status)) {
2680 0 : return status;
2681 : }
2682 :
2683 0 : status = result;
2684 :
2685 0 : done:
2686 0 : dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2687 0 : return status;
2688 : }
2689 :
2690 0 : static NTSTATUS rpc_group_delmem_internals(struct net_context *c,
2691 : const struct dom_sid *domain_sid,
2692 : const char *domain_name,
2693 : struct cli_state *cli,
2694 : struct rpc_pipe_client *pipe_hnd,
2695 : TALLOC_CTX *mem_ctx,
2696 : int argc,
2697 : const char **argv)
2698 : {
2699 : struct dom_sid group_sid;
2700 : enum lsa_SidType group_type;
2701 :
2702 0 : if (argc != 2 || c->display_usage) {
2703 0 : d_printf("%s\n%s",
2704 : _("Usage:"),
2705 : _("net rpc group delmem <group> <member>\n"
2706 : " Delete a member from a group\n"
2707 : " group\tGroup to delete member from\n"
2708 : " member\tMember to delete from group\n"));
2709 0 : return NT_STATUS_UNSUCCESSFUL;
2710 : }
2711 :
2712 0 : if (!NT_STATUS_IS_OK(get_sid_from_name(cli, mem_ctx, argv[0],
2713 : &group_sid, &group_type))) {
2714 0 : d_fprintf(stderr, _("Could not lookup group name %s\n"),
2715 : argv[0]);
2716 0 : return NT_STATUS_UNSUCCESSFUL;
2717 : }
2718 :
2719 0 : if (group_type == SID_NAME_DOM_GRP) {
2720 0 : NTSTATUS result = rpc_del_groupmem(c, pipe_hnd, mem_ctx,
2721 0 : &group_sid, argv[1]);
2722 :
2723 0 : if (!NT_STATUS_IS_OK(result)) {
2724 0 : d_fprintf(stderr, _("Could not del %s from %s: %s\n"),
2725 0 : argv[1], argv[0], nt_errstr(result));
2726 : }
2727 0 : return result;
2728 : }
2729 :
2730 0 : if (group_type == SID_NAME_ALIAS) {
2731 0 : NTSTATUS result = rpc_del_aliasmem(pipe_hnd, cli, mem_ctx,
2732 0 : &group_sid, argv[1]);
2733 :
2734 0 : if (!NT_STATUS_IS_OK(result)) {
2735 0 : d_fprintf(stderr, _("Could not del %s from %s: %s\n"),
2736 0 : argv[1], argv[0], nt_errstr(result));
2737 : }
2738 0 : return result;
2739 : }
2740 :
2741 0 : d_fprintf(stderr, _("Can only delete members from global or local "
2742 : "groups which %s is not\n"), argv[0]);
2743 :
2744 0 : return NT_STATUS_UNSUCCESSFUL;
2745 : }
2746 :
2747 0 : static int rpc_group_delmem(struct net_context *c, int argc, const char **argv)
2748 : {
2749 0 : return run_rpc_command(c, NULL, &ndr_table_samr, 0,
2750 : rpc_group_delmem_internals,
2751 : argc, argv);
2752 : }
2753 :
2754 : /**
2755 : * List groups on a remote RPC server.
2756 : *
2757 : * All parameters are provided by the run_rpc_command function, except for
2758 : * argc, argv which are passes through.
2759 : *
2760 : * @param domain_sid The domain sid acquired from the remote server.
2761 : * @param cli A cli_state connected to the server.
2762 : * @param mem_ctx Talloc context, destroyed on completion of the function.
2763 : * @param argc Standard main() style argc.
2764 : * @param argv Standard main() style argv. Initial components are already
2765 : * stripped.
2766 : *
2767 : * @return Normal NTSTATUS return.
2768 : **/
2769 :
2770 0 : static NTSTATUS rpc_group_list_internals(struct net_context *c,
2771 : const struct dom_sid *domain_sid,
2772 : const char *domain_name,
2773 : struct cli_state *cli,
2774 : struct rpc_pipe_client *pipe_hnd,
2775 : TALLOC_CTX *mem_ctx,
2776 : int argc,
2777 : const char **argv)
2778 : {
2779 : struct policy_handle connect_pol, domain_pol;
2780 : NTSTATUS status, result;
2781 0 : uint32_t start_idx=0, max_entries=250, num_entries, i, loop_count = 0;
2782 0 : struct samr_SamArray *groups = NULL;
2783 0 : bool global = false;
2784 0 : bool local = false;
2785 0 : bool builtin = false;
2786 0 : struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
2787 :
2788 0 : if (c->display_usage) {
2789 0 : d_printf("%s\n%s",
2790 : _("Usage:"),
2791 : _("net rpc group list [global] [local] [builtin]\n"
2792 : " List groups on RPC server\n"
2793 : " global\tList global groups\n"
2794 : " local\tList local groups\n"
2795 : " builtin\tList builtin groups\n"
2796 : " If none of global, local or builtin is "
2797 : "specified, all three options are considered "
2798 : "set\n"));
2799 0 : return NT_STATUS_OK;
2800 : }
2801 :
2802 0 : if (argc == 0) {
2803 0 : global = true;
2804 0 : local = true;
2805 0 : builtin = true;
2806 : }
2807 :
2808 0 : for (i=0; i<argc; i++) {
2809 0 : if (strequal(argv[i], "global"))
2810 0 : global = true;
2811 :
2812 0 : if (strequal(argv[i], "local"))
2813 0 : local = true;
2814 :
2815 0 : if (strequal(argv[i], "builtin"))
2816 0 : builtin = true;
2817 : }
2818 :
2819 : /* Get sam policy handle */
2820 :
2821 0 : status = dcerpc_samr_Connect2(b, mem_ctx,
2822 0 : pipe_hnd->desthost,
2823 : MAXIMUM_ALLOWED_ACCESS,
2824 : &connect_pol,
2825 : &result);
2826 0 : if (!NT_STATUS_IS_OK(status)) {
2827 0 : goto done;
2828 : }
2829 0 : if (!NT_STATUS_IS_OK(result)) {
2830 0 : status = result;
2831 0 : goto done;
2832 : }
2833 :
2834 : /* Get domain policy handle */
2835 :
2836 0 : status = dcerpc_samr_OpenDomain(b, mem_ctx,
2837 : &connect_pol,
2838 : MAXIMUM_ALLOWED_ACCESS,
2839 : discard_const_p(struct dom_sid2, domain_sid),
2840 : &domain_pol,
2841 : &result);
2842 0 : if (!NT_STATUS_IS_OK(status)) {
2843 0 : goto done;
2844 : }
2845 0 : if (!NT_STATUS_IS_OK(result)) {
2846 0 : status = result;
2847 0 : goto done;
2848 : }
2849 :
2850 : /* Query domain groups */
2851 0 : if (c->opt_long_list_entries)
2852 0 : d_printf(_("\nGroup name Comment"
2853 : "\n-----------------------------\n"));
2854 : do {
2855 : uint32_t max_size, total_size, returned_size;
2856 : union samr_DispInfo info;
2857 :
2858 0 : if (!global) break;
2859 :
2860 0 : dcerpc_get_query_dispinfo_params(
2861 : loop_count, &max_entries, &max_size);
2862 :
2863 0 : status = dcerpc_samr_QueryDisplayInfo(b, mem_ctx,
2864 : &domain_pol,
2865 : 3,
2866 : start_idx,
2867 : max_entries,
2868 : max_size,
2869 : &total_size,
2870 : &returned_size,
2871 : &info,
2872 : &result);
2873 0 : if (!NT_STATUS_IS_OK(status)) {
2874 0 : goto done;
2875 : }
2876 0 : num_entries = info.info3.count;
2877 0 : start_idx += info.info3.count;
2878 :
2879 0 : if (!NT_STATUS_IS_OK(result) &&
2880 0 : !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
2881 0 : break;
2882 :
2883 0 : for (i = 0; i < num_entries; i++) {
2884 :
2885 0 : const char *group = NULL;
2886 0 : const char *desc = NULL;
2887 :
2888 0 : group = info.info3.entries[i].account_name.string;
2889 0 : desc = info.info3.entries[i].description.string;
2890 :
2891 0 : if (c->opt_long_list_entries)
2892 0 : printf("%-21.21s %-50.50s\n",
2893 : group, desc);
2894 : else
2895 0 : printf("%s\n", group);
2896 : }
2897 0 : } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
2898 : /* query domain aliases */
2899 0 : start_idx = 0;
2900 : do {
2901 0 : if (!local) break;
2902 :
2903 0 : status = dcerpc_samr_EnumDomainAliases(b, mem_ctx,
2904 : &domain_pol,
2905 : &start_idx,
2906 : &groups,
2907 : 0xffff,
2908 : &num_entries,
2909 : &result);
2910 0 : if (!NT_STATUS_IS_OK(status)) {
2911 0 : goto done;
2912 : }
2913 0 : if (!NT_STATUS_IS_OK(result) &&
2914 0 : !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
2915 0 : break;
2916 :
2917 0 : for (i = 0; i < num_entries; i++) {
2918 :
2919 0 : const char *description = NULL;
2920 :
2921 0 : if (c->opt_long_list_entries) {
2922 :
2923 : struct policy_handle alias_pol;
2924 0 : union samr_AliasInfo *info = NULL;
2925 : NTSTATUS _result;
2926 :
2927 0 : status = dcerpc_samr_OpenAlias(b, mem_ctx,
2928 : &domain_pol,
2929 : 0x8,
2930 0 : groups->entries[i].idx,
2931 : &alias_pol,
2932 : &_result);
2933 0 : if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(_result)) {
2934 0 : status = dcerpc_samr_QueryAliasInfo(b, mem_ctx,
2935 : &alias_pol,
2936 : 3,
2937 : &info,
2938 : &_result);
2939 0 : if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(_result)) {
2940 0 : status = dcerpc_samr_Close(b, mem_ctx,
2941 : &alias_pol,
2942 : &_result);
2943 0 : if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(_result)) {
2944 0 : description = info->description.string;
2945 : }
2946 : }
2947 : }
2948 : }
2949 :
2950 0 : if (description != NULL) {
2951 0 : printf("%-21.21s %-50.50s\n",
2952 0 : groups->entries[i].name.string,
2953 : description);
2954 : } else {
2955 0 : printf("%s\n", groups->entries[i].name.string);
2956 : }
2957 : }
2958 0 : } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
2959 0 : dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2960 : /* Get builtin policy handle */
2961 :
2962 0 : status = dcerpc_samr_OpenDomain(b, mem_ctx,
2963 : &connect_pol,
2964 : MAXIMUM_ALLOWED_ACCESS,
2965 : discard_const_p(struct dom_sid2, &global_sid_Builtin),
2966 : &domain_pol,
2967 : &result);
2968 0 : if (!NT_STATUS_IS_OK(status)) {
2969 0 : goto done;
2970 : }
2971 0 : if (!NT_STATUS_IS_OK(result)) {
2972 0 : status = result;
2973 0 : goto done;
2974 : }
2975 :
2976 : /* query builtin aliases */
2977 0 : start_idx = 0;
2978 : do {
2979 0 : if (!builtin) break;
2980 :
2981 0 : status = dcerpc_samr_EnumDomainAliases(b, mem_ctx,
2982 : &domain_pol,
2983 : &start_idx,
2984 : &groups,
2985 : max_entries,
2986 : &num_entries,
2987 : &result);
2988 0 : if (!NT_STATUS_IS_OK(status)) {
2989 0 : break;
2990 : }
2991 0 : if (!NT_STATUS_IS_OK(result) &&
2992 0 : !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
2993 0 : status = result;
2994 0 : break;
2995 : }
2996 :
2997 0 : for (i = 0; i < num_entries; i++) {
2998 :
2999 0 : const char *description = NULL;
3000 :
3001 0 : if (c->opt_long_list_entries) {
3002 :
3003 : struct policy_handle alias_pol;
3004 0 : union samr_AliasInfo *info = NULL;
3005 : NTSTATUS _result;
3006 :
3007 0 : status = dcerpc_samr_OpenAlias(b, mem_ctx,
3008 : &domain_pol,
3009 : 0x8,
3010 0 : groups->entries[i].idx,
3011 : &alias_pol,
3012 : &_result);
3013 0 : if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(_result)) {
3014 0 : status = dcerpc_samr_QueryAliasInfo(b, mem_ctx,
3015 : &alias_pol,
3016 : 3,
3017 : &info,
3018 : &_result);
3019 0 : if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(_result)) {
3020 0 : status = dcerpc_samr_Close(b, mem_ctx,
3021 : &alias_pol,
3022 : &_result);
3023 0 : if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(_result)) {
3024 0 : description = info->description.string;
3025 : }
3026 : }
3027 : }
3028 : }
3029 :
3030 0 : if (description != NULL) {
3031 0 : printf("%-21.21s %-50.50s\n",
3032 0 : groups->entries[i].name.string,
3033 : description);
3034 : } else {
3035 0 : printf("%s\n", groups->entries[i].name.string);
3036 : }
3037 : }
3038 0 : } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
3039 :
3040 0 : status = result;
3041 :
3042 0 : done:
3043 0 : return status;
3044 : }
3045 :
3046 0 : static int rpc_group_list(struct net_context *c, int argc, const char **argv)
3047 : {
3048 0 : return run_rpc_command(c, NULL, &ndr_table_samr, 0,
3049 : rpc_group_list_internals,
3050 : argc, argv);
3051 : }
3052 :
3053 0 : static NTSTATUS rpc_list_group_members(struct net_context *c,
3054 : struct rpc_pipe_client *pipe_hnd,
3055 : TALLOC_CTX *mem_ctx,
3056 : const char *domain_name,
3057 : const struct dom_sid *domain_sid,
3058 : struct policy_handle *domain_pol,
3059 : uint32_t rid)
3060 : {
3061 : NTSTATUS result, status;
3062 : struct policy_handle group_pol;
3063 : uint32_t num_members, *group_rids;
3064 : uint32_t i;
3065 0 : struct samr_RidAttrArray *rids = NULL;
3066 : struct lsa_Strings names;
3067 : struct samr_Ids types;
3068 0 : struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
3069 :
3070 0 : status = dcerpc_samr_OpenGroup(b, mem_ctx,
3071 : domain_pol,
3072 : MAXIMUM_ALLOWED_ACCESS,
3073 : rid,
3074 : &group_pol,
3075 : &result);
3076 0 : if (!NT_STATUS_IS_OK(status)) {
3077 0 : return status;
3078 : }
3079 0 : if (!NT_STATUS_IS_OK(result)) {
3080 0 : return result;
3081 : }
3082 :
3083 0 : status = dcerpc_samr_QueryGroupMember(b, mem_ctx,
3084 : &group_pol,
3085 : &rids,
3086 : &result);
3087 0 : if (!NT_STATUS_IS_OK(status)) {
3088 0 : return status;
3089 : }
3090 0 : if (!NT_STATUS_IS_OK(result)) {
3091 0 : return result;
3092 : }
3093 :
3094 0 : num_members = rids->count;
3095 0 : group_rids = rids->rids;
3096 :
3097 0 : while (num_members > 0) {
3098 0 : uint32_t this_time = 512;
3099 :
3100 0 : if (num_members < this_time)
3101 0 : this_time = num_members;
3102 :
3103 0 : status = dcerpc_samr_LookupRids(b, mem_ctx,
3104 : domain_pol,
3105 : this_time,
3106 : group_rids,
3107 : &names,
3108 : &types,
3109 : &result);
3110 0 : if (!NT_STATUS_IS_OK(status)) {
3111 0 : return status;
3112 : }
3113 0 : if (!NT_STATUS_IS_OK(result)) {
3114 0 : return result;
3115 : }
3116 0 : if (names.count != this_time) {
3117 0 : return NT_STATUS_INVALID_NETWORK_RESPONSE;
3118 : }
3119 0 : if (types.count != this_time) {
3120 0 : return NT_STATUS_INVALID_NETWORK_RESPONSE;
3121 : }
3122 : /* We only have users as members, but make the output
3123 : the same as the output of alias members */
3124 :
3125 0 : for (i = 0; i < this_time; i++) {
3126 :
3127 0 : if (c->opt_long_list_entries) {
3128 : struct dom_sid sid;
3129 : struct dom_sid_buf sid_str;
3130 :
3131 0 : sid_compose(&sid, domain_sid, group_rids[i]);
3132 :
3133 0 : printf("%s %s\\%s %d\n",
3134 : dom_sid_str_buf(&sid, &sid_str),
3135 : domain_name,
3136 0 : names.names[i].string,
3137 : SID_NAME_USER);
3138 : } else {
3139 0 : printf("%s\\%s\n", domain_name,
3140 0 : names.names[i].string);
3141 : }
3142 : }
3143 :
3144 0 : num_members -= this_time;
3145 0 : group_rids += 512;
3146 : }
3147 :
3148 0 : return NT_STATUS_OK;
3149 : }
3150 :
3151 0 : static NTSTATUS rpc_list_alias_members(struct net_context *c,
3152 : struct rpc_pipe_client *pipe_hnd,
3153 : struct cli_state *cli,
3154 : TALLOC_CTX *mem_ctx,
3155 : struct policy_handle *domain_pol,
3156 : uint32_t rid)
3157 : {
3158 : NTSTATUS result, status;
3159 : struct rpc_pipe_client *lsa_pipe;
3160 : struct policy_handle alias_pol, lsa_pol;
3161 : uint32_t num_members;
3162 : struct dom_sid *alias_sids;
3163 : char **domains;
3164 : char **names;
3165 : enum lsa_SidType *types;
3166 : uint32_t i;
3167 : struct lsa_SidArray sid_array;
3168 0 : struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
3169 :
3170 0 : status = dcerpc_samr_OpenAlias(b, mem_ctx,
3171 : domain_pol,
3172 : MAXIMUM_ALLOWED_ACCESS,
3173 : rid,
3174 : &alias_pol,
3175 : &result);
3176 0 : if (!NT_STATUS_IS_OK(status)) {
3177 0 : return status;
3178 : }
3179 0 : if (!NT_STATUS_IS_OK(result)) {
3180 0 : return result;
3181 : }
3182 :
3183 0 : status = dcerpc_samr_GetMembersInAlias(b, mem_ctx,
3184 : &alias_pol,
3185 : &sid_array,
3186 : &result);
3187 0 : if (!NT_STATUS_IS_OK(status)) {
3188 0 : d_fprintf(stderr, _("Couldn't list alias members\n"));
3189 0 : return status;
3190 : }
3191 0 : if (!NT_STATUS_IS_OK(result)) {
3192 0 : d_fprintf(stderr, _("Couldn't list alias members\n"));
3193 0 : return result;
3194 : }
3195 :
3196 0 : num_members = sid_array.num_sids;
3197 :
3198 0 : if (num_members == 0) {
3199 0 : return NT_STATUS_OK;
3200 : }
3201 :
3202 0 : result = cli_rpc_pipe_open_noauth(cli,
3203 : &ndr_table_lsarpc,
3204 : &lsa_pipe);
3205 0 : if (!NT_STATUS_IS_OK(result)) {
3206 0 : d_fprintf(stderr, _("Couldn't open LSA pipe. Error was %s\n"),
3207 : nt_errstr(result) );
3208 0 : return result;
3209 : }
3210 :
3211 0 : result = rpccli_lsa_open_policy(lsa_pipe, mem_ctx, true,
3212 : SEC_FLAG_MAXIMUM_ALLOWED, &lsa_pol);
3213 :
3214 0 : if (!NT_STATUS_IS_OK(result)) {
3215 0 : d_fprintf(stderr, _("Couldn't open LSA policy handle\n"));
3216 0 : TALLOC_FREE(lsa_pipe);
3217 0 : return result;
3218 : }
3219 :
3220 0 : alias_sids = talloc_zero_array(mem_ctx, struct dom_sid, num_members);
3221 0 : if (!alias_sids) {
3222 0 : d_fprintf(stderr, _("Out of memory\n"));
3223 0 : TALLOC_FREE(lsa_pipe);
3224 0 : return NT_STATUS_NO_MEMORY;
3225 : }
3226 :
3227 0 : for (i=0; i<num_members; i++) {
3228 0 : sid_copy(&alias_sids[i], sid_array.sids[i].sid);
3229 : }
3230 :
3231 0 : result = rpccli_lsa_lookup_sids(lsa_pipe, mem_ctx, &lsa_pol,
3232 : num_members, alias_sids,
3233 : &domains, &names, &types);
3234 :
3235 0 : if (!NT_STATUS_IS_OK(result) &&
3236 0 : !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
3237 0 : d_fprintf(stderr, _("Couldn't lookup SIDs\n"));
3238 0 : TALLOC_FREE(lsa_pipe);
3239 0 : return result;
3240 : }
3241 :
3242 0 : for (i = 0; i < num_members; i++) {
3243 : struct dom_sid_buf sid_str;
3244 0 : dom_sid_str_buf(&alias_sids[i], &sid_str);
3245 :
3246 0 : if (c->opt_long_list_entries) {
3247 0 : printf("%s %s\\%s %d\n", sid_str.buf,
3248 0 : domains[i] ? domains[i] : _("*unknown*"),
3249 0 : names[i] ? names[i] : _("*unknown*"), types[i]);
3250 : } else {
3251 0 : if (domains[i])
3252 0 : printf("%s\\%s\n", domains[i], names[i]);
3253 : else
3254 0 : printf("%s\n", sid_str.buf);
3255 : }
3256 : }
3257 :
3258 0 : TALLOC_FREE(lsa_pipe);
3259 0 : return NT_STATUS_OK;
3260 : }
3261 :
3262 0 : static NTSTATUS rpc_group_members_internals(struct net_context *c,
3263 : const struct dom_sid *domain_sid,
3264 : const char *domain_name,
3265 : struct cli_state *cli,
3266 : struct rpc_pipe_client *pipe_hnd,
3267 : TALLOC_CTX *mem_ctx,
3268 : int argc,
3269 : const char **argv)
3270 : {
3271 : NTSTATUS result, status;
3272 : struct policy_handle connect_pol, domain_pol;
3273 : struct samr_Ids rids, rid_types;
3274 : struct lsa_String lsa_acct_name;
3275 0 : struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
3276 :
3277 : /* Get sam policy handle */
3278 :
3279 0 : status = dcerpc_samr_Connect2(b, mem_ctx,
3280 0 : pipe_hnd->desthost,
3281 : MAXIMUM_ALLOWED_ACCESS,
3282 : &connect_pol,
3283 : &result);
3284 0 : if (!NT_STATUS_IS_OK(status)) {
3285 0 : return status;
3286 : }
3287 0 : if (!NT_STATUS_IS_OK(result)) {
3288 0 : return result;
3289 : }
3290 :
3291 : /* Get domain policy handle */
3292 :
3293 0 : status = dcerpc_samr_OpenDomain(b, mem_ctx,
3294 : &connect_pol,
3295 : MAXIMUM_ALLOWED_ACCESS,
3296 : discard_const_p(struct dom_sid2, domain_sid),
3297 : &domain_pol,
3298 : &result);
3299 0 : if (!NT_STATUS_IS_OK(status)) {
3300 0 : return status;
3301 : }
3302 0 : if (!NT_STATUS_IS_OK(result)) {
3303 0 : return result;
3304 : }
3305 :
3306 0 : init_lsa_String(&lsa_acct_name, argv[0]); /* sure? */
3307 :
3308 0 : status = dcerpc_samr_LookupNames(b, mem_ctx,
3309 : &domain_pol,
3310 : 1,
3311 : &lsa_acct_name,
3312 : &rids,
3313 : &rid_types,
3314 : &result);
3315 0 : if (!NT_STATUS_IS_OK(status)) {
3316 0 : return status;
3317 : }
3318 :
3319 0 : if (!NT_STATUS_IS_OK(result)) {
3320 :
3321 : /* Ok, did not find it in the global sam, try with builtin */
3322 :
3323 : struct dom_sid sid_Builtin;
3324 :
3325 0 : dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
3326 :
3327 0 : sid_copy(&sid_Builtin, &global_sid_Builtin);
3328 :
3329 0 : status = dcerpc_samr_OpenDomain(b, mem_ctx,
3330 : &connect_pol,
3331 : MAXIMUM_ALLOWED_ACCESS,
3332 : &sid_Builtin,
3333 : &domain_pol,
3334 : &result);
3335 0 : if (!NT_STATUS_IS_OK(status)) {
3336 0 : return status;
3337 : }
3338 0 : if (!NT_STATUS_IS_OK(result)) {
3339 0 : d_fprintf(stderr, _("Couldn't find group %s\n"),
3340 : argv[0]);
3341 0 : return result;
3342 : }
3343 :
3344 0 : status = dcerpc_samr_LookupNames(b, mem_ctx,
3345 : &domain_pol,
3346 : 1,
3347 : &lsa_acct_name,
3348 : &rids,
3349 : &rid_types,
3350 : &result);
3351 0 : if (!NT_STATUS_IS_OK(status)) {
3352 0 : return status;
3353 : }
3354 0 : if (!NT_STATUS_IS_OK(result)) {
3355 0 : d_fprintf(stderr, _("Couldn't find group %s\n"),
3356 : argv[0]);
3357 0 : return result;
3358 : }
3359 : }
3360 :
3361 0 : if (rids.count != 1) {
3362 0 : d_fprintf(stderr, _("Couldn't find group %s\n"),
3363 : argv[0]);
3364 0 : return NT_STATUS_INVALID_NETWORK_RESPONSE;
3365 : }
3366 0 : if (rid_types.count != 1) {
3367 0 : d_fprintf(stderr, _("Couldn't find group %s\n"),
3368 : argv[0]);
3369 0 : return NT_STATUS_INVALID_NETWORK_RESPONSE;
3370 : }
3371 :
3372 :
3373 0 : if (rid_types.ids[0] == SID_NAME_DOM_GRP) {
3374 0 : return rpc_list_group_members(c, pipe_hnd, mem_ctx, domain_name,
3375 : domain_sid, &domain_pol,
3376 0 : rids.ids[0]);
3377 : }
3378 :
3379 0 : if (rid_types.ids[0] == SID_NAME_ALIAS) {
3380 0 : return rpc_list_alias_members(c, pipe_hnd, cli, mem_ctx, &domain_pol,
3381 0 : rids.ids[0]);
3382 : }
3383 :
3384 0 : return NT_STATUS_NO_SUCH_GROUP;
3385 : }
3386 :
3387 0 : static int rpc_group_members(struct net_context *c, int argc, const char **argv)
3388 : {
3389 0 : if (argc != 1 || c->display_usage) {
3390 0 : return rpc_group_usage(c, argc, argv);
3391 : }
3392 :
3393 0 : return run_rpc_command(c, NULL, &ndr_table_samr, 0,
3394 : rpc_group_members_internals,
3395 : argc, argv);
3396 : }
3397 :
3398 0 : static int rpc_group_rename_internals(struct net_context *c, int argc, const char **argv)
3399 : {
3400 : NET_API_STATUS status;
3401 : struct GROUP_INFO_0 g0;
3402 : uint32_t parm_err;
3403 :
3404 0 : if (argc != 2) {
3405 0 : d_printf(_("Usage:\n"));
3406 0 : d_printf("net rpc group rename group newname\n");
3407 0 : return -1;
3408 : }
3409 :
3410 0 : g0.grpi0_name = argv[1];
3411 :
3412 0 : status = NetGroupSetInfo(c->opt_host,
3413 : argv[0],
3414 : 0,
3415 : (uint8_t *)&g0,
3416 : &parm_err);
3417 :
3418 0 : if (status != 0) {
3419 0 : d_fprintf(stderr, _("Renaming group %s failed with: %s\n"),
3420 : argv[0], libnetapi_get_error_string(c->netapi_ctx,
3421 : status));
3422 0 : return -1;
3423 : }
3424 :
3425 0 : return 0;
3426 : }
3427 :
3428 0 : static int rpc_group_rename(struct net_context *c, int argc, const char **argv)
3429 : {
3430 0 : if (argc != 2 || c->display_usage) {
3431 0 : return rpc_group_usage(c, argc, argv);
3432 : }
3433 :
3434 0 : return rpc_group_rename_internals(c, argc, argv);
3435 : }
3436 :
3437 : /**
3438 : * 'net rpc group' entrypoint.
3439 : * @param argc Standard main() style argc.
3440 : * @param argv Standard main() style argv. Initial components are already
3441 : * stripped.
3442 : **/
3443 :
3444 210 : int net_rpc_group(struct net_context *c, int argc, const char **argv)
3445 : {
3446 : NET_API_STATUS status;
3447 :
3448 210 : struct functable func[] = {
3449 : {
3450 : "add",
3451 : rpc_group_add,
3452 : NET_TRANSPORT_RPC,
3453 : N_("Create specified group"),
3454 : N_("net rpc group add\n"
3455 : " Create specified group")
3456 : },
3457 : {
3458 : "delete",
3459 : rpc_group_delete,
3460 : NET_TRANSPORT_RPC,
3461 : N_("Delete specified group"),
3462 : N_("net rpc group delete\n"
3463 : " Delete specified group")
3464 : },
3465 : {
3466 : "addmem",
3467 : rpc_group_addmem,
3468 : NET_TRANSPORT_RPC,
3469 : N_("Add member to group"),
3470 : N_("net rpc group addmem\n"
3471 : " Add member to group")
3472 : },
3473 : {
3474 : "delmem",
3475 : rpc_group_delmem,
3476 : NET_TRANSPORT_RPC,
3477 : N_("Remove member from group"),
3478 : N_("net rpc group delmem\n"
3479 : " Remove member from group")
3480 : },
3481 : {
3482 : "list",
3483 : rpc_group_list,
3484 : NET_TRANSPORT_RPC,
3485 : N_("List groups"),
3486 : N_("net rpc group list\n"
3487 : " List groups")
3488 : },
3489 : {
3490 : "members",
3491 : rpc_group_members,
3492 : NET_TRANSPORT_RPC,
3493 : N_("List group members"),
3494 : N_("net rpc group members\n"
3495 : " List group members")
3496 : },
3497 : {
3498 : "rename",
3499 : rpc_group_rename,
3500 : NET_TRANSPORT_RPC,
3501 : N_("Rename group"),
3502 : N_("net rpc group rename\n"
3503 : " Rename group")
3504 : },
3505 : {NULL, NULL, 0, NULL, NULL}
3506 : };
3507 :
3508 210 : status = libnetapi_net_init(&c->netapi_ctx);
3509 210 : if (status != 0) {
3510 0 : return -1;
3511 : }
3512 :
3513 210 : status = libnetapi_set_creds(c->netapi_ctx, c->creds);
3514 210 : if (status != 0) {
3515 0 : return -1;
3516 : }
3517 :
3518 210 : if (argc == 0) {
3519 0 : if (c->display_usage) {
3520 0 : d_printf(_("Usage:\n"));
3521 0 : d_printf(_("net rpc group\n"
3522 : " Alias for net rpc group list global "
3523 : "local builtin\n"));
3524 0 : net_display_usage_from_functable(func);
3525 0 : return 0;
3526 : }
3527 :
3528 0 : return run_rpc_command(c, NULL, &ndr_table_samr, 0,
3529 : rpc_group_list_internals,
3530 : argc, argv);
3531 : }
3532 :
3533 210 : return net_run_function(c, argc, argv, "net rpc group", func);
3534 : }
3535 :
3536 : /****************************************************************************/
3537 :
3538 0 : static int rpc_share_usage(struct net_context *c, int argc, const char **argv)
3539 : {
3540 0 : return net_share_usage(c, argc, argv);
3541 : }
3542 :
3543 : /**
3544 : * Add a share on a remote RPC server.
3545 : *
3546 : * @param argc Standard main() style argc.
3547 : * @param argv Standard main() style argv. Initial components are already
3548 : * stripped.
3549 : *
3550 : * @return A shell status integer (0 for success).
3551 : **/
3552 :
3553 0 : static int rpc_share_add(struct net_context *c, int argc, const char **argv)
3554 : {
3555 : NET_API_STATUS status;
3556 : char *sharename;
3557 : char *path;
3558 0 : uint32_t type = STYPE_DISKTREE; /* only allow disk shares to be added */
3559 0 : uint32_t num_users=0, perms=0;
3560 0 : char *password=NULL; /* don't allow a share password */
3561 : struct SHARE_INFO_2 i2;
3562 0 : uint32_t parm_error = 0;
3563 :
3564 0 : if ((argc < 1) || !strchr(argv[0], '=') || c->display_usage) {
3565 0 : return rpc_share_usage(c, argc, argv);
3566 : }
3567 :
3568 0 : if ((sharename = talloc_strdup(c, argv[0])) == NULL) {
3569 0 : return -1;
3570 : }
3571 :
3572 0 : path = strchr(sharename, '=');
3573 0 : if (!path) {
3574 0 : return -1;
3575 : }
3576 :
3577 0 : *path++ = '\0';
3578 :
3579 0 : i2.shi2_netname = sharename;
3580 0 : i2.shi2_type = type;
3581 0 : i2.shi2_remark = c->opt_comment;
3582 0 : i2.shi2_permissions = perms;
3583 0 : i2.shi2_max_uses = c->opt_maxusers;
3584 0 : i2.shi2_current_uses = num_users;
3585 0 : i2.shi2_path = path;
3586 0 : i2.shi2_passwd = password;
3587 :
3588 0 : status = NetShareAdd(c->opt_host,
3589 : 2,
3590 : (uint8_t *)&i2,
3591 : &parm_error);
3592 0 : if (status != 0) {
3593 0 : printf(_("NetShareAdd failed with: %s\n"),
3594 : libnetapi_get_error_string(c->netapi_ctx, status));
3595 : }
3596 :
3597 0 : return status;
3598 : }
3599 :
3600 : /**
3601 : * Delete a share on a remote RPC server.
3602 : *
3603 : * @param domain_sid The domain sid acquired from the remote server.
3604 : * @param argc Standard main() style argc.
3605 : * @param argv Standard main() style argv. Initial components are already
3606 : * stripped.
3607 : *
3608 : * @return A shell status integer (0 for success).
3609 : **/
3610 0 : static int rpc_share_delete(struct net_context *c, int argc, const char **argv)
3611 : {
3612 0 : if (argc < 1 || c->display_usage) {
3613 0 : return rpc_share_usage(c, argc, argv);
3614 : }
3615 :
3616 0 : return NetShareDel(c->opt_host, argv[0], 0);
3617 : }
3618 :
3619 : /**
3620 : * Formatted print of share info
3621 : *
3622 : * @param r pointer to SHARE_INFO_1 to format
3623 : **/
3624 :
3625 0 : static void display_share_info_1(struct net_context *c,
3626 : struct SHARE_INFO_1 *r)
3627 : {
3628 0 : if (c->opt_long_list_entries) {
3629 0 : d_printf("%-12s %-8.8s %-50s\n",
3630 : r->shi1_netname,
3631 0 : net_share_type_str(r->shi1_type & ~(STYPE_TEMPORARY|STYPE_HIDDEN)),
3632 : r->shi1_remark);
3633 : } else {
3634 0 : d_printf("%s\n", r->shi1_netname);
3635 : }
3636 0 : }
3637 :
3638 0 : static WERROR get_share_info(struct net_context *c,
3639 : struct rpc_pipe_client *pipe_hnd,
3640 : TALLOC_CTX *mem_ctx,
3641 : uint32_t level,
3642 : int argc,
3643 : const char **argv,
3644 : struct srvsvc_NetShareInfoCtr *info_ctr)
3645 : {
3646 : WERROR result;
3647 : NTSTATUS status;
3648 : union srvsvc_NetShareInfo info;
3649 0 : struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
3650 :
3651 : /* no specific share requested, enumerate all */
3652 0 : if (argc == 0) {
3653 :
3654 0 : uint32_t preferred_len = 0xffffffff;
3655 0 : uint32_t total_entries = 0;
3656 0 : uint32_t resume_handle = 0;
3657 :
3658 0 : info_ctr->level = level;
3659 :
3660 0 : status = dcerpc_srvsvc_NetShareEnumAll(b, mem_ctx,
3661 0 : pipe_hnd->desthost,
3662 : info_ctr,
3663 : preferred_len,
3664 : &total_entries,
3665 : &resume_handle,
3666 : &result);
3667 0 : if (!NT_STATUS_IS_OK(status)) {
3668 0 : return ntstatus_to_werror(status);
3669 : }
3670 0 : return result;
3671 : }
3672 :
3673 : /* request just one share */
3674 0 : status = dcerpc_srvsvc_NetShareGetInfo(b, mem_ctx,
3675 0 : pipe_hnd->desthost,
3676 : argv[0],
3677 : level,
3678 : &info,
3679 : &result);
3680 :
3681 0 : if (!NT_STATUS_IS_OK(status)) {
3682 0 : result = ntstatus_to_werror(status);
3683 0 : goto done;
3684 : }
3685 :
3686 0 : if (!W_ERROR_IS_OK(result)) {
3687 0 : goto done;
3688 : }
3689 :
3690 : /* construct ctr */
3691 0 : ZERO_STRUCTP(info_ctr);
3692 :
3693 0 : info_ctr->level = level;
3694 :
3695 0 : switch (level) {
3696 0 : case 1:
3697 : {
3698 : struct srvsvc_NetShareCtr1 *ctr1;
3699 :
3700 0 : ctr1 = talloc_zero(mem_ctx, struct srvsvc_NetShareCtr1);
3701 0 : W_ERROR_HAVE_NO_MEMORY(ctr1);
3702 :
3703 0 : ctr1->count = 1;
3704 0 : ctr1->array = info.info1;
3705 :
3706 0 : info_ctr->ctr.ctr1 = ctr1;
3707 :
3708 0 : break;
3709 : }
3710 0 : case 2:
3711 : {
3712 : struct srvsvc_NetShareCtr2 *ctr2;
3713 :
3714 0 : ctr2 = talloc_zero(mem_ctx, struct srvsvc_NetShareCtr2);
3715 0 : W_ERROR_HAVE_NO_MEMORY(ctr2);
3716 :
3717 0 : ctr2->count = 1;
3718 0 : ctr2->array = info.info2;
3719 :
3720 0 : info_ctr->ctr.ctr2 = ctr2;
3721 :
3722 0 : break;
3723 : }
3724 0 : case 502:
3725 : {
3726 : struct srvsvc_NetShareCtr502 *ctr502;
3727 :
3728 0 : ctr502 = talloc_zero(mem_ctx, struct srvsvc_NetShareCtr502);
3729 0 : W_ERROR_HAVE_NO_MEMORY(ctr502);
3730 :
3731 0 : ctr502->count = 1;
3732 0 : ctr502->array = info.info502;
3733 :
3734 0 : info_ctr->ctr.ctr502 = ctr502;
3735 :
3736 0 : break;
3737 : }
3738 : } /* switch */
3739 0 : done:
3740 0 : return result;
3741 : }
3742 :
3743 : /***
3744 : * 'net rpc share list' entrypoint.
3745 : * @param argc Standard main() style argc.
3746 : * @param argv Standard main() style argv. Initial components are already
3747 : * stripped.
3748 : **/
3749 0 : static int rpc_share_list(struct net_context *c, int argc, const char **argv)
3750 : {
3751 : NET_API_STATUS status;
3752 0 : struct SHARE_INFO_1 *i1 = NULL;
3753 0 : uint32_t entries_read = 0;
3754 0 : uint32_t total_entries = 0;
3755 0 : uint32_t resume_handle = 0;
3756 0 : uint32_t i, level = 1;
3757 :
3758 0 : if (c->display_usage) {
3759 0 : d_printf( "%s\n"
3760 : "net rpc share list\n"
3761 : " %s\n",
3762 : _("Usage:"),
3763 : _("List shares on remote server"));
3764 0 : return 0;
3765 : }
3766 :
3767 0 : status = NetShareEnum(c->opt_host,
3768 : level,
3769 : (uint8_t **)(void *)&i1,
3770 : (uint32_t)-1,
3771 : &entries_read,
3772 : &total_entries,
3773 : &resume_handle);
3774 0 : if (status != 0) {
3775 0 : goto done;
3776 : }
3777 :
3778 : /* Display results */
3779 :
3780 0 : if (c->opt_long_list_entries) {
3781 0 : d_printf(_(
3782 : "\nEnumerating shared resources (exports) on remote server:\n\n"
3783 : "\nShare name Type Description\n"
3784 : "---------- ---- -----------\n"));
3785 : }
3786 0 : for (i = 0; i < entries_read; i++)
3787 0 : display_share_info_1(c, &i1[i]);
3788 0 : done:
3789 0 : return status;
3790 : }
3791 :
3792 0 : static bool check_share_availability(struct cli_state *cli, const char *netname)
3793 : {
3794 : NTSTATUS status;
3795 :
3796 0 : status = cli_tree_connect(cli, netname, "A:", NULL);
3797 0 : if (!NT_STATUS_IS_OK(status)) {
3798 0 : d_printf(_("skipping [%s]: not a file share.\n"), netname);
3799 0 : return false;
3800 : }
3801 :
3802 0 : status = cli_tdis(cli);
3803 0 : if (!NT_STATUS_IS_OK(status)) {
3804 0 : d_printf(_("cli_tdis returned %s\n"), nt_errstr(status));
3805 0 : return false;
3806 : }
3807 :
3808 0 : return true;
3809 : }
3810 :
3811 0 : static bool check_share_sanity(struct net_context *c, struct cli_state *cli,
3812 : const char *netname, uint32_t type)
3813 : {
3814 : /* only support disk shares */
3815 0 : if (! ( type == STYPE_DISKTREE || type == (STYPE_DISKTREE | STYPE_HIDDEN)) ) {
3816 0 : printf(_("share [%s] is not a diskshare (type: %x)\n"), netname,
3817 : type);
3818 0 : return false;
3819 : }
3820 :
3821 : /* skip builtin shares */
3822 : /* FIXME: should print$ be added too ? */
3823 0 : if (strequal(netname,"IPC$") || strequal(netname,"ADMIN$") ||
3824 0 : strequal(netname,"global"))
3825 0 : return false;
3826 :
3827 0 : if (c->opt_exclude && in_list(netname, c->opt_exclude, false)) {
3828 0 : printf(_("excluding [%s]\n"), netname);
3829 0 : return false;
3830 : }
3831 :
3832 0 : return check_share_availability(cli, netname);
3833 : }
3834 :
3835 : /**
3836 : * Migrate shares from a remote RPC server to the local RPC server.
3837 : *
3838 : * All parameters are provided by the run_rpc_command function, except for
3839 : * argc, argv which are passed through.
3840 : *
3841 : * @param domain_sid The domain sid acquired from the remote server.
3842 : * @param cli A cli_state connected to the server.
3843 : * @param mem_ctx Talloc context, destroyed on completion of the function.
3844 : * @param argc Standard main() style argc.
3845 : * @param argv Standard main() style argv. Initial components are already
3846 : * stripped.
3847 : *
3848 : * @return Normal NTSTATUS return.
3849 : **/
3850 :
3851 0 : static NTSTATUS rpc_share_migrate_shares_internals(struct net_context *c,
3852 : const struct dom_sid *domain_sid,
3853 : const char *domain_name,
3854 : struct cli_state *cli,
3855 : struct rpc_pipe_client *pipe_hnd,
3856 : TALLOC_CTX *mem_ctx,
3857 : int argc,
3858 : const char **argv)
3859 : {
3860 : WERROR result;
3861 0 : NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
3862 : struct srvsvc_NetShareInfoCtr ctr_src;
3863 : uint32_t i;
3864 0 : struct rpc_pipe_client *srvsvc_pipe = NULL;
3865 0 : struct cli_state *cli_dst = NULL;
3866 0 : uint32_t level = 502; /* includes secdesc */
3867 0 : uint32_t parm_error = 0;
3868 : struct dcerpc_binding_handle *b;
3869 :
3870 0 : result = get_share_info(c, pipe_hnd, mem_ctx, level, argc, argv,
3871 : &ctr_src);
3872 0 : if (!W_ERROR_IS_OK(result))
3873 0 : goto done;
3874 :
3875 : /* connect destination PI_SRVSVC */
3876 0 : nt_status = connect_dst_pipe(c, &cli_dst, &srvsvc_pipe,
3877 : &ndr_table_srvsvc);
3878 0 : if (!NT_STATUS_IS_OK(nt_status))
3879 0 : return nt_status;
3880 :
3881 0 : b = srvsvc_pipe->binding_handle;
3882 :
3883 0 : for (i = 0; i < ctr_src.ctr.ctr502->count; i++) {
3884 :
3885 : union srvsvc_NetShareInfo info;
3886 0 : struct srvsvc_NetShareInfo502 info502 =
3887 0 : ctr_src.ctr.ctr502->array[i];
3888 :
3889 : /* reset error-code */
3890 0 : nt_status = NT_STATUS_UNSUCCESSFUL;
3891 :
3892 0 : if (!check_share_sanity(c, cli, info502.name, info502.type))
3893 0 : continue;
3894 :
3895 : /* finally add the share on the dst server */
3896 :
3897 0 : printf(_("migrating: [%s], path: %s, comment: %s, without "
3898 : "share-ACLs\n"),
3899 : info502.name, info502.path, info502.comment);
3900 :
3901 0 : info.info502 = &info502;
3902 :
3903 0 : nt_status = dcerpc_srvsvc_NetShareAdd(b, mem_ctx,
3904 0 : srvsvc_pipe->desthost,
3905 : 502,
3906 : &info,
3907 : &parm_error,
3908 : &result);
3909 0 : if (!NT_STATUS_IS_OK(nt_status)) {
3910 0 : printf(_("cannot add share: %s\n"),
3911 : nt_errstr(nt_status));
3912 0 : goto done;
3913 : }
3914 0 : if (W_ERROR_V(result) == W_ERROR_V(WERR_FILE_EXISTS)) {
3915 0 : printf(_(" [%s] does already exist\n"),
3916 : info502.name);
3917 0 : continue;
3918 : }
3919 :
3920 0 : if (!W_ERROR_IS_OK(result)) {
3921 0 : nt_status = werror_to_ntstatus(result);
3922 0 : printf(_("cannot add share: %s\n"),
3923 : win_errstr(result));
3924 0 : goto done;
3925 : }
3926 :
3927 : }
3928 :
3929 0 : nt_status = NT_STATUS_OK;
3930 :
3931 0 : done:
3932 0 : if (cli_dst) {
3933 0 : cli_shutdown(cli_dst);
3934 : }
3935 :
3936 0 : return nt_status;
3937 :
3938 : }
3939 :
3940 : /**
3941 : * Migrate shares from a RPC server to another.
3942 : *
3943 : * @param argc Standard main() style argc.
3944 : * @param argv Standard main() style argv. Initial components are already
3945 : * stripped.
3946 : *
3947 : * @return A shell status integer (0 for success).
3948 : **/
3949 0 : static int rpc_share_migrate_shares(struct net_context *c, int argc,
3950 : const char **argv)
3951 : {
3952 0 : if (c->display_usage) {
3953 0 : d_printf( "%s\n"
3954 : "net rpc share migrate shares\n"
3955 : " %s\n",
3956 : _("Usage:"),
3957 : _("Migrate shares to local server"));
3958 0 : return 0;
3959 : }
3960 :
3961 0 : if (!c->opt_host) {
3962 0 : printf(_("no server to migrate\n"));
3963 0 : return -1;
3964 : }
3965 :
3966 0 : return run_rpc_command(c, NULL, &ndr_table_srvsvc, 0,
3967 : rpc_share_migrate_shares_internals,
3968 : argc, argv);
3969 : }
3970 :
3971 : /**
3972 : * Copy a file/dir
3973 : *
3974 : * @param f file_info
3975 : * @param mask current search mask
3976 : * @param state arg-pointer
3977 : *
3978 : **/
3979 0 : static NTSTATUS copy_fn(struct file_info *f,
3980 : const char *mask, void *state)
3981 : {
3982 : static NTSTATUS nt_status;
3983 : static struct copy_clistate *local_state;
3984 : static fstring filename, new_mask;
3985 : fstring dir;
3986 : char *old_dir;
3987 : struct net_context *c;
3988 :
3989 0 : local_state = (struct copy_clistate *)state;
3990 0 : nt_status = NT_STATUS_UNSUCCESSFUL;
3991 :
3992 0 : c = local_state->c;
3993 :
3994 0 : if (strequal(f->name, ".") || strequal(f->name, ".."))
3995 0 : return NT_STATUS_OK;
3996 :
3997 0 : DEBUG(3,("got mask: %s, name: %s\n", mask, f->name));
3998 :
3999 : /* DIRECTORY */
4000 0 : if (f->attr & FILE_ATTRIBUTE_DIRECTORY) {
4001 :
4002 0 : DEBUG(3,("got dir: %s\n", f->name));
4003 :
4004 0 : fstrcpy(dir, local_state->cwd);
4005 0 : fstrcat(dir, "\\");
4006 0 : fstrcat(dir, f->name);
4007 :
4008 0 : switch (net_mode_share)
4009 : {
4010 0 : case NET_MODE_SHARE_MIGRATE:
4011 : /* create that directory */
4012 0 : nt_status = net_copy_file(c, local_state->mem_ctx,
4013 0 : local_state->cli_share_src,
4014 0 : local_state->cli_share_dst,
4015 : dir, dir,
4016 0 : c->opt_acls? true : false,
4017 0 : c->opt_attrs? true : false,
4018 0 : c->opt_timestamps? true:false,
4019 : false);
4020 0 : break;
4021 0 : default:
4022 0 : d_fprintf(stderr, _("Unsupported mode %d\n"), net_mode_share);
4023 0 : return NT_STATUS_INTERNAL_ERROR;
4024 : }
4025 :
4026 0 : if (!NT_STATUS_IS_OK(nt_status)) {
4027 0 : printf(_("could not handle dir %s: %s\n"),
4028 : dir, nt_errstr(nt_status));
4029 0 : return nt_status;
4030 : }
4031 :
4032 : /* search below that directory */
4033 0 : if (strlcpy(new_mask, dir, sizeof(new_mask)) >= sizeof(new_mask)) {
4034 0 : return NT_STATUS_NO_MEMORY;
4035 : }
4036 0 : if (strlcat(new_mask, "\\*", sizeof(new_mask)) >= sizeof(new_mask)) {
4037 0 : return NT_STATUS_NO_MEMORY;
4038 : }
4039 :
4040 0 : old_dir = local_state->cwd;
4041 0 : local_state->cwd = dir;
4042 0 : nt_status = sync_files(local_state, new_mask);
4043 0 : if (!NT_STATUS_IS_OK(nt_status)) {
4044 0 : printf(_("could not handle files\n"));
4045 : }
4046 0 : local_state->cwd = old_dir;
4047 :
4048 0 : return nt_status;
4049 : }
4050 :
4051 :
4052 : /* FILE */
4053 0 : fstrcpy(filename, local_state->cwd);
4054 0 : fstrcat(filename, "\\");
4055 0 : fstrcat(filename, f->name);
4056 :
4057 0 : DEBUG(3,("got file: %s\n", filename));
4058 :
4059 0 : switch (net_mode_share)
4060 : {
4061 0 : case NET_MODE_SHARE_MIGRATE:
4062 0 : nt_status = net_copy_file(c, local_state->mem_ctx,
4063 0 : local_state->cli_share_src,
4064 0 : local_state->cli_share_dst,
4065 : filename, filename,
4066 0 : c->opt_acls? true : false,
4067 0 : c->opt_attrs? true : false,
4068 0 : c->opt_timestamps? true: false,
4069 : true);
4070 0 : break;
4071 0 : default:
4072 0 : d_fprintf(stderr, _("Unsupported file mode %d\n"),
4073 : net_mode_share);
4074 0 : return NT_STATUS_INTERNAL_ERROR;
4075 : }
4076 :
4077 0 : if (!NT_STATUS_IS_OK(nt_status))
4078 0 : printf(_("could not handle file %s: %s\n"),
4079 : filename, nt_errstr(nt_status));
4080 0 : return nt_status;
4081 : }
4082 :
4083 : /**
4084 : * sync files, can be called recursively to list files
4085 : * and then call copy_fn for each file
4086 : *
4087 : * @param cp_clistate pointer to the copy_clistate we work with
4088 : * @param mask the current search mask
4089 : *
4090 : * @return Boolean result
4091 : **/
4092 0 : static NTSTATUS sync_files(struct copy_clistate *cp_clistate, const char *mask)
4093 : {
4094 : struct cli_state *targetcli;
4095 0 : char *targetpath = NULL;
4096 : NTSTATUS status;
4097 :
4098 0 : DEBUG(3,("calling cli_list with mask: %s\n", mask));
4099 :
4100 0 : status = cli_resolve_path(talloc_tos(), "", NULL,
4101 : cp_clistate->cli_share_src,
4102 : mask, &targetcli, &targetpath);
4103 0 : if (!NT_STATUS_IS_OK(status)) {
4104 0 : d_fprintf(stderr, _("cli_resolve_path %s failed with error: "
4105 : "%s\n"),
4106 : mask, nt_errstr(status));
4107 0 : return status;
4108 : }
4109 :
4110 0 : status = cli_list(targetcli, targetpath, cp_clistate->attribute,
4111 : copy_fn, cp_clistate);
4112 0 : if (!NT_STATUS_IS_OK(status)) {
4113 0 : d_fprintf(stderr, _("listing %s failed with error: %s\n"),
4114 : mask, nt_errstr(status));
4115 : }
4116 :
4117 0 : return status;
4118 : }
4119 :
4120 :
4121 : /**
4122 : * Set the top level directory permissions before we do any further copies.
4123 : * Should set up ACL inheritance.
4124 : **/
4125 :
4126 0 : bool copy_top_level_perms(struct net_context *c,
4127 : struct copy_clistate *cp_clistate,
4128 : const char *sharename)
4129 : {
4130 0 : NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
4131 :
4132 0 : switch (net_mode_share) {
4133 0 : case NET_MODE_SHARE_MIGRATE:
4134 0 : DEBUG(3,("calling net_copy_fileattr for '.' directory in share %s\n", sharename));
4135 0 : nt_status = net_copy_fileattr(c,
4136 : cp_clistate->mem_ctx,
4137 : cp_clistate->cli_share_src,
4138 : cp_clistate->cli_share_dst,
4139 : "\\", "\\",
4140 0 : c->opt_acls? true : false,
4141 0 : c->opt_attrs? true : false,
4142 0 : c->opt_timestamps? true: false,
4143 : false);
4144 0 : break;
4145 0 : default:
4146 0 : d_fprintf(stderr, _("Unsupported mode %d\n"), net_mode_share);
4147 0 : break;
4148 : }
4149 :
4150 0 : if (!NT_STATUS_IS_OK(nt_status)) {
4151 0 : printf(_("Could handle directory attributes for top level "
4152 : "directory of share %s. Error %s\n"),
4153 : sharename, nt_errstr(nt_status));
4154 0 : return false;
4155 : }
4156 :
4157 0 : return true;
4158 : }
4159 :
4160 : /**
4161 : * Sync all files inside a remote share to another share (over smb).
4162 : *
4163 : * All parameters are provided by the run_rpc_command function, except for
4164 : * argc, argv which are passed through.
4165 : *
4166 : * @param domain_sid The domain sid acquired from the remote server.
4167 : * @param cli A cli_state connected to the server.
4168 : * @param mem_ctx Talloc context, destroyed on completion of the function.
4169 : * @param argc Standard main() style argc.
4170 : * @param argv Standard main() style argv. Initial components are already
4171 : * stripped.
4172 : *
4173 : * @return Normal NTSTATUS return.
4174 : **/
4175 :
4176 0 : static NTSTATUS rpc_share_migrate_files_internals(struct net_context *c,
4177 : const struct dom_sid *domain_sid,
4178 : const char *domain_name,
4179 : struct cli_state *cli,
4180 : struct rpc_pipe_client *pipe_hnd,
4181 : TALLOC_CTX *mem_ctx,
4182 : int argc,
4183 : const char **argv)
4184 : {
4185 : WERROR result;
4186 0 : NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
4187 : struct srvsvc_NetShareInfoCtr ctr_src;
4188 : uint32_t i;
4189 0 : uint32_t level = 502;
4190 : struct copy_clistate cp_clistate;
4191 0 : bool got_src_share = false;
4192 0 : bool got_dst_share = false;
4193 0 : const char *mask = "\\*";
4194 0 : char *dst = NULL;
4195 :
4196 0 : dst = SMB_STRDUP(c->opt_destination?c->opt_destination:"127.0.0.1");
4197 0 : if (dst == NULL) {
4198 0 : nt_status = NT_STATUS_NO_MEMORY;
4199 0 : goto done;
4200 : }
4201 :
4202 0 : result = get_share_info(c, pipe_hnd, mem_ctx, level, argc, argv,
4203 : &ctr_src);
4204 :
4205 0 : if (!W_ERROR_IS_OK(result))
4206 0 : goto done;
4207 :
4208 0 : for (i = 0; i < ctr_src.ctr.ctr502->count; i++) {
4209 :
4210 0 : struct srvsvc_NetShareInfo502 info502 =
4211 0 : ctr_src.ctr.ctr502->array[i];
4212 :
4213 0 : if (!check_share_sanity(c, cli, info502.name, info502.type))
4214 0 : continue;
4215 :
4216 : /* one might not want to mirror whole discs :) */
4217 0 : if (strequal(info502.name, "print$") || info502.name[1] == '$') {
4218 0 : d_printf(_("skipping [%s]: builtin/hidden share\n"),
4219 : info502.name);
4220 0 : continue;
4221 : }
4222 :
4223 0 : switch (net_mode_share)
4224 : {
4225 0 : case NET_MODE_SHARE_MIGRATE:
4226 0 : printf("syncing");
4227 0 : break;
4228 0 : default:
4229 0 : d_fprintf(stderr, _("Unsupported mode %d\n"),
4230 : net_mode_share);
4231 0 : break;
4232 : }
4233 0 : printf(_(" [%s] files and directories %s ACLs, %s DOS "
4234 : "Attributes %s\n"),
4235 : info502.name,
4236 0 : c->opt_acls ? _("including") : _("without"),
4237 0 : c->opt_attrs ? _("including") : _("without"),
4238 0 : c->opt_timestamps ? _("(preserving timestamps)") : "");
4239 :
4240 0 : cp_clistate.mem_ctx = mem_ctx;
4241 0 : cp_clistate.cli_share_src = NULL;
4242 0 : cp_clistate.cli_share_dst = NULL;
4243 0 : cp_clistate.cwd = NULL;
4244 0 : cp_clistate.attribute = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY;
4245 0 : cp_clistate.c = c;
4246 :
4247 : /* open share source */
4248 0 : nt_status = connect_to_service(c, &cp_clistate.cli_share_src,
4249 : smbXcli_conn_remote_sockaddr(cli->conn),
4250 : smbXcli_conn_remote_name(cli->conn),
4251 : info502.name, "A:");
4252 0 : if (!NT_STATUS_IS_OK(nt_status))
4253 0 : goto done;
4254 :
4255 0 : got_src_share = true;
4256 :
4257 0 : if (net_mode_share == NET_MODE_SHARE_MIGRATE) {
4258 : /* open share destination */
4259 0 : nt_status = connect_to_service(c, &cp_clistate.cli_share_dst,
4260 : NULL, dst, info502.name, "A:");
4261 0 : if (!NT_STATUS_IS_OK(nt_status))
4262 0 : goto done;
4263 :
4264 0 : got_dst_share = true;
4265 : }
4266 :
4267 0 : if (!copy_top_level_perms(c, &cp_clistate, info502.name)) {
4268 0 : d_fprintf(stderr, _("Could not handle the top level "
4269 : "directory permissions for the "
4270 : "share: %s\n"), info502.name);
4271 0 : nt_status = NT_STATUS_UNSUCCESSFUL;
4272 0 : goto done;
4273 : }
4274 :
4275 0 : nt_status = sync_files(&cp_clistate, mask);
4276 0 : if (!NT_STATUS_IS_OK(nt_status)) {
4277 0 : d_fprintf(stderr, _("could not handle files for share: "
4278 : "%s\n"), info502.name);
4279 0 : goto done;
4280 : }
4281 : }
4282 :
4283 0 : nt_status = NT_STATUS_OK;
4284 :
4285 0 : done:
4286 :
4287 0 : if (got_src_share)
4288 0 : cli_shutdown(cp_clistate.cli_share_src);
4289 :
4290 0 : if (got_dst_share)
4291 0 : cli_shutdown(cp_clistate.cli_share_dst);
4292 :
4293 0 : SAFE_FREE(dst);
4294 0 : return nt_status;
4295 :
4296 : }
4297 :
4298 0 : static int rpc_share_migrate_files(struct net_context *c, int argc, const char **argv)
4299 : {
4300 0 : if (c->display_usage) {
4301 0 : d_printf( "%s\n"
4302 : "net share migrate files\n"
4303 : " %s\n",
4304 : _("Usage:"),
4305 : _("Migrate files to local server"));
4306 0 : return 0;
4307 : }
4308 :
4309 0 : if (!c->opt_host) {
4310 0 : d_printf(_("no server to migrate\n"));
4311 0 : return -1;
4312 : }
4313 :
4314 0 : return run_rpc_command(c, NULL, &ndr_table_srvsvc, 0,
4315 : rpc_share_migrate_files_internals,
4316 : argc, argv);
4317 : }
4318 :
4319 : /**
4320 : * Migrate share-ACLs from a remote RPC server to the local RPC server.
4321 : *
4322 : * All parameters are provided by the run_rpc_command function, except for
4323 : * argc, argv which are passed through.
4324 : *
4325 : * @param domain_sid The domain sid acquired from the remote server.
4326 : * @param cli A cli_state connected to the server.
4327 : * @param mem_ctx Talloc context, destroyed on completion of the function.
4328 : * @param argc Standard main() style argc.
4329 : * @param argv Standard main() style argv. Initial components are already
4330 : * stripped.
4331 : *
4332 : * @return Normal NTSTATUS return.
4333 : **/
4334 :
4335 0 : static NTSTATUS rpc_share_migrate_security_internals(struct net_context *c,
4336 : const struct dom_sid *domain_sid,
4337 : const char *domain_name,
4338 : struct cli_state *cli,
4339 : struct rpc_pipe_client *pipe_hnd,
4340 : TALLOC_CTX *mem_ctx,
4341 : int argc,
4342 : const char **argv)
4343 : {
4344 : WERROR result;
4345 0 : NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
4346 : struct srvsvc_NetShareInfoCtr ctr_src;
4347 : union srvsvc_NetShareInfo info;
4348 : uint32_t i;
4349 0 : struct rpc_pipe_client *srvsvc_pipe = NULL;
4350 0 : struct cli_state *cli_dst = NULL;
4351 0 : uint32_t level = 502; /* includes secdesc */
4352 0 : uint32_t parm_error = 0;
4353 : struct dcerpc_binding_handle *b;
4354 :
4355 0 : result = get_share_info(c, pipe_hnd, mem_ctx, level, argc, argv,
4356 : &ctr_src);
4357 :
4358 0 : if (!W_ERROR_IS_OK(result))
4359 0 : goto done;
4360 :
4361 : /* connect destination PI_SRVSVC */
4362 0 : nt_status = connect_dst_pipe(c, &cli_dst, &srvsvc_pipe,
4363 : &ndr_table_srvsvc);
4364 0 : if (!NT_STATUS_IS_OK(nt_status))
4365 0 : return nt_status;
4366 :
4367 0 : b = srvsvc_pipe->binding_handle;
4368 :
4369 0 : for (i = 0; i < ctr_src.ctr.ctr502->count; i++) {
4370 :
4371 0 : struct srvsvc_NetShareInfo502 info502 =
4372 0 : ctr_src.ctr.ctr502->array[i];
4373 :
4374 : /* reset error-code */
4375 0 : nt_status = NT_STATUS_UNSUCCESSFUL;
4376 :
4377 0 : if (!check_share_sanity(c, cli, info502.name, info502.type))
4378 0 : continue;
4379 :
4380 0 : printf(_("migrating: [%s], path: %s, comment: %s, including "
4381 : "share-ACLs\n"),
4382 : info502.name, info502.path, info502.comment);
4383 :
4384 0 : if (c->opt_verbose)
4385 0 : display_sec_desc(info502.sd_buf.sd);
4386 :
4387 : /* FIXME: shouldn't we be able to just set the security descriptor ? */
4388 0 : info.info502 = &info502;
4389 :
4390 : /* finally modify the share on the dst server */
4391 0 : nt_status = dcerpc_srvsvc_NetShareSetInfo(b, mem_ctx,
4392 0 : srvsvc_pipe->desthost,
4393 : info502.name,
4394 : level,
4395 : &info,
4396 : &parm_error,
4397 : &result);
4398 0 : if (!NT_STATUS_IS_OK(nt_status)) {
4399 0 : printf(_("cannot set share-acl: %s\n"),
4400 : nt_errstr(nt_status));
4401 0 : goto done;
4402 : }
4403 0 : if (!W_ERROR_IS_OK(result)) {
4404 0 : nt_status = werror_to_ntstatus(result);
4405 0 : printf(_("cannot set share-acl: %s\n"),
4406 : win_errstr(result));
4407 0 : goto done;
4408 : }
4409 :
4410 : }
4411 :
4412 0 : nt_status = NT_STATUS_OK;
4413 :
4414 0 : done:
4415 0 : if (cli_dst) {
4416 0 : cli_shutdown(cli_dst);
4417 : }
4418 :
4419 0 : return nt_status;
4420 :
4421 : }
4422 :
4423 : /**
4424 : * Migrate share-acls from a RPC server to another.
4425 : *
4426 : * @param argc Standard main() style argc.
4427 : * @param argv Standard main() style argv. Initial components are already
4428 : * stripped.
4429 : *
4430 : * @return A shell status integer (0 for success).
4431 : **/
4432 0 : static int rpc_share_migrate_security(struct net_context *c, int argc,
4433 : const char **argv)
4434 : {
4435 0 : if (c->display_usage) {
4436 0 : d_printf( "%s\n"
4437 : "net rpc share migrate security\n"
4438 : " %s\n",
4439 : _("Usage:"),
4440 : _("Migrate share-acls to local server"));
4441 0 : return 0;
4442 : }
4443 :
4444 0 : if (!c->opt_host) {
4445 0 : d_printf(_("no server to migrate\n"));
4446 0 : return -1;
4447 : }
4448 :
4449 0 : return run_rpc_command(c, NULL, &ndr_table_srvsvc, 0,
4450 : rpc_share_migrate_security_internals,
4451 : argc, argv);
4452 : }
4453 :
4454 : /**
4455 : * Migrate shares (including share-definitions, share-acls and files with acls/attrs)
4456 : * from one server to another.
4457 : *
4458 : * @param argc Standard main() style argc.
4459 : * @param argv Standard main() style argv. Initial components are already
4460 : * stripped.
4461 : *
4462 : * @return A shell status integer (0 for success).
4463 : *
4464 : **/
4465 0 : static int rpc_share_migrate_all(struct net_context *c, int argc,
4466 : const char **argv)
4467 : {
4468 : int ret;
4469 :
4470 0 : if (c->display_usage) {
4471 0 : d_printf( "%s\n"
4472 : "net rpc share migrate all\n"
4473 : " %s\n",
4474 : _("Usage:"),
4475 : _("Migrates shares including all share settings"));
4476 0 : return 0;
4477 : }
4478 :
4479 0 : if (!c->opt_host) {
4480 0 : d_printf(_("no server to migrate\n"));
4481 0 : return -1;
4482 : }
4483 :
4484 : /* order is important. we don't want to be locked out by the share-acl
4485 : * before copying files - gd */
4486 :
4487 0 : ret = run_rpc_command(c, NULL, &ndr_table_srvsvc, 0,
4488 : rpc_share_migrate_shares_internals, argc, argv);
4489 0 : if (ret)
4490 0 : return ret;
4491 :
4492 0 : ret = run_rpc_command(c, NULL, &ndr_table_srvsvc, 0,
4493 : rpc_share_migrate_files_internals, argc, argv);
4494 0 : if (ret)
4495 0 : return ret;
4496 :
4497 0 : return run_rpc_command(c, NULL, &ndr_table_srvsvc, 0,
4498 : rpc_share_migrate_security_internals, argc,
4499 : argv);
4500 : }
4501 :
4502 :
4503 : /**
4504 : * 'net rpc share migrate' entrypoint.
4505 : * @param argc Standard main() style argc.
4506 : * @param argv Standard main() style argv. Initial components are already
4507 : * stripped.
4508 : **/
4509 0 : static int rpc_share_migrate(struct net_context *c, int argc, const char **argv)
4510 : {
4511 :
4512 0 : struct functable func[] = {
4513 : {
4514 : "all",
4515 : rpc_share_migrate_all,
4516 : NET_TRANSPORT_RPC,
4517 : N_("Migrate shares from remote to local server"),
4518 : N_("net rpc share migrate all\n"
4519 : " Migrate shares from remote to local server")
4520 : },
4521 : {
4522 : "files",
4523 : rpc_share_migrate_files,
4524 : NET_TRANSPORT_RPC,
4525 : N_("Migrate files from remote to local server"),
4526 : N_("net rpc share migrate files\n"
4527 : " Migrate files from remote to local server")
4528 : },
4529 : {
4530 : "security",
4531 : rpc_share_migrate_security,
4532 : NET_TRANSPORT_RPC,
4533 : N_("Migrate share-ACLs from remote to local server"),
4534 : N_("net rpc share migrate security\n"
4535 : " Migrate share-ACLs from remote to local server")
4536 : },
4537 : {
4538 : "shares",
4539 : rpc_share_migrate_shares,
4540 : NET_TRANSPORT_RPC,
4541 : N_("Migrate shares from remote to local server"),
4542 : N_("net rpc share migrate shares\n"
4543 : " Migrate shares from remote to local server")
4544 : },
4545 : {NULL, NULL, 0, NULL, NULL}
4546 : };
4547 :
4548 0 : net_mode_share = NET_MODE_SHARE_MIGRATE;
4549 :
4550 0 : return net_run_function(c, argc, argv, "net rpc share migrate", func);
4551 : }
4552 :
4553 : struct full_alias {
4554 : struct dom_sid sid;
4555 : uint32_t num_members;
4556 : struct dom_sid *members;
4557 : };
4558 :
4559 : static int num_server_aliases;
4560 : static struct full_alias *server_aliases;
4561 :
4562 : /*
4563 : * Add an alias to the static list.
4564 : */
4565 0 : static void push_alias(struct full_alias *alias)
4566 : {
4567 : size_t array_size;
4568 :
4569 0 : if (server_aliases == NULL) {
4570 0 : server_aliases = talloc_array(NULL, struct full_alias, 100);
4571 0 : if (server_aliases == NULL) {
4572 0 : smb_panic("talloc_array failed");
4573 : }
4574 : }
4575 :
4576 0 : array_size = talloc_array_length(server_aliases);
4577 0 : if (array_size == num_server_aliases) {
4578 0 : server_aliases = talloc_realloc(NULL, server_aliases,
4579 : struct full_alias, array_size + 100);
4580 0 : if (server_aliases == NULL) {
4581 0 : smb_panic("talloc_realloc failed");
4582 : }
4583 : }
4584 :
4585 0 : server_aliases[num_server_aliases] = *alias;
4586 0 : num_server_aliases += 1;
4587 0 : }
4588 :
4589 : /*
4590 : * For a specific domain on the server, fetch all the aliases
4591 : * and their members. Add all of them to the server_aliases.
4592 : */
4593 :
4594 0 : static NTSTATUS rpc_fetch_domain_aliases(struct rpc_pipe_client *pipe_hnd,
4595 : TALLOC_CTX *mem_ctx,
4596 : struct policy_handle *connect_pol,
4597 : const struct dom_sid *domain_sid)
4598 : {
4599 : uint32_t start_idx, max_entries, num_entries, i;
4600 0 : struct samr_SamArray *groups = NULL;
4601 : NTSTATUS result, status;
4602 : struct policy_handle domain_pol;
4603 0 : struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
4604 :
4605 : /* Get domain policy handle */
4606 :
4607 0 : status = dcerpc_samr_OpenDomain(b, mem_ctx,
4608 : connect_pol,
4609 : MAXIMUM_ALLOWED_ACCESS,
4610 : discard_const_p(struct dom_sid2, domain_sid),
4611 : &domain_pol,
4612 : &result);
4613 0 : if (!NT_STATUS_IS_OK(status)) {
4614 0 : return status;
4615 : }
4616 0 : if (!NT_STATUS_IS_OK(result)) {
4617 0 : return result;
4618 : }
4619 :
4620 0 : start_idx = 0;
4621 0 : max_entries = 250;
4622 :
4623 : do {
4624 0 : status = dcerpc_samr_EnumDomainAliases(b, mem_ctx,
4625 : &domain_pol,
4626 : &start_idx,
4627 : &groups,
4628 : max_entries,
4629 : &num_entries,
4630 : &result);
4631 0 : if (!NT_STATUS_IS_OK(status)) {
4632 0 : goto done;
4633 : }
4634 0 : for (i = 0; i < num_entries; i++) {
4635 :
4636 : struct policy_handle alias_pol;
4637 : struct full_alias alias;
4638 : struct lsa_SidArray sid_array;
4639 : int j;
4640 : NTSTATUS _result;
4641 :
4642 0 : status = dcerpc_samr_OpenAlias(b, mem_ctx,
4643 : &domain_pol,
4644 : MAXIMUM_ALLOWED_ACCESS,
4645 0 : groups->entries[i].idx,
4646 : &alias_pol,
4647 : &_result);
4648 0 : if (!NT_STATUS_IS_OK(status)) {
4649 0 : goto done;
4650 : }
4651 0 : if (!NT_STATUS_IS_OK(_result)) {
4652 0 : status = _result;
4653 0 : goto done;
4654 : }
4655 :
4656 0 : status = dcerpc_samr_GetMembersInAlias(b, mem_ctx,
4657 : &alias_pol,
4658 : &sid_array,
4659 : &_result);
4660 0 : if (!NT_STATUS_IS_OK(status)) {
4661 0 : goto done;
4662 : }
4663 0 : if (!NT_STATUS_IS_OK(_result)) {
4664 0 : status = _result;
4665 0 : goto done;
4666 : }
4667 :
4668 0 : alias.num_members = sid_array.num_sids;
4669 :
4670 0 : status = dcerpc_samr_Close(b, mem_ctx, &alias_pol, &_result);
4671 0 : if (!NT_STATUS_IS_OK(status)) {
4672 0 : goto done;
4673 : }
4674 0 : if (!NT_STATUS_IS_OK(_result)) {
4675 0 : status = _result;
4676 0 : goto done;
4677 : }
4678 :
4679 0 : alias.members = NULL;
4680 :
4681 0 : if (alias.num_members > 0) {
4682 0 : alias.members = SMB_MALLOC_ARRAY(struct dom_sid, alias.num_members);
4683 0 : if (alias.members == NULL) {
4684 0 : status = NT_STATUS_NO_MEMORY;
4685 0 : goto done;
4686 : }
4687 :
4688 0 : for (j = 0; j < alias.num_members; j++)
4689 0 : sid_copy(&alias.members[j],
4690 0 : sid_array.sids[j].sid);
4691 : }
4692 :
4693 0 : sid_compose(&alias.sid, domain_sid,
4694 0 : groups->entries[i].idx);
4695 :
4696 0 : push_alias(&alias);
4697 : }
4698 0 : } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
4699 :
4700 0 : status = NT_STATUS_OK;
4701 :
4702 0 : done:
4703 0 : dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
4704 :
4705 0 : return status;
4706 : }
4707 :
4708 : /*
4709 : * Dump server_aliases as names for debugging purposes.
4710 : */
4711 :
4712 0 : static NTSTATUS rpc_aliaslist_dump(struct net_context *c,
4713 : const struct dom_sid *domain_sid,
4714 : const char *domain_name,
4715 : struct cli_state *cli,
4716 : struct rpc_pipe_client *pipe_hnd,
4717 : TALLOC_CTX *mem_ctx,
4718 : int argc,
4719 : const char **argv)
4720 : {
4721 : uint32_t i;
4722 : NTSTATUS result;
4723 : struct policy_handle lsa_pol;
4724 0 : struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
4725 :
4726 0 : result = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, true,
4727 : SEC_FLAG_MAXIMUM_ALLOWED,
4728 : &lsa_pol);
4729 0 : if (!NT_STATUS_IS_OK(result))
4730 0 : return result;
4731 :
4732 0 : for (i=0; i<num_server_aliases; i++) {
4733 : char **names;
4734 : char **domains;
4735 : enum lsa_SidType *types;
4736 : int j;
4737 :
4738 0 : struct full_alias *alias = &server_aliases[i];
4739 :
4740 0 : result = rpccli_lsa_lookup_sids(pipe_hnd, mem_ctx, &lsa_pol, 1,
4741 0 : &alias->sid,
4742 : &domains, &names, &types);
4743 0 : if (!NT_STATUS_IS_OK(result))
4744 0 : continue;
4745 :
4746 0 : DEBUG(1, ("%s\\%s %d: ", domains[0], names[0], types[0]));
4747 :
4748 0 : if (alias->num_members == 0) {
4749 0 : DEBUG(1, ("\n"));
4750 0 : continue;
4751 : }
4752 :
4753 0 : result = rpccli_lsa_lookup_sids(pipe_hnd, mem_ctx, &lsa_pol,
4754 0 : alias->num_members,
4755 0 : alias->members,
4756 : &domains, &names, &types);
4757 :
4758 0 : if (!NT_STATUS_IS_OK(result) &&
4759 0 : !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
4760 0 : continue;
4761 :
4762 0 : for (j=0; j<alias->num_members; j++)
4763 0 : DEBUG(1, ("%s\\%s (%d); ",
4764 : domains[j] ? domains[j] : "*unknown*",
4765 : names[j] ? names[j] : "*unknown*",types[j]));
4766 0 : DEBUG(1, ("\n"));
4767 : }
4768 :
4769 0 : dcerpc_lsa_Close(b, mem_ctx, &lsa_pol, &result);
4770 :
4771 0 : return NT_STATUS_OK;
4772 : }
4773 :
4774 : /*
4775 : * Fetch a list of all server aliases and their members into
4776 : * server_aliases.
4777 : */
4778 :
4779 0 : static NTSTATUS rpc_aliaslist_internals(struct net_context *c,
4780 : const struct dom_sid *domain_sid,
4781 : const char *domain_name,
4782 : struct cli_state *cli,
4783 : struct rpc_pipe_client *pipe_hnd,
4784 : TALLOC_CTX *mem_ctx,
4785 : int argc,
4786 : const char **argv)
4787 : {
4788 : NTSTATUS result, status;
4789 : struct policy_handle connect_pol;
4790 0 : struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
4791 :
4792 0 : status = dcerpc_samr_Connect2(b, mem_ctx,
4793 0 : pipe_hnd->desthost,
4794 : MAXIMUM_ALLOWED_ACCESS,
4795 : &connect_pol,
4796 : &result);
4797 0 : if (!NT_STATUS_IS_OK(status)) {
4798 0 : goto done;
4799 : }
4800 0 : if (!NT_STATUS_IS_OK(result)) {
4801 0 : status = result;
4802 0 : goto done;
4803 : }
4804 :
4805 0 : status = rpc_fetch_domain_aliases(pipe_hnd, mem_ctx, &connect_pol,
4806 : &global_sid_Builtin);
4807 0 : if (!NT_STATUS_IS_OK(status)) {
4808 0 : goto done;
4809 : }
4810 :
4811 0 : status = rpc_fetch_domain_aliases(pipe_hnd, mem_ctx, &connect_pol,
4812 : domain_sid);
4813 :
4814 0 : dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
4815 0 : done:
4816 0 : return status;
4817 : }
4818 :
4819 0 : static void init_user_token(struct security_token *token, struct dom_sid *user_sid)
4820 : {
4821 0 : token->num_sids = 4;
4822 :
4823 0 : if (!(token->sids = SMB_MALLOC_ARRAY(struct dom_sid, 4))) {
4824 0 : d_fprintf(stderr, "malloc %s\n",_("failed"));
4825 0 : token->num_sids = 0;
4826 0 : return;
4827 : }
4828 :
4829 0 : token->sids[0] = *user_sid;
4830 0 : sid_copy(&token->sids[1], &global_sid_World);
4831 0 : sid_copy(&token->sids[2], &global_sid_Network);
4832 0 : sid_copy(&token->sids[3], &global_sid_Authenticated_Users);
4833 : }
4834 :
4835 0 : static void free_user_token(struct security_token *token)
4836 : {
4837 0 : SAFE_FREE(token->sids);
4838 0 : }
4839 :
4840 0 : static void add_sid_to_token(struct security_token *token, struct dom_sid *sid)
4841 : {
4842 0 : if (security_token_has_sid(token, sid))
4843 0 : return;
4844 :
4845 0 : token->sids = SMB_REALLOC_ARRAY(token->sids, struct dom_sid, token->num_sids+1);
4846 0 : if (!token->sids) {
4847 0 : return;
4848 : }
4849 :
4850 0 : sid_copy(&token->sids[token->num_sids], sid);
4851 :
4852 0 : token->num_sids += 1;
4853 : }
4854 :
4855 : struct user_token {
4856 : fstring name;
4857 : struct security_token token;
4858 : };
4859 :
4860 0 : static void dump_user_token(struct user_token *token)
4861 : {
4862 : uint32_t i;
4863 :
4864 0 : d_printf("%s\n", token->name);
4865 :
4866 0 : for (i=0; i<token->token.num_sids; i++) {
4867 : struct dom_sid_buf buf;
4868 0 : d_printf(" %s\n",
4869 0 : dom_sid_str_buf(&token->token.sids[i], &buf));
4870 : }
4871 0 : }
4872 :
4873 0 : static bool is_alias_member(struct dom_sid *sid, struct full_alias *alias)
4874 : {
4875 : uint32_t i;
4876 :
4877 0 : for (i=0; i<alias->num_members; i++) {
4878 0 : if (dom_sid_equal(sid, &alias->members[i])) {
4879 0 : return true;
4880 : }
4881 : }
4882 :
4883 0 : return false;
4884 : }
4885 :
4886 0 : static void collect_sid_memberships(struct security_token *token, struct dom_sid sid)
4887 : {
4888 : int i;
4889 :
4890 0 : for (i=0; i<num_server_aliases; i++) {
4891 0 : if (is_alias_member(&sid, &server_aliases[i]))
4892 0 : add_sid_to_token(token, &server_aliases[i].sid);
4893 : }
4894 0 : }
4895 :
4896 : /*
4897 : * We got a user token with all the SIDs we can know about without asking the
4898 : * server directly. These are the user and domain group sids. All of these can
4899 : * be members of aliases. So scan the list of aliases for each of the SIDs and
4900 : * add them to the token.
4901 : */
4902 :
4903 0 : static void collect_alias_memberships(struct security_token *token)
4904 : {
4905 0 : int num_global_sids = token->num_sids;
4906 : int i;
4907 :
4908 0 : for (i=0; i<num_global_sids; i++) {
4909 0 : collect_sid_memberships(token, token->sids[i]);
4910 : }
4911 0 : }
4912 :
4913 0 : static bool get_user_sids(const char *domain, const char *user, struct security_token *token)
4914 : {
4915 0 : wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
4916 : enum wbcSidType type;
4917 : fstring full_name;
4918 : struct wbcDomainSid wsid;
4919 : char sid_str[WBC_SID_STRING_BUFLEN];
4920 : struct dom_sid user_sid;
4921 : uint32_t num_groups;
4922 0 : gid_t *groups = NULL;
4923 : uint32_t i;
4924 :
4925 0 : fstr_sprintf(full_name, "%s%c%s",
4926 0 : domain, *lp_winbind_separator(), user);
4927 :
4928 : /* First let's find out the user sid */
4929 :
4930 0 : wbc_status = wbcLookupName(domain, user, &wsid, &type);
4931 :
4932 0 : if (!WBC_ERROR_IS_OK(wbc_status)) {
4933 0 : DEBUG(1, ("winbind could not find %s: %s\n",
4934 : full_name, wbcErrorString(wbc_status)));
4935 0 : return false;
4936 : }
4937 :
4938 0 : wbcSidToStringBuf(&wsid, sid_str, sizeof(sid_str));
4939 :
4940 0 : if (type != WBC_SID_NAME_USER) {
4941 0 : DEBUG(1, ("%s is not a user\n", full_name));
4942 0 : return false;
4943 : }
4944 :
4945 0 : if (!string_to_sid(&user_sid, sid_str)) {
4946 0 : DEBUG(1,("Could not convert sid %s from string\n", sid_str));
4947 0 : return false;
4948 : }
4949 :
4950 0 : init_user_token(token, &user_sid);
4951 :
4952 : /* And now the groups winbind knows about */
4953 :
4954 0 : wbc_status = wbcGetGroups(full_name, &num_groups, &groups);
4955 0 : if (!WBC_ERROR_IS_OK(wbc_status)) {
4956 0 : DEBUG(1, ("winbind could not get groups of %s: %s\n",
4957 : full_name, wbcErrorString(wbc_status)));
4958 0 : return false;
4959 : }
4960 :
4961 0 : for (i = 0; i < num_groups; i++) {
4962 0 : gid_t gid = groups[i];
4963 : struct dom_sid sid;
4964 : bool ok;
4965 :
4966 0 : wbc_status = wbcGidToSid(gid, &wsid);
4967 0 : if (!WBC_ERROR_IS_OK(wbc_status)) {
4968 0 : DEBUG(1, ("winbind could not find SID of gid %u: %s\n",
4969 : (unsigned int)gid, wbcErrorString(wbc_status)));
4970 0 : wbcFreeMemory(groups);
4971 0 : return false;
4972 : }
4973 :
4974 0 : wbcSidToStringBuf(&wsid, sid_str, sizeof(sid_str));
4975 :
4976 0 : DEBUG(3, (" %s\n", sid_str));
4977 :
4978 0 : ok = string_to_sid(&sid, sid_str);
4979 0 : if (!ok) {
4980 0 : DEBUG(1, ("Failed to convert string to SID\n"));
4981 0 : wbcFreeMemory(groups);
4982 0 : return false;
4983 : }
4984 0 : add_sid_to_token(token, &sid);
4985 : }
4986 0 : wbcFreeMemory(groups);
4987 :
4988 0 : return true;
4989 : }
4990 :
4991 : /**
4992 : * Get a list of all user tokens we want to look at
4993 : **/
4994 :
4995 0 : static bool get_user_tokens(struct net_context *c, int *num_tokens,
4996 : struct user_token **user_tokens)
4997 : {
4998 0 : wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
4999 : uint32_t i, num_users;
5000 : const char **users;
5001 : struct user_token *result;
5002 0 : TALLOC_CTX *frame = NULL;
5003 :
5004 0 : if (lp_winbind_use_default_domain() &&
5005 0 : (c->opt_target_workgroup == NULL)) {
5006 0 : d_fprintf(stderr, _("winbind use default domain = yes set, "
5007 : "please specify a workgroup\n"));
5008 0 : return false;
5009 : }
5010 :
5011 : /* Send request to winbind daemon */
5012 :
5013 0 : wbc_status = wbcListUsers(NULL, &num_users, &users);
5014 0 : if (!WBC_ERROR_IS_OK(wbc_status)) {
5015 0 : DEBUG(1, (_("winbind could not list users: %s\n"),
5016 : wbcErrorString(wbc_status)));
5017 0 : return false;
5018 : }
5019 :
5020 0 : result = SMB_MALLOC_ARRAY(struct user_token, num_users);
5021 :
5022 0 : if (result == NULL) {
5023 0 : DEBUG(1, ("Could not malloc sid array\n"));
5024 0 : wbcFreeMemory(users);
5025 0 : return false;
5026 : }
5027 :
5028 0 : frame = talloc_stackframe();
5029 0 : for (i=0; i < num_users; i++) {
5030 : fstring domain, user;
5031 : char *p;
5032 :
5033 0 : fstrcpy(result[i].name, users[i]);
5034 :
5035 0 : p = strchr(users[i], *lp_winbind_separator());
5036 :
5037 0 : DEBUG(3, ("%s\n", users[i]));
5038 :
5039 0 : if (p == NULL) {
5040 0 : fstrcpy(domain, c->opt_target_workgroup);
5041 0 : fstrcpy(user, users[i]);
5042 : } else {
5043 0 : *p++ = '\0';
5044 0 : fstrcpy(domain, users[i]);
5045 0 : if (!strupper_m(domain)) {
5046 0 : DEBUG(1, ("strupper_m %s failed\n", domain));
5047 0 : wbcFreeMemory(users);
5048 0 : return false;
5049 : }
5050 0 : fstrcpy(user, p);
5051 : }
5052 :
5053 0 : get_user_sids(domain, user, &(result[i].token));
5054 : }
5055 0 : TALLOC_FREE(frame);
5056 0 : wbcFreeMemory(users);
5057 :
5058 0 : *num_tokens = num_users;
5059 0 : *user_tokens = result;
5060 :
5061 0 : return true;
5062 : }
5063 :
5064 0 : static bool get_user_tokens_from_file(FILE *f,
5065 : int *num_tokens,
5066 : struct user_token **tokens)
5067 : {
5068 0 : struct user_token *token = NULL;
5069 :
5070 0 : while (!feof(f)) {
5071 : fstring line;
5072 :
5073 0 : if (fgets(line, sizeof(line)-1, f) == NULL) {
5074 0 : return true;
5075 : }
5076 :
5077 0 : if ((strlen(line) > 0) && (line[strlen(line)-1] == '\n')) {
5078 0 : line[strlen(line)-1] = '\0';
5079 : }
5080 :
5081 0 : if (line[0] == ' ') {
5082 : /* We have a SID */
5083 :
5084 : struct dom_sid sid;
5085 0 : if(!string_to_sid(&sid, &line[1])) {
5086 0 : DEBUG(1,("get_user_tokens_from_file: Could "
5087 : "not convert sid %s \n",&line[1]));
5088 0 : return false;
5089 : }
5090 :
5091 0 : if (token == NULL) {
5092 0 : DEBUG(0, ("File does not begin with username"));
5093 0 : return false;
5094 : }
5095 :
5096 0 : add_sid_to_token(&token->token, &sid);
5097 0 : continue;
5098 : }
5099 :
5100 : /* And a new user... */
5101 :
5102 0 : *num_tokens += 1;
5103 0 : *tokens = SMB_REALLOC_ARRAY(*tokens, struct user_token, *num_tokens);
5104 0 : if (*tokens == NULL) {
5105 0 : DEBUG(0, ("Could not realloc tokens\n"));
5106 0 : return false;
5107 : }
5108 :
5109 0 : token = &((*tokens)[*num_tokens-1]);
5110 :
5111 0 : if (strlcpy(token->name, line, sizeof(token->name)) >= sizeof(token->name)) {
5112 0 : return false;
5113 : }
5114 0 : token->token.num_sids = 0;
5115 0 : token->token.sids = NULL;
5116 0 : continue;
5117 : }
5118 :
5119 0 : return false;
5120 : }
5121 :
5122 :
5123 : /*
5124 : * Show the list of all users that have access to a share
5125 : */
5126 :
5127 0 : static void show_userlist(struct rpc_pipe_client *pipe_hnd,
5128 : struct cli_state *cli,
5129 : TALLOC_CTX *mem_ctx,
5130 : const char *netname,
5131 : int num_tokens,
5132 : struct user_token *tokens)
5133 : {
5134 : uint16_t fnum;
5135 0 : struct security_descriptor *share_sd = NULL;
5136 0 : struct security_descriptor *root_sd = NULL;
5137 : int i;
5138 : union srvsvc_NetShareInfo info;
5139 : WERROR result;
5140 : NTSTATUS status;
5141 0 : struct smbXcli_tcon *orig_tcon = NULL;
5142 0 : char *orig_share = NULL;
5143 0 : struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
5144 :
5145 0 : status = dcerpc_srvsvc_NetShareGetInfo(b, mem_ctx,
5146 0 : pipe_hnd->desthost,
5147 : netname,
5148 : 502,
5149 : &info,
5150 : &result);
5151 :
5152 0 : if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
5153 0 : DEBUG(1, ("Could not query secdesc for share %s\n",
5154 : netname));
5155 0 : return;
5156 : }
5157 :
5158 0 : share_sd = info.info502->sd_buf.sd;
5159 0 : if (share_sd == NULL) {
5160 0 : DEBUG(1, ("Got no secdesc for share %s\n",
5161 : netname));
5162 : }
5163 :
5164 0 : if (cli_state_has_tcon(cli)) {
5165 0 : cli_state_save_tcon_share(cli, &orig_tcon, &orig_share);
5166 : }
5167 :
5168 0 : if (!NT_STATUS_IS_OK(cli_tree_connect(cli, netname, "A:", NULL))) {
5169 0 : cli_state_restore_tcon_share(cli, orig_tcon, orig_share);
5170 0 : return;
5171 : }
5172 :
5173 0 : if (!NT_STATUS_IS_OK(cli_ntcreate(cli, "\\", 0, READ_CONTROL_ACCESS, 0,
5174 : FILE_SHARE_READ|FILE_SHARE_WRITE,
5175 : FILE_OPEN, 0x0, 0x0, &fnum, NULL))) {
5176 0 : cli_query_secdesc(cli, fnum, mem_ctx, &root_sd);
5177 : }
5178 :
5179 0 : for (i=0; i<num_tokens; i++) {
5180 : uint32_t acc_granted;
5181 :
5182 0 : if (share_sd != NULL) {
5183 0 : status = se_access_check(share_sd, &tokens[i].token,
5184 : 1, &acc_granted);
5185 :
5186 0 : if (!NT_STATUS_IS_OK(status)) {
5187 0 : DEBUG(1, ("Could not check share_sd for "
5188 : "user %s\n",
5189 : tokens[i].name));
5190 0 : continue;
5191 : }
5192 : }
5193 :
5194 0 : if (root_sd == NULL) {
5195 0 : d_printf(" %s\n", tokens[i].name);
5196 0 : continue;
5197 : }
5198 :
5199 0 : status = se_access_check(root_sd, &tokens[i].token,
5200 : 1, &acc_granted);
5201 0 : if (!NT_STATUS_IS_OK(status)) {
5202 0 : DEBUG(1, ("Could not check root_sd for user %s\n",
5203 : tokens[i].name));
5204 0 : continue;
5205 : }
5206 0 : d_printf(" %s\n", tokens[i].name);
5207 : }
5208 :
5209 0 : if (fnum != (uint16_t)-1)
5210 0 : cli_close(cli, fnum);
5211 0 : cli_tdis(cli);
5212 0 : cli_state_restore_tcon_share(cli, orig_tcon, orig_share);
5213 :
5214 0 : return;
5215 : }
5216 :
5217 : /**
5218 : * List shares on a remote RPC server, including the security descriptors.
5219 : *
5220 : * All parameters are provided by the run_rpc_command function, except for
5221 : * argc, argv which are passed through.
5222 : *
5223 : * @param domain_sid The domain sid acquired from the remote server.
5224 : * @param cli A cli_state connected to the server.
5225 : * @param mem_ctx Talloc context, destroyed on completion of the function.
5226 : * @param argc Standard main() style argc.
5227 : * @param argv Standard main() style argv. Initial components are already
5228 : * stripped.
5229 : *
5230 : * @return Normal NTSTATUS return.
5231 : **/
5232 :
5233 0 : static NTSTATUS rpc_share_allowedusers_internals(struct net_context *c,
5234 : const struct dom_sid *domain_sid,
5235 : const char *domain_name,
5236 : struct cli_state *cli,
5237 : struct rpc_pipe_client *pipe_hnd,
5238 : TALLOC_CTX *mem_ctx,
5239 : int argc,
5240 : const char **argv)
5241 : {
5242 : bool r;
5243 : FILE *f;
5244 0 : NTSTATUS nt_status = NT_STATUS_OK;
5245 0 : uint32_t total_entries = 0;
5246 0 : uint32_t resume_handle = 0;
5247 0 : uint32_t preferred_len = 0xffffffff;
5248 : uint32_t i;
5249 0 : struct dcerpc_binding_handle *b = NULL;
5250 : struct srvsvc_NetShareInfoCtr info_ctr;
5251 : struct srvsvc_NetShareCtr1 ctr1;
5252 : WERROR result;
5253 :
5254 0 : struct user_token *tokens = NULL;
5255 0 : int num_tokens = 0;
5256 :
5257 0 : if (argc == 0) {
5258 0 : f = stdin;
5259 : } else {
5260 0 : if (strequal(argv[0], "-")) {
5261 0 : f = stdin;
5262 : } else {
5263 0 : f = fopen(argv[0], "r");
5264 : }
5265 0 : argv++;
5266 0 : argc--;
5267 : }
5268 :
5269 0 : if (f == NULL) {
5270 0 : DEBUG(0, ("Could not open userlist: %s\n", strerror(errno)));
5271 0 : return NT_STATUS_UNSUCCESSFUL;
5272 : }
5273 :
5274 0 : r = get_user_tokens_from_file(f, &num_tokens, &tokens);
5275 :
5276 0 : if (f != stdin)
5277 0 : fclose(f);
5278 :
5279 0 : if (!r) {
5280 0 : DEBUG(0, ("Could not read users from file\n"));
5281 0 : return NT_STATUS_UNSUCCESSFUL;
5282 : }
5283 :
5284 0 : for (i=0; i<num_tokens; i++)
5285 0 : collect_alias_memberships(&tokens[i].token);
5286 :
5287 0 : ZERO_STRUCT(info_ctr);
5288 0 : ZERO_STRUCT(ctr1);
5289 :
5290 0 : info_ctr.level = 1;
5291 0 : info_ctr.ctr.ctr1 = &ctr1;
5292 :
5293 0 : b = pipe_hnd->binding_handle;
5294 :
5295 0 : if (argc != 0) {
5296 : /* Show results only for shares listed on the command line. */
5297 0 : while (*argv) {
5298 0 : const char *netname = *argv++;
5299 0 : d_printf("%s\n", netname);
5300 0 : show_userlist(pipe_hnd, cli, mem_ctx, netname,
5301 : num_tokens, tokens);
5302 : }
5303 0 : goto done;
5304 : }
5305 :
5306 : /* Issue the NetShareEnum RPC call and retrieve the response */
5307 0 : nt_status = dcerpc_srvsvc_NetShareEnumAll(b,
5308 : talloc_tos(),
5309 0 : pipe_hnd->desthost,
5310 : &info_ctr,
5311 : preferred_len,
5312 : &total_entries,
5313 : &resume_handle,
5314 : &result);
5315 :
5316 : /* Was it successful? */
5317 0 : if (!NT_STATUS_IS_OK(nt_status)) {
5318 : /* Nope. Go clean up. */
5319 0 : goto done;
5320 : }
5321 :
5322 0 : if (!W_ERROR_IS_OK(result)) {
5323 : /* Nope. Go clean up. */
5324 0 : nt_status = werror_to_ntstatus(result);
5325 0 : goto done;
5326 : }
5327 :
5328 0 : if (total_entries == 0) {
5329 0 : goto done;
5330 : }
5331 :
5332 : /* For each returned entry... */
5333 0 : for (i = 0; i < info_ctr.ctr.ctr1->count; i++) {
5334 0 : const char *netname = info_ctr.ctr.ctr1->array[i].name;
5335 :
5336 0 : if (info_ctr.ctr.ctr1->array[i].type != STYPE_DISKTREE) {
5337 0 : continue;
5338 : }
5339 :
5340 0 : d_printf("%s\n", netname);
5341 :
5342 0 : show_userlist(pipe_hnd, cli, mem_ctx, netname,
5343 : num_tokens, tokens);
5344 : }
5345 0 : done:
5346 0 : for (i=0; i<num_tokens; i++) {
5347 0 : free_user_token(&tokens[i].token);
5348 : }
5349 0 : SAFE_FREE(tokens);
5350 0 : TALLOC_FREE(server_aliases);
5351 :
5352 0 : return nt_status;
5353 : }
5354 :
5355 0 : static int rpc_share_allowedusers(struct net_context *c, int argc,
5356 : const char **argv)
5357 : {
5358 : int result;
5359 :
5360 0 : if (c->display_usage) {
5361 0 : d_printf( "%s\n"
5362 : "net rpc share allowedusers\n"
5363 : " %s\n",
5364 : _("Usage:"),
5365 : _("List allowed users"));
5366 0 : return 0;
5367 : }
5368 :
5369 0 : result = run_rpc_command(c, NULL, &ndr_table_samr, 0,
5370 : rpc_aliaslist_internals,
5371 : argc, argv);
5372 0 : if (result != 0)
5373 0 : return result;
5374 :
5375 0 : result = run_rpc_command(c, NULL, &ndr_table_lsarpc, 0,
5376 : rpc_aliaslist_dump,
5377 : argc, argv);
5378 0 : if (result != 0)
5379 0 : return result;
5380 :
5381 0 : return run_rpc_command(c, NULL, &ndr_table_srvsvc, 0,
5382 : rpc_share_allowedusers_internals,
5383 : argc, argv);
5384 : }
5385 :
5386 0 : int net_usersidlist(struct net_context *c, int argc, const char **argv)
5387 : {
5388 0 : int num_tokens = 0;
5389 0 : struct user_token *tokens = NULL;
5390 : int i;
5391 :
5392 0 : if (argc != 0) {
5393 0 : net_usersidlist_usage(c, argc, argv);
5394 0 : return 0;
5395 : }
5396 :
5397 0 : if (!get_user_tokens(c, &num_tokens, &tokens)) {
5398 0 : DEBUG(0, ("Could not get the user/sid list\n"));
5399 0 : return -1;
5400 : }
5401 :
5402 0 : for (i=0; i<num_tokens; i++) {
5403 0 : dump_user_token(&tokens[i]);
5404 0 : free_user_token(&tokens[i].token);
5405 : }
5406 :
5407 0 : SAFE_FREE(tokens);
5408 0 : return 0;
5409 : }
5410 :
5411 0 : int net_usersidlist_usage(struct net_context *c, int argc, const char **argv)
5412 : {
5413 0 : d_printf(_("net usersidlist\n"
5414 : "\tprints out a list of all users the running winbind knows\n"
5415 : "\tabout, together with all their SIDs. This is used as\n"
5416 : "\tinput to the 'net rpc share allowedusers' command.\n\n"));
5417 :
5418 0 : net_common_flags_usage(c, argc, argv);
5419 0 : return -1;
5420 : }
5421 :
5422 : /**
5423 : * 'net rpc share' entrypoint.
5424 : * @param argc Standard main() style argc.
5425 : * @param argv Standard main() style argv. Initial components are already
5426 : * stripped.
5427 : **/
5428 :
5429 0 : int net_rpc_share(struct net_context *c, int argc, const char **argv)
5430 : {
5431 : NET_API_STATUS status;
5432 :
5433 0 : struct functable func[] = {
5434 : {
5435 : "add",
5436 : rpc_share_add,
5437 : NET_TRANSPORT_RPC,
5438 : N_("Add share"),
5439 : N_("net rpc share add\n"
5440 : " Add share")
5441 : },
5442 : {
5443 : "delete",
5444 : rpc_share_delete,
5445 : NET_TRANSPORT_RPC,
5446 : N_("Remove share"),
5447 : N_("net rpc share delete\n"
5448 : " Remove share")
5449 : },
5450 : {
5451 : "allowedusers",
5452 : rpc_share_allowedusers,
5453 : NET_TRANSPORT_RPC,
5454 : N_("List allowed users"),
5455 : N_("net rpc share allowedusers\n"
5456 : " List allowed users")
5457 : },
5458 : {
5459 : "migrate",
5460 : rpc_share_migrate,
5461 : NET_TRANSPORT_RPC,
5462 : N_("Migrate share to local server"),
5463 : N_("net rpc share migrate\n"
5464 : " Migrate share to local server")
5465 : },
5466 : {
5467 : "list",
5468 : rpc_share_list,
5469 : NET_TRANSPORT_RPC,
5470 : N_("List shares"),
5471 : N_("net rpc share list\n"
5472 : " List shares")
5473 : },
5474 : {NULL, NULL, 0, NULL, NULL}
5475 : };
5476 :
5477 0 : status = libnetapi_net_init(&c->netapi_ctx);
5478 0 : if (status != 0) {
5479 0 : return -1;
5480 : }
5481 :
5482 0 : status = libnetapi_set_creds(c->netapi_ctx, c->creds);
5483 0 : if (status != 0) {
5484 0 : return -1;
5485 : }
5486 :
5487 :
5488 0 : if (argc == 0) {
5489 0 : if (c->display_usage) {
5490 0 : d_printf("%s\n%s",
5491 : _("Usage:"),
5492 : _("net rpc share\n"
5493 : " List shares\n"
5494 : " Alias for net rpc share list\n"));
5495 0 : net_display_usage_from_functable(func);
5496 0 : return 0;
5497 : }
5498 :
5499 0 : return rpc_share_list(c, argc, argv);
5500 : }
5501 :
5502 0 : return net_run_function(c, argc, argv, "net rpc share", func);
5503 : }
5504 :
5505 0 : static NTSTATUS rpc_sh_share_list(struct net_context *c,
5506 : TALLOC_CTX *mem_ctx,
5507 : struct rpc_sh_ctx *ctx,
5508 : struct rpc_pipe_client *pipe_hnd,
5509 : int argc, const char **argv)
5510 : {
5511 :
5512 0 : return werror_to_ntstatus(W_ERROR(rpc_share_list(c, argc, argv)));
5513 : }
5514 :
5515 0 : static NTSTATUS rpc_sh_share_add(struct net_context *c,
5516 : TALLOC_CTX *mem_ctx,
5517 : struct rpc_sh_ctx *ctx,
5518 : struct rpc_pipe_client *pipe_hnd,
5519 : int argc, const char **argv)
5520 : {
5521 : NET_API_STATUS status;
5522 0 : uint32_t parm_err = 0;
5523 : struct SHARE_INFO_2 i2;
5524 :
5525 0 : if ((argc < 2) || (argc > 3)) {
5526 0 : d_fprintf(stderr, _("Usage: %s <share> <path> [comment]\n"),
5527 : ctx->whoami);
5528 0 : return NT_STATUS_INVALID_PARAMETER;
5529 : }
5530 :
5531 0 : i2.shi2_netname = argv[0];
5532 0 : i2.shi2_type = STYPE_DISKTREE;
5533 0 : i2.shi2_remark = (argc == 3) ? argv[2] : "";
5534 0 : i2.shi2_permissions = 0;
5535 0 : i2.shi2_max_uses = 0;
5536 0 : i2.shi2_current_uses = 0;
5537 0 : i2.shi2_path = argv[1];
5538 0 : i2.shi2_passwd = NULL;
5539 :
5540 0 : status = NetShareAdd(pipe_hnd->desthost,
5541 : 2,
5542 : (uint8_t *)&i2,
5543 : &parm_err);
5544 :
5545 0 : return werror_to_ntstatus(W_ERROR(status));
5546 : }
5547 :
5548 0 : static NTSTATUS rpc_sh_share_delete(struct net_context *c,
5549 : TALLOC_CTX *mem_ctx,
5550 : struct rpc_sh_ctx *ctx,
5551 : struct rpc_pipe_client *pipe_hnd,
5552 : int argc, const char **argv)
5553 : {
5554 0 : if (argc != 1) {
5555 0 : d_fprintf(stderr, "%s %s <share>\n", _("Usage:"), ctx->whoami);
5556 0 : return NT_STATUS_INVALID_PARAMETER;
5557 : }
5558 :
5559 0 : return werror_to_ntstatus(W_ERROR(NetShareDel(pipe_hnd->desthost, argv[0], 0)));
5560 : }
5561 :
5562 0 : static NTSTATUS rpc_sh_share_info(struct net_context *c,
5563 : TALLOC_CTX *mem_ctx,
5564 : struct rpc_sh_ctx *ctx,
5565 : struct rpc_pipe_client *pipe_hnd,
5566 : int argc, const char **argv)
5567 : {
5568 : union srvsvc_NetShareInfo info;
5569 : WERROR result;
5570 : NTSTATUS status;
5571 0 : struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
5572 :
5573 0 : if (argc != 1) {
5574 0 : d_fprintf(stderr, "%s %s <share>\n", _("Usage:"), ctx->whoami);
5575 0 : return NT_STATUS_INVALID_PARAMETER;
5576 : }
5577 :
5578 0 : status = dcerpc_srvsvc_NetShareGetInfo(b, mem_ctx,
5579 0 : pipe_hnd->desthost,
5580 : argv[0],
5581 : 2,
5582 : &info,
5583 : &result);
5584 0 : if (!NT_STATUS_IS_OK(status)) {
5585 0 : result = ntstatus_to_werror(status);
5586 0 : goto done;
5587 : }
5588 0 : if (!W_ERROR_IS_OK(result)) {
5589 0 : goto done;
5590 : }
5591 :
5592 0 : d_printf(_("Name: %s\n"), info.info2->name);
5593 0 : d_printf(_("Comment: %s\n"), info.info2->comment);
5594 0 : d_printf(_("Path: %s\n"), info.info2->path);
5595 0 : d_printf(_("Password: %s\n"), info.info2->password);
5596 :
5597 0 : done:
5598 0 : return werror_to_ntstatus(result);
5599 : }
5600 :
5601 0 : struct rpc_sh_cmd *net_rpc_share_cmds(struct net_context *c, TALLOC_CTX *mem_ctx,
5602 : struct rpc_sh_ctx *ctx)
5603 : {
5604 : static struct rpc_sh_cmd cmds[] = {
5605 :
5606 : { "list", NULL, &ndr_table_srvsvc, rpc_sh_share_list,
5607 : N_("List available shares") },
5608 :
5609 : { "add", NULL, &ndr_table_srvsvc, rpc_sh_share_add,
5610 : N_("Add a share") },
5611 :
5612 : { "delete", NULL, &ndr_table_srvsvc, rpc_sh_share_delete,
5613 : N_("Delete a share") },
5614 :
5615 : { "info", NULL, &ndr_table_srvsvc, rpc_sh_share_info,
5616 : N_("Get information about a share") },
5617 :
5618 : { NULL, NULL, 0, NULL, NULL }
5619 : };
5620 :
5621 0 : return cmds;
5622 : }
5623 :
5624 : /****************************************************************************/
5625 :
5626 0 : static int rpc_file_usage(struct net_context *c, int argc, const char **argv)
5627 : {
5628 0 : return net_file_usage(c, argc, argv);
5629 : }
5630 :
5631 : /**
5632 : * Close a file on a remote RPC server.
5633 : *
5634 : * @param argc Standard main() style argc.
5635 : * @param argv Standard main() style argv. Initial components are already
5636 : * stripped.
5637 : *
5638 : * @return A shell status integer (0 for success).
5639 : **/
5640 0 : static int rpc_file_close(struct net_context *c, int argc, const char **argv)
5641 : {
5642 0 : if (argc < 1 || c->display_usage) {
5643 0 : return rpc_file_usage(c, argc, argv);
5644 : }
5645 :
5646 0 : return NetFileClose(c->opt_host, atoi(argv[0]));
5647 : }
5648 :
5649 : /**
5650 : * Formatted print of open file info
5651 : *
5652 : * @param r struct FILE_INFO_3 contents
5653 : **/
5654 :
5655 0 : static void display_file_info_3(struct FILE_INFO_3 *r)
5656 : {
5657 0 : d_printf("%-7.1" PRIu32 " %-20.20s 0x%-4.2x %-6.1u %s\n",
5658 : r->fi3_id, r->fi3_username, r->fi3_permissions,
5659 : r->fi3_num_locks, r->fi3_pathname);
5660 0 : }
5661 :
5662 : /**
5663 : * List files for a user on a remote RPC server.
5664 : *
5665 : * @param argc Standard main() style argc.
5666 : * @param argv Standard main() style argv. Initial components are already
5667 : * stripped.
5668 : *
5669 : * @return A shell status integer (0 for success)..
5670 : **/
5671 :
5672 0 : static int rpc_file_user(struct net_context *c, int argc, const char **argv)
5673 : {
5674 : NET_API_STATUS status;
5675 0 : uint32_t preferred_len = 0xffffffff, i;
5676 0 : char *username=NULL;
5677 0 : uint32_t total_entries = 0;
5678 0 : uint32_t entries_read = 0;
5679 0 : uint32_t resume_handle = 0;
5680 0 : struct FILE_INFO_3 *i3 = NULL;
5681 :
5682 0 : if (c->display_usage) {
5683 0 : return rpc_file_usage(c, argc, argv);
5684 : }
5685 :
5686 : /* if argc > 0, must be user command */
5687 0 : if (argc > 0) {
5688 0 : username = smb_xstrdup(argv[0]);
5689 : }
5690 :
5691 0 : status = NetFileEnum(c->opt_host,
5692 : NULL,
5693 : username,
5694 : 3,
5695 : (uint8_t **)(void *)&i3,
5696 : preferred_len,
5697 : &entries_read,
5698 : &total_entries,
5699 : &resume_handle);
5700 :
5701 0 : if (status != 0) {
5702 0 : goto done;
5703 : }
5704 :
5705 : /* Display results */
5706 :
5707 0 : d_printf(_(
5708 : "\nEnumerating open files on remote server:\n\n"
5709 : "\nFileId Opened by Perms Locks Path"
5710 : "\n------ --------- ----- ----- ---- \n"));
5711 0 : for (i = 0; i < entries_read; i++) {
5712 0 : display_file_info_3(&i3[i]);
5713 : }
5714 0 : done:
5715 0 : SAFE_FREE(username);
5716 0 : return status;
5717 : }
5718 :
5719 : /**
5720 : * 'net rpc file' entrypoint.
5721 : * @param argc Standard main() style argc.
5722 : * @param argv Standard main() style argv. Initial components are already
5723 : * stripped.
5724 : **/
5725 :
5726 0 : int net_rpc_file(struct net_context *c, int argc, const char **argv)
5727 : {
5728 : NET_API_STATUS status;
5729 :
5730 0 : struct functable func[] = {
5731 : {
5732 : "close",
5733 : rpc_file_close,
5734 : NET_TRANSPORT_RPC,
5735 : N_("Close opened file"),
5736 : N_("net rpc file close\n"
5737 : " Close opened file")
5738 : },
5739 : {
5740 : "user",
5741 : rpc_file_user,
5742 : NET_TRANSPORT_RPC,
5743 : N_("List files opened by user"),
5744 : N_("net rpc file user\n"
5745 : " List files opened by user")
5746 : },
5747 : #if 0
5748 : {
5749 : "info",
5750 : rpc_file_info,
5751 : NET_TRANSPORT_RPC,
5752 : N_("Display information about opened file"),
5753 : N_("net rpc file info\n"
5754 : " Display information about opened file")
5755 : },
5756 : #endif
5757 : {NULL, NULL, 0, NULL, NULL}
5758 : };
5759 :
5760 0 : status = libnetapi_net_init(&c->netapi_ctx);
5761 0 : if (status != 0) {
5762 0 : return -1;
5763 : }
5764 :
5765 0 : status = libnetapi_set_creds(c->netapi_ctx, c->creds);
5766 0 : if (status != 0) {
5767 0 : return -1;
5768 : }
5769 :
5770 0 : if (argc == 0) {
5771 0 : if (c->display_usage) {
5772 0 : d_printf(_("Usage:\n"));
5773 0 : d_printf(_("net rpc file\n"
5774 : " List opened files\n"));
5775 0 : net_display_usage_from_functable(func);
5776 0 : return 0;
5777 : }
5778 :
5779 0 : return rpc_file_user(c, argc, argv);
5780 : }
5781 :
5782 0 : return net_run_function(c, argc, argv, "net rpc file", func);
5783 : }
5784 :
5785 : /**
5786 : * ABORT the shutdown of a remote RPC Server, over initshutdown pipe.
5787 : *
5788 : * All parameters are provided by the run_rpc_command function, except for
5789 : * argc, argv which are passed through.
5790 : *
5791 : * @param c A net_context structure.
5792 : * @param domain_sid The domain sid acquired from the remote server.
5793 : * @param cli A cli_state connected to the server.
5794 : * @param mem_ctx Talloc context, destroyed on completion of the function.
5795 : * @param argc Standard main() style argc.
5796 : * @param argv Standard main() style argv. Initial components are already
5797 : * stripped.
5798 : *
5799 : * @return Normal NTSTATUS return.
5800 : **/
5801 :
5802 0 : static NTSTATUS rpc_shutdown_abort_internals(struct net_context *c,
5803 : const struct dom_sid *domain_sid,
5804 : const char *domain_name,
5805 : struct cli_state *cli,
5806 : struct rpc_pipe_client *pipe_hnd,
5807 : TALLOC_CTX *mem_ctx,
5808 : int argc,
5809 : const char **argv)
5810 : {
5811 0 : NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
5812 : WERROR result;
5813 0 : struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
5814 :
5815 0 : status = dcerpc_initshutdown_Abort(b, mem_ctx, NULL, &result);
5816 0 : if (!NT_STATUS_IS_OK(status)) {
5817 0 : return status;
5818 : }
5819 0 : if (W_ERROR_IS_OK(result)) {
5820 0 : d_printf(_("\nShutdown successfully aborted\n"));
5821 0 : DEBUG(5,("cmd_shutdown_abort: query succeeded\n"));
5822 : } else
5823 0 : DEBUG(5,("cmd_shutdown_abort: query failed\n"));
5824 :
5825 0 : return werror_to_ntstatus(result);
5826 : }
5827 :
5828 : /**
5829 : * ABORT the shutdown of a remote RPC Server, over winreg pipe.
5830 : *
5831 : * All parameters are provided by the run_rpc_command function, except for
5832 : * argc, argv which are passed through.
5833 : *
5834 : * @param c A net_context structure.
5835 : * @param domain_sid The domain sid acquired from the remote server.
5836 : * @param cli A cli_state connected to the server.
5837 : * @param mem_ctx Talloc context, destroyed on completion of the function.
5838 : * @param argc Standard main() style argc.
5839 : * @param argv Standard main() style argv. Initial components are already
5840 : * stripped.
5841 : *
5842 : * @return Normal NTSTATUS return.
5843 : **/
5844 :
5845 0 : static NTSTATUS rpc_reg_shutdown_abort_internals(struct net_context *c,
5846 : const struct dom_sid *domain_sid,
5847 : const char *domain_name,
5848 : struct cli_state *cli,
5849 : struct rpc_pipe_client *pipe_hnd,
5850 : TALLOC_CTX *mem_ctx,
5851 : int argc,
5852 : const char **argv)
5853 : {
5854 0 : NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
5855 : WERROR werr;
5856 0 : struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
5857 :
5858 0 : result = dcerpc_winreg_AbortSystemShutdown(b, mem_ctx, NULL, &werr);
5859 :
5860 0 : if (!NT_STATUS_IS_OK(result)) {
5861 0 : DEBUG(5,("cmd_reg_abort_shutdown: query failed\n"));
5862 0 : return result;
5863 : }
5864 0 : if (W_ERROR_IS_OK(werr)) {
5865 0 : d_printf(_("\nShutdown successfully aborted\n"));
5866 0 : DEBUG(5,("cmd_reg_abort_shutdown: query succeeded\n"));
5867 : } else
5868 0 : DEBUG(5,("cmd_reg_abort_shutdown: query failed\n"));
5869 :
5870 0 : return werror_to_ntstatus(werr);
5871 : }
5872 :
5873 : /**
5874 : * ABORT the shutdown of a remote RPC server.
5875 : *
5876 : * @param argc Standard main() style argc.
5877 : * @param argv Standard main() style argv. Initial components are already
5878 : * stripped.
5879 : *
5880 : * @return A shell status integer (0 for success).
5881 : **/
5882 :
5883 0 : static int rpc_shutdown_abort(struct net_context *c, int argc,
5884 : const char **argv)
5885 : {
5886 0 : int rc = -1;
5887 :
5888 0 : if (c->display_usage) {
5889 0 : d_printf( "%s\n"
5890 : "net rpc abortshutdown\n"
5891 : " %s\n",
5892 : _("Usage:"),
5893 : _("Abort a scheduled shutdown"));
5894 0 : return 0;
5895 : }
5896 :
5897 0 : rc = run_rpc_command(c, NULL, &ndr_table_initshutdown, 0,
5898 : rpc_shutdown_abort_internals, argc, argv);
5899 :
5900 0 : if (rc == 0)
5901 0 : return rc;
5902 :
5903 0 : DEBUG(1, ("initshutdown pipe didn't work, trying winreg pipe\n"));
5904 :
5905 0 : return run_rpc_command(c, NULL, &ndr_table_winreg, 0,
5906 : rpc_reg_shutdown_abort_internals,
5907 : argc, argv);
5908 : }
5909 :
5910 : /**
5911 : * Shut down a remote RPC Server via initshutdown pipe.
5912 : *
5913 : * All parameters are provided by the run_rpc_command function, except for
5914 : * argc, argv which are passed through.
5915 : *
5916 : * @param c A net_context structure.
5917 : * @param domain_sid The domain sid acquired from the remote server.
5918 : * @param cli A cli_state connected to the server.
5919 : * @param mem_ctx Talloc context, destroyed on completion of the function.
5920 : * @param argc Standard main() style argc.
5921 : * @param argv Standard main() style argv. Initial components are already
5922 : * stripped.
5923 : *
5924 : * @return Normal NTSTATUS return.
5925 : **/
5926 :
5927 0 : NTSTATUS rpc_init_shutdown_internals(struct net_context *c,
5928 : const struct dom_sid *domain_sid,
5929 : const char *domain_name,
5930 : struct cli_state *cli,
5931 : struct rpc_pipe_client *pipe_hnd,
5932 : TALLOC_CTX *mem_ctx,
5933 : int argc,
5934 : const char **argv)
5935 : {
5936 0 : NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
5937 : WERROR result;
5938 0 : const char *msg = N_("This machine will be shutdown shortly");
5939 0 : uint32_t timeout = 20;
5940 : struct lsa_StringLarge msg_string;
5941 0 : struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
5942 :
5943 0 : if (c->opt_comment) {
5944 0 : msg = c->opt_comment;
5945 : }
5946 0 : if (c->opt_timeout) {
5947 0 : timeout = c->opt_timeout;
5948 : }
5949 :
5950 0 : msg_string.string = msg;
5951 :
5952 : /* create an entry */
5953 0 : status = dcerpc_initshutdown_Init(b, mem_ctx, NULL,
5954 0 : &msg_string, timeout, c->opt_force, c->opt_reboot,
5955 : &result);
5956 0 : if (!NT_STATUS_IS_OK(status)) {
5957 0 : return status;
5958 : }
5959 0 : if (W_ERROR_IS_OK(result)) {
5960 0 : d_printf(_("\nShutdown of remote machine succeeded\n"));
5961 0 : DEBUG(5,("Shutdown of remote machine succeeded\n"));
5962 : } else {
5963 0 : DEBUG(1,("Shutdown of remote machine failed!\n"));
5964 : }
5965 0 : return werror_to_ntstatus(result);
5966 : }
5967 :
5968 : /**
5969 : * Shut down a remote RPC Server via winreg pipe.
5970 : *
5971 : * All parameters are provided by the run_rpc_command function, except for
5972 : * argc, argv which are passed through.
5973 : *
5974 : * @param c A net_context structure.
5975 : * @param domain_sid The domain sid acquired from the remote server.
5976 : * @param cli A cli_state connected to the server.
5977 : * @param mem_ctx Talloc context, destroyed on completion of the function.
5978 : * @param argc Standard main() style argc.
5979 : * @param argv Standard main() style argv. Initial components are already
5980 : * stripped.
5981 : *
5982 : * @return Normal NTSTATUS return.
5983 : **/
5984 :
5985 0 : NTSTATUS rpc_reg_shutdown_internals(struct net_context *c,
5986 : const struct dom_sid *domain_sid,
5987 : const char *domain_name,
5988 : struct cli_state *cli,
5989 : struct rpc_pipe_client *pipe_hnd,
5990 : TALLOC_CTX *mem_ctx,
5991 : int argc,
5992 : const char **argv)
5993 : {
5994 0 : const char *msg = N_("This machine will be shutdown shortly");
5995 0 : uint32_t timeout = 20;
5996 : struct lsa_StringLarge msg_string;
5997 : NTSTATUS result;
5998 : WERROR werr;
5999 0 : struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
6000 :
6001 0 : if (c->opt_comment) {
6002 0 : msg = c->opt_comment;
6003 : }
6004 0 : msg_string.string = msg;
6005 :
6006 0 : if (c->opt_timeout) {
6007 0 : timeout = c->opt_timeout;
6008 : }
6009 :
6010 : /* create an entry */
6011 0 : result = dcerpc_winreg_InitiateSystemShutdown(b, mem_ctx, NULL,
6012 0 : &msg_string, timeout, c->opt_force, c->opt_reboot,
6013 : &werr);
6014 0 : if (!NT_STATUS_IS_OK(result)) {
6015 0 : d_fprintf(stderr, "\nShutdown of remote machine failed\n");
6016 0 : return result;
6017 : }
6018 :
6019 0 : if (W_ERROR_IS_OK(werr)) {
6020 0 : d_printf(_("\nShutdown of remote machine succeeded\n"));
6021 : } else {
6022 0 : d_fprintf(stderr, "\nShutdown of remote machine failed\n");
6023 0 : if ( W_ERROR_EQUAL(werr, WERR_MACHINE_LOCKED) )
6024 0 : d_fprintf(stderr, "\nMachine locked, use -f switch to force\n");
6025 : else
6026 0 : d_fprintf(stderr, "\nresult was: %s\n", win_errstr(werr));
6027 : }
6028 :
6029 0 : return werror_to_ntstatus(werr);
6030 : }
6031 :
6032 : /**
6033 : * Shut down a remote RPC server.
6034 : *
6035 : * @param argc Standard main() style argc.
6036 : * @param argv Standard main() style argv. Initial components are already
6037 : * stripped.
6038 : *
6039 : * @return A shell status integer (0 for success).
6040 : **/
6041 :
6042 0 : static int rpc_shutdown(struct net_context *c, int argc, const char **argv)
6043 : {
6044 0 : int rc = -1;
6045 :
6046 0 : if (c->display_usage) {
6047 0 : d_printf( "%s\n"
6048 : "net rpc shutdown\n"
6049 : " %s\n",
6050 : _("Usage:"),
6051 : _("Shut down a remote RPC server"));
6052 0 : return 0;
6053 : }
6054 :
6055 0 : rc = run_rpc_command(c, NULL, &ndr_table_initshutdown, 0,
6056 : rpc_init_shutdown_internals, argc, argv);
6057 :
6058 0 : if (rc) {
6059 0 : DEBUG(1, ("initshutdown pipe failed, trying winreg pipe\n"));
6060 0 : rc = run_rpc_command(c, NULL, &ndr_table_winreg, 0,
6061 : rpc_reg_shutdown_internals, argc, argv);
6062 : }
6063 :
6064 0 : return rc;
6065 : }
6066 :
6067 : /***************************************************************************
6068 : NT Domain trusts code (i.e. 'net rpc trustdom' functionality)
6069 : ***************************************************************************/
6070 :
6071 : /**
6072 : * Add interdomain trust account to the RPC server.
6073 : * All parameters (except for argc and argv) are passed by run_rpc_command
6074 : * function.
6075 : *
6076 : * @param c A net_context structure.
6077 : * @param domain_sid The domain sid acquired from the server.
6078 : * @param cli A cli_state connected to the server.
6079 : * @param mem_ctx Talloc context, destroyed on completion of the function.
6080 : * @param argc Standard main() style argc.
6081 : * @param argv Standard main() style argv. Initial components are already
6082 : * stripped.
6083 : *
6084 : * @return normal NTSTATUS return code.
6085 : */
6086 :
6087 0 : static NTSTATUS rpc_trustdom_add_internals(struct net_context *c,
6088 : const struct dom_sid *domain_sid,
6089 : const char *domain_name,
6090 : struct cli_state *cli,
6091 : struct rpc_pipe_client *pipe_hnd,
6092 : TALLOC_CTX *mem_ctx,
6093 : int argc,
6094 : const char **argv)
6095 : {
6096 : struct policy_handle connect_pol, domain_pol, user_pol;
6097 : NTSTATUS status, result;
6098 : char *acct_name;
6099 : struct lsa_String lsa_acct_name;
6100 : uint32_t acb_info;
6101 0 : uint32_t acct_flags=0;
6102 : uint32_t user_rid;
6103 0 : uint32_t access_granted = 0;
6104 : union samr_UserInfo info;
6105 : unsigned int orig_timeout;
6106 0 : struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
6107 0 : DATA_BLOB session_key = data_blob_null;
6108 0 : TALLOC_CTX *frame = NULL;
6109 :
6110 0 : if (argc != 2) {
6111 0 : d_printf("%s\n%s",
6112 : _("Usage:"),
6113 : _(" net rpc trustdom add <domain_name> "
6114 : "<trust password>\n"));
6115 0 : return NT_STATUS_INVALID_PARAMETER;
6116 : }
6117 :
6118 0 : frame = talloc_stackframe();
6119 :
6120 : /*
6121 : * Make valid trusting domain account (ie. uppercased and with '$' appended)
6122 : */
6123 :
6124 0 : if (asprintf(&acct_name, "%s$", argv[0]) < 0) {
6125 0 : status = NT_STATUS_NO_MEMORY;
6126 : }
6127 :
6128 0 : if (!strupper_m(acct_name)) {
6129 0 : status = NT_STATUS_INVALID_PARAMETER;
6130 0 : goto done;
6131 : }
6132 :
6133 0 : init_lsa_String(&lsa_acct_name, acct_name);
6134 :
6135 0 : status = cli_get_session_key(frame, pipe_hnd, &session_key);
6136 0 : if (!NT_STATUS_IS_OK(status)) {
6137 0 : DEBUG(0,("Error getting session_key of SAM pipe. Error was %s\n",
6138 : nt_errstr(status)));
6139 0 : goto done;
6140 : }
6141 :
6142 : /* Get samr policy handle */
6143 0 : status = dcerpc_samr_Connect2(b, frame,
6144 0 : pipe_hnd->desthost,
6145 : MAXIMUM_ALLOWED_ACCESS,
6146 : &connect_pol,
6147 : &result);
6148 0 : if (!NT_STATUS_IS_OK(status)) {
6149 0 : goto done;
6150 : }
6151 0 : if (!NT_STATUS_IS_OK(result)) {
6152 0 : status = result;
6153 0 : goto done;
6154 : }
6155 :
6156 : /* Get domain policy handle */
6157 0 : status = dcerpc_samr_OpenDomain(b, frame,
6158 : &connect_pol,
6159 : MAXIMUM_ALLOWED_ACCESS,
6160 : discard_const_p(struct dom_sid2, domain_sid),
6161 : &domain_pol,
6162 : &result);
6163 0 : if (!NT_STATUS_IS_OK(status)) {
6164 0 : goto done;
6165 : }
6166 0 : if (!NT_STATUS_IS_OK(result)) {
6167 0 : status = result;
6168 0 : goto done;
6169 : }
6170 :
6171 : /* This call can take a long time - allow the server to time out.
6172 : * 35 seconds should do it. */
6173 :
6174 0 : orig_timeout = rpccli_set_timeout(pipe_hnd, 35000);
6175 :
6176 : /* Create trusting domain's account */
6177 0 : acb_info = ACB_NORMAL;
6178 0 : acct_flags = SEC_GENERIC_READ | SEC_GENERIC_WRITE | SEC_GENERIC_EXECUTE |
6179 : SEC_STD_WRITE_DAC | SEC_STD_DELETE |
6180 : SAMR_USER_ACCESS_SET_PASSWORD |
6181 : SAMR_USER_ACCESS_GET_ATTRIBUTES |
6182 : SAMR_USER_ACCESS_SET_ATTRIBUTES;
6183 :
6184 0 : status = dcerpc_samr_CreateUser2(b, frame,
6185 : &domain_pol,
6186 : &lsa_acct_name,
6187 : acb_info,
6188 : acct_flags,
6189 : &user_pol,
6190 : &access_granted,
6191 : &user_rid,
6192 : &result);
6193 0 : if (!NT_STATUS_IS_OK(status)) {
6194 0 : goto done;
6195 : }
6196 : /* And restore our original timeout. */
6197 0 : rpccli_set_timeout(pipe_hnd, orig_timeout);
6198 :
6199 0 : if (!NT_STATUS_IS_OK(result)) {
6200 0 : status = result;
6201 0 : d_printf(_("net rpc trustdom add: create user %s failed %s\n"),
6202 : acct_name, nt_errstr(result));
6203 0 : goto done;
6204 : }
6205 :
6206 : {
6207 : struct samr_CryptPassword crypt_pwd;
6208 :
6209 0 : ZERO_STRUCT(info.info23);
6210 :
6211 0 : status = init_samr_CryptPassword(argv[1],
6212 : &session_key,
6213 : &crypt_pwd);
6214 0 : if (!NT_STATUS_IS_OK(status)) {
6215 0 : goto done;
6216 : }
6217 :
6218 0 : info.info23.info.fields_present = SAMR_FIELD_ACCT_FLAGS |
6219 : SAMR_FIELD_NT_PASSWORD_PRESENT;
6220 0 : info.info23.info.acct_flags = ACB_DOMTRUST;
6221 0 : info.info23.password = crypt_pwd;
6222 :
6223 0 : status = dcerpc_samr_SetUserInfo2(b, frame,
6224 : &user_pol,
6225 : 23,
6226 : &info,
6227 : &result);
6228 0 : if (!NT_STATUS_IS_OK(status)) {
6229 0 : goto done;
6230 : }
6231 :
6232 0 : if (!NT_STATUS_IS_OK(result)) {
6233 0 : status = result;
6234 0 : DEBUG(0,("Could not set trust account password: %s\n",
6235 : nt_errstr(result)));
6236 0 : goto done;
6237 : }
6238 : }
6239 :
6240 0 : status = NT_STATUS_OK;
6241 0 : done:
6242 0 : SAFE_FREE(acct_name);
6243 0 : data_blob_clear_free(&session_key);
6244 0 : TALLOC_FREE(frame);
6245 0 : return status;
6246 : }
6247 :
6248 : /**
6249 : * Create interdomain trust account for a remote domain.
6250 : *
6251 : * @param argc Standard argc.
6252 : * @param argv Standard argv without initial components.
6253 : *
6254 : * @return Integer status (0 means success).
6255 : **/
6256 :
6257 0 : static int rpc_trustdom_add(struct net_context *c, int argc, const char **argv)
6258 : {
6259 0 : if (argc > 0 && !c->display_usage) {
6260 0 : return run_rpc_command(c, NULL, &ndr_table_samr, 0,
6261 : rpc_trustdom_add_internals, argc, argv);
6262 : } else {
6263 0 : d_printf("%s\n%s",
6264 : _("Usage:"),
6265 : _("net rpc trustdom add <domain_name> <trust "
6266 : "password>\n"));
6267 0 : return -1;
6268 : }
6269 : }
6270 :
6271 :
6272 : /**
6273 : * Remove interdomain trust account from the RPC server.
6274 : * All parameters (except for argc and argv) are passed by run_rpc_command
6275 : * function.
6276 : *
6277 : * @param c A net_context structure.
6278 : * @param domain_sid The domain sid acquired from the server.
6279 : * @param cli A cli_state connected to the server.
6280 : * @param mem_ctx Talloc context, destroyed on completion of the function.
6281 : * @param argc Standard main() style argc.
6282 : * @param argv Standard main() style argv. Initial components are already
6283 : * stripped.
6284 : *
6285 : * @return normal NTSTATUS return code.
6286 : */
6287 :
6288 0 : static NTSTATUS rpc_trustdom_del_internals(struct net_context *c,
6289 : const struct dom_sid *domain_sid,
6290 : const char *domain_name,
6291 : struct cli_state *cli,
6292 : struct rpc_pipe_client *pipe_hnd,
6293 : TALLOC_CTX *mem_ctx,
6294 : int argc,
6295 : const char **argv)
6296 : {
6297 : struct policy_handle connect_pol, domain_pol, user_pol;
6298 : NTSTATUS status, result;
6299 : char *acct_name;
6300 : struct dom_sid trust_acct_sid;
6301 : struct samr_Ids user_rids, name_types;
6302 : struct lsa_String lsa_acct_name;
6303 0 : struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
6304 :
6305 0 : if (argc != 1) {
6306 0 : d_printf("%s\n%s",
6307 : _("Usage:"),
6308 : _(" net rpc trustdom del <domain_name>\n"));
6309 0 : return NT_STATUS_INVALID_PARAMETER;
6310 : }
6311 :
6312 : /*
6313 : * Make valid trusting domain account (ie. uppercased and with '$' appended)
6314 : */
6315 0 : acct_name = talloc_asprintf(mem_ctx, "%s$", argv[0]);
6316 :
6317 0 : if (acct_name == NULL)
6318 0 : return NT_STATUS_NO_MEMORY;
6319 :
6320 0 : if (!strupper_m(acct_name)) {
6321 0 : TALLOC_FREE(acct_name);
6322 0 : return NT_STATUS_INVALID_PARAMETER;
6323 : }
6324 :
6325 : /* Get samr policy handle */
6326 0 : status = dcerpc_samr_Connect2(b, mem_ctx,
6327 0 : pipe_hnd->desthost,
6328 : MAXIMUM_ALLOWED_ACCESS,
6329 : &connect_pol,
6330 : &result);
6331 0 : if (!NT_STATUS_IS_OK(status)) {
6332 0 : goto done;
6333 : }
6334 0 : if (!NT_STATUS_IS_OK(result)) {
6335 0 : status = result;
6336 0 : goto done;
6337 : }
6338 :
6339 : /* Get domain policy handle */
6340 0 : status = dcerpc_samr_OpenDomain(b, mem_ctx,
6341 : &connect_pol,
6342 : MAXIMUM_ALLOWED_ACCESS,
6343 : discard_const_p(struct dom_sid2, domain_sid),
6344 : &domain_pol,
6345 : &result);
6346 0 : if (!NT_STATUS_IS_OK(status)) {
6347 0 : goto done;
6348 : }
6349 0 : if (!NT_STATUS_IS_OK(result)) {
6350 0 : status = result;
6351 0 : goto done;
6352 : }
6353 :
6354 0 : init_lsa_String(&lsa_acct_name, acct_name);
6355 :
6356 0 : status = dcerpc_samr_LookupNames(b, mem_ctx,
6357 : &domain_pol,
6358 : 1,
6359 : &lsa_acct_name,
6360 : &user_rids,
6361 : &name_types,
6362 : &result);
6363 0 : if (!NT_STATUS_IS_OK(status)) {
6364 0 : d_printf(_("net rpc trustdom del: LookupNames on user %s "
6365 : "failed %s\n"),
6366 : acct_name, nt_errstr(status));
6367 0 : goto done;
6368 : }
6369 0 : if (!NT_STATUS_IS_OK(result)) {
6370 0 : status = result;
6371 0 : d_printf(_("net rpc trustdom del: LookupNames on user %s "
6372 : "failed %s\n"),
6373 : acct_name, nt_errstr(result) );
6374 0 : goto done;
6375 : }
6376 0 : if (user_rids.count != 1) {
6377 0 : status = NT_STATUS_INVALID_NETWORK_RESPONSE;
6378 0 : goto done;
6379 : }
6380 0 : if (name_types.count != 1) {
6381 0 : status = NT_STATUS_INVALID_NETWORK_RESPONSE;
6382 0 : goto done;
6383 : }
6384 :
6385 0 : status = dcerpc_samr_OpenUser(b, mem_ctx,
6386 : &domain_pol,
6387 : MAXIMUM_ALLOWED_ACCESS,
6388 0 : user_rids.ids[0],
6389 : &user_pol,
6390 : &result);
6391 0 : if (!NT_STATUS_IS_OK(status)) {
6392 0 : d_printf(_("net rpc trustdom del: OpenUser on user %s failed "
6393 : "%s\n"),
6394 : acct_name, nt_errstr(status) );
6395 0 : goto done;
6396 : }
6397 :
6398 0 : if (!NT_STATUS_IS_OK(result)) {
6399 0 : status = result;
6400 0 : d_printf(_("net rpc trustdom del: OpenUser on user %s failed "
6401 : "%s\n"),
6402 : acct_name, nt_errstr(result) );
6403 0 : goto done;
6404 : }
6405 :
6406 : /* append the rid to the domain sid */
6407 0 : if (!sid_compose(&trust_acct_sid, domain_sid, user_rids.ids[0])) {
6408 0 : goto done;
6409 : }
6410 :
6411 : /* remove the sid */
6412 :
6413 0 : status = dcerpc_samr_RemoveMemberFromForeignDomain(b, mem_ctx,
6414 : &user_pol,
6415 : &trust_acct_sid,
6416 : &result);
6417 0 : if (!NT_STATUS_IS_OK(status)) {
6418 0 : d_printf(_("net rpc trustdom del: RemoveMemberFromForeignDomain"
6419 : " on user %s failed %s\n"),
6420 : acct_name, nt_errstr(status));
6421 0 : goto done;
6422 : }
6423 0 : if (!NT_STATUS_IS_OK(result)) {
6424 0 : status = result;
6425 0 : d_printf(_("net rpc trustdom del: RemoveMemberFromForeignDomain"
6426 : " on user %s failed %s\n"),
6427 : acct_name, nt_errstr(result) );
6428 0 : goto done;
6429 : }
6430 :
6431 :
6432 : /* Delete user */
6433 :
6434 0 : status = dcerpc_samr_DeleteUser(b, mem_ctx,
6435 : &user_pol,
6436 : &result);
6437 0 : if (!NT_STATUS_IS_OK(status)) {
6438 0 : d_printf(_("net rpc trustdom del: DeleteUser on user %s failed "
6439 : "%s\n"),
6440 : acct_name, nt_errstr(status));
6441 0 : goto done;
6442 : }
6443 :
6444 0 : if (!NT_STATUS_IS_OK(result)) {
6445 0 : result = status;
6446 0 : d_printf(_("net rpc trustdom del: DeleteUser on user %s failed "
6447 : "%s\n"),
6448 : acct_name, nt_errstr(result) );
6449 0 : goto done;
6450 : }
6451 :
6452 0 : if (!NT_STATUS_IS_OK(result)) {
6453 0 : d_printf(_("Could not set trust account password: %s\n"),
6454 : nt_errstr(result));
6455 0 : goto done;
6456 : }
6457 :
6458 0 : done:
6459 0 : return status;
6460 : }
6461 :
6462 : /**
6463 : * Delete interdomain trust account for a remote domain.
6464 : *
6465 : * @param argc Standard argc.
6466 : * @param argv Standard argv without initial components.
6467 : *
6468 : * @return Integer status (0 means success).
6469 : **/
6470 :
6471 0 : static int rpc_trustdom_del(struct net_context *c, int argc, const char **argv)
6472 : {
6473 0 : if (argc > 0 && !c->display_usage) {
6474 0 : return run_rpc_command(c, NULL, &ndr_table_samr, 0,
6475 : rpc_trustdom_del_internals, argc, argv);
6476 : } else {
6477 0 : d_printf("%s\n%s",
6478 : _("Usage:"),
6479 : _("net rpc trustdom del <domain>\n"));
6480 0 : return -1;
6481 : }
6482 : }
6483 :
6484 0 : static NTSTATUS rpc_trustdom_get_pdc(struct net_context *c,
6485 : struct cli_state *cli,
6486 : TALLOC_CTX *mem_ctx,
6487 : const char *domain_name)
6488 : {
6489 0 : char *dc_name = NULL;
6490 0 : const char *buffer = NULL;
6491 : struct rpc_pipe_client *netr;
6492 : NTSTATUS status;
6493 : WERROR result;
6494 : struct dcerpc_binding_handle *b;
6495 :
6496 : /* Use NetServerEnum2 */
6497 :
6498 0 : if (cli_get_pdc_name(cli, domain_name, &dc_name)) {
6499 0 : SAFE_FREE(dc_name);
6500 0 : return NT_STATUS_OK;
6501 : }
6502 :
6503 0 : DEBUG(1,("NetServerEnum2 error: Couldn't find primary domain controller\
6504 : for domain %s\n", domain_name));
6505 :
6506 : /* Try netr_GetDcName */
6507 :
6508 0 : status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon,
6509 : &netr);
6510 0 : if (!NT_STATUS_IS_OK(status)) {
6511 0 : return status;
6512 : }
6513 :
6514 0 : b = netr->binding_handle;
6515 :
6516 0 : status = dcerpc_netr_GetDcName(b, mem_ctx,
6517 0 : netr->desthost,
6518 : domain_name,
6519 : &buffer,
6520 : &result);
6521 0 : TALLOC_FREE(netr);
6522 :
6523 0 : if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(result)) {
6524 0 : return status;
6525 : }
6526 :
6527 0 : DEBUG(1,("netr_GetDcName error: Couldn't find primary domain controller\
6528 : for domain %s\n", domain_name));
6529 :
6530 0 : if (!NT_STATUS_IS_OK(status)) {
6531 0 : return status;
6532 : }
6533 :
6534 0 : return werror_to_ntstatus(result);
6535 : }
6536 :
6537 : /**
6538 : * Establish trust relationship to a trusting domain.
6539 : * Interdomain account must already be created on remote PDC.
6540 : *
6541 : * @param c A net_context structure.
6542 : * @param argc Standard argc.
6543 : * @param argv Standard argv without initial components.
6544 : *
6545 : * @return Integer status (0 means success).
6546 : **/
6547 :
6548 0 : static int rpc_trustdom_establish(struct net_context *c, int argc,
6549 : const char **argv)
6550 : {
6551 0 : struct cli_state *cli = NULL;
6552 : struct sockaddr_storage server_ss;
6553 0 : struct rpc_pipe_client *pipe_hnd = NULL;
6554 : struct policy_handle connect_hnd;
6555 : TALLOC_CTX *mem_ctx;
6556 : NTSTATUS nt_status, result;
6557 : struct dom_sid *domain_sid;
6558 :
6559 : char* domain_name;
6560 : char* acct_name;
6561 : fstring pdc_name;
6562 0 : union lsa_PolicyInformation *info = NULL;
6563 : struct dcerpc_binding_handle *b;
6564 :
6565 : /*
6566 : * Connect to \\server\ipc$ as 'our domain' account with password
6567 : */
6568 :
6569 0 : if (argc != 1 || c->display_usage) {
6570 0 : d_printf("%s\n%s",
6571 : _("Usage:"),
6572 : _("net rpc trustdom establish <domain_name>\n"));
6573 0 : return -1;
6574 : }
6575 :
6576 0 : domain_name = smb_xstrdup(argv[0]);
6577 0 : if (!strupper_m(domain_name)) {
6578 0 : SAFE_FREE(domain_name);
6579 0 : return -1;
6580 : }
6581 :
6582 : /* account name used at first is our domain's name with '$' */
6583 0 : if (asprintf(&acct_name, "%s$", lp_workgroup()) == -1) {
6584 0 : return -1;
6585 : }
6586 0 : if (!strupper_m(acct_name)) {
6587 0 : SAFE_FREE(domain_name);
6588 0 : SAFE_FREE(acct_name);
6589 0 : return -1;
6590 : }
6591 :
6592 : /*
6593 : * opt_workgroup will be used by connection functions further,
6594 : * hence it should be set to remote domain name instead of ours
6595 : */
6596 0 : if (c->opt_workgroup) {
6597 0 : c->opt_workgroup = smb_xstrdup(domain_name);
6598 : };
6599 :
6600 0 : c->opt_user_name = acct_name;
6601 0 : c->opt_user_specified = true;
6602 :
6603 : /* find the domain controller */
6604 0 : if (!net_find_pdc(&server_ss, pdc_name, domain_name)) {
6605 0 : DEBUG(0, ("Couldn't find domain controller for domain %s\n", domain_name));
6606 0 : return -1;
6607 : }
6608 :
6609 : /* connect to ipc$ as username/password */
6610 0 : nt_status = connect_to_ipc(c, &cli, &server_ss, pdc_name);
6611 0 : if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT)) {
6612 :
6613 : /* Is it trusting domain account for sure ? */
6614 0 : DEBUG(0, ("Couldn't verify trusting domain account. Error was %s\n",
6615 : nt_errstr(nt_status)));
6616 0 : return -1;
6617 : }
6618 :
6619 : /* store who we connected to */
6620 :
6621 0 : saf_store( domain_name, pdc_name );
6622 :
6623 : /*
6624 : * Connect to \\server\ipc$ again (this time anonymously)
6625 : */
6626 :
6627 0 : nt_status = connect_to_ipc_anonymous(c, &cli, &server_ss,
6628 : (char*)pdc_name);
6629 :
6630 0 : if (NT_STATUS_IS_ERR(nt_status)) {
6631 0 : DEBUG(0, ("Couldn't connect to domain %s controller. Error was %s.\n",
6632 : domain_name, nt_errstr(nt_status)));
6633 0 : return -1;
6634 : }
6635 :
6636 0 : if (!(mem_ctx = talloc_init("establishing trust relationship to "
6637 : "domain %s", domain_name))) {
6638 0 : DEBUG(0, ("talloc_init() failed\n"));
6639 0 : cli_shutdown(cli);
6640 0 : return -1;
6641 : }
6642 :
6643 : /* Make sure we're talking to a proper server */
6644 :
6645 0 : nt_status = rpc_trustdom_get_pdc(c, cli, mem_ctx, domain_name);
6646 0 : if (!NT_STATUS_IS_OK(nt_status)) {
6647 0 : cli_shutdown(cli);
6648 0 : talloc_destroy(mem_ctx);
6649 0 : return -1;
6650 : }
6651 :
6652 : /*
6653 : * Call LsaOpenPolicy and LsaQueryInfo
6654 : */
6655 :
6656 0 : nt_status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc,
6657 : &pipe_hnd);
6658 0 : if (!NT_STATUS_IS_OK(nt_status)) {
6659 0 : DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n", nt_errstr(nt_status) ));
6660 0 : cli_shutdown(cli);
6661 0 : talloc_destroy(mem_ctx);
6662 0 : return -1;
6663 : }
6664 :
6665 0 : b = pipe_hnd->binding_handle;
6666 :
6667 0 : nt_status = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, true, KEY_QUERY_VALUE,
6668 : &connect_hnd);
6669 0 : if (NT_STATUS_IS_ERR(nt_status)) {
6670 0 : DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
6671 : nt_errstr(nt_status)));
6672 0 : cli_shutdown(cli);
6673 0 : talloc_destroy(mem_ctx);
6674 0 : return -1;
6675 : }
6676 :
6677 : /* Querying info level 5 */
6678 :
6679 0 : nt_status = dcerpc_lsa_QueryInfoPolicy(b, mem_ctx,
6680 : &connect_hnd,
6681 : LSA_POLICY_INFO_ACCOUNT_DOMAIN,
6682 : &info,
6683 : &result);
6684 0 : if (NT_STATUS_IS_ERR(nt_status)) {
6685 0 : DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
6686 : nt_errstr(nt_status)));
6687 0 : cli_shutdown(cli);
6688 0 : talloc_destroy(mem_ctx);
6689 0 : return -1;
6690 : }
6691 0 : if (NT_STATUS_IS_ERR(result)) {
6692 0 : DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
6693 : nt_errstr(result)));
6694 0 : cli_shutdown(cli);
6695 0 : talloc_destroy(mem_ctx);
6696 0 : return -1;
6697 : }
6698 :
6699 0 : domain_sid = info->account_domain.sid;
6700 :
6701 : /* There should be actually query info level 3 (following nt serv behaviour),
6702 : but I still don't know if it's _really_ necessary */
6703 :
6704 : /*
6705 : * Store the password in secrets db
6706 : */
6707 :
6708 0 : if (!pdb_set_trusteddom_pw(domain_name, c->opt_password, domain_sid)) {
6709 0 : DEBUG(0, ("Storing password for trusted domain failed.\n"));
6710 0 : cli_shutdown(cli);
6711 0 : talloc_destroy(mem_ctx);
6712 0 : return -1;
6713 : }
6714 :
6715 : /*
6716 : * Close the pipes and clean up
6717 : */
6718 :
6719 0 : nt_status = dcerpc_lsa_Close(b, mem_ctx, &connect_hnd, &result);
6720 0 : if (NT_STATUS_IS_ERR(nt_status)) {
6721 0 : DEBUG(0, ("Couldn't close LSA pipe. Error was %s\n",
6722 : nt_errstr(nt_status)));
6723 0 : cli_shutdown(cli);
6724 0 : talloc_destroy(mem_ctx);
6725 0 : return -1;
6726 : }
6727 :
6728 0 : cli_shutdown(cli);
6729 :
6730 0 : talloc_destroy(mem_ctx);
6731 :
6732 0 : d_printf(_("Trust to domain %s established\n"), domain_name);
6733 0 : return 0;
6734 : }
6735 :
6736 : /**
6737 : * Revoke trust relationship to the remote domain.
6738 : *
6739 : * @param c A net_context structure.
6740 : * @param argc Standard argc.
6741 : * @param argv Standard argv without initial components.
6742 : *
6743 : * @return Integer status (0 means success).
6744 : **/
6745 :
6746 0 : static int rpc_trustdom_revoke(struct net_context *c, int argc,
6747 : const char **argv)
6748 : {
6749 : char* domain_name;
6750 0 : int rc = -1;
6751 :
6752 0 : if (argc < 1 || c->display_usage) {
6753 0 : d_printf("%s\n%s",
6754 : _("Usage:"),
6755 : _("net rpc trustdom revoke <domain_name>\n"
6756 : " Revoke trust relationship\n"
6757 : " domain_name\tName of domain to revoke trust\n"));
6758 0 : return -1;
6759 : }
6760 :
6761 : /* generate upper cased domain name */
6762 0 : domain_name = smb_xstrdup(argv[0]);
6763 0 : if (!strupper_m(domain_name)) {
6764 0 : SAFE_FREE(domain_name);
6765 0 : return -1;
6766 : }
6767 :
6768 : /* delete password of the trust */
6769 0 : if (!pdb_del_trusteddom_pw(domain_name)) {
6770 0 : DEBUG(0, ("Failed to revoke relationship to the trusted domain %s\n",
6771 : domain_name));
6772 0 : goto done;
6773 : };
6774 :
6775 0 : rc = 0;
6776 0 : done:
6777 0 : SAFE_FREE(domain_name);
6778 0 : return rc;
6779 : }
6780 :
6781 0 : static NTSTATUS rpc_query_domain_sid(struct net_context *c,
6782 : const struct dom_sid *domain_sid,
6783 : const char *domain_name,
6784 : struct cli_state *cli,
6785 : struct rpc_pipe_client *pipe_hnd,
6786 : TALLOC_CTX *mem_ctx,
6787 : int argc,
6788 : const char **argv)
6789 : {
6790 : struct dom_sid_buf sid_str;
6791 0 : d_printf("%s\n", dom_sid_str_buf(domain_sid, &sid_str));
6792 0 : return NT_STATUS_OK;
6793 : }
6794 :
6795 0 : static void print_trusted_domain(struct dom_sid *dom_sid, const char *trusted_dom_name)
6796 : {
6797 : struct dom_sid_buf sid_str;
6798 :
6799 0 : d_printf("%-20s%s\n",
6800 : trusted_dom_name,
6801 : dom_sid_str_buf(dom_sid, &sid_str));
6802 0 : }
6803 :
6804 0 : static NTSTATUS vampire_trusted_domain(struct rpc_pipe_client *pipe_hnd,
6805 : TALLOC_CTX *mem_ctx,
6806 : struct policy_handle *pol,
6807 : struct dom_sid dom_sid,
6808 : const char *trusted_dom_name)
6809 : {
6810 : NTSTATUS nt_status, result;
6811 0 : union lsa_TrustedDomainInfo *info = NULL;
6812 0 : char *cleartextpwd = NULL;
6813 : DATA_BLOB session_key;
6814 0 : DATA_BLOB data = data_blob_null;
6815 0 : struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
6816 :
6817 0 : nt_status = dcerpc_lsa_QueryTrustedDomainInfoBySid(b, mem_ctx,
6818 : pol,
6819 : &dom_sid,
6820 : LSA_TRUSTED_DOMAIN_INFO_PASSWORD,
6821 : &info,
6822 : &result);
6823 0 : if (NT_STATUS_IS_ERR(nt_status)) {
6824 0 : DEBUG(0,("Could not query trusted domain info. Error was %s\n",
6825 : nt_errstr(nt_status)));
6826 0 : goto done;
6827 : }
6828 0 : if (NT_STATUS_IS_ERR(result)) {
6829 0 : nt_status = result;
6830 0 : DEBUG(0,("Could not query trusted domain info. Error was %s\n",
6831 : nt_errstr(result)));
6832 0 : goto done;
6833 : }
6834 :
6835 0 : data = data_blob(info->password.password->data,
6836 : info->password.password->length);
6837 :
6838 0 : nt_status = cli_get_session_key(mem_ctx, pipe_hnd, &session_key);
6839 0 : if (!NT_STATUS_IS_OK(nt_status)) {
6840 0 : DEBUG(0, ("Could not retrieve session key: %s\n", nt_errstr(nt_status)));
6841 0 : goto done;
6842 : }
6843 :
6844 0 : cleartextpwd = sess_decrypt_string(mem_ctx, &data, &session_key);
6845 0 : data_blob_free(&session_key);
6846 :
6847 0 : if (cleartextpwd == NULL) {
6848 0 : DEBUG(0,("retrieved NULL password\n"));
6849 0 : nt_status = NT_STATUS_UNSUCCESSFUL;
6850 0 : goto done;
6851 : }
6852 :
6853 0 : if (!pdb_set_trusteddom_pw(trusted_dom_name, cleartextpwd, &dom_sid)) {
6854 0 : DEBUG(0, ("Storing password for trusted domain failed.\n"));
6855 0 : nt_status = NT_STATUS_UNSUCCESSFUL;
6856 0 : goto done;
6857 : }
6858 :
6859 : #ifdef DEBUG_PASSWORD
6860 : {
6861 : struct dom_sid_buf buf;
6862 0 : DEBUG(100,("successfully vampired trusted domain [%s], "
6863 : "sid: [%s], password: [%s]\n",
6864 : trusted_dom_name,
6865 : dom_sid_str_buf(&dom_sid, &buf),
6866 : cleartextpwd));
6867 : }
6868 : #endif
6869 :
6870 0 : done:
6871 0 : SAFE_FREE(cleartextpwd);
6872 0 : data_blob_free(&data);
6873 :
6874 0 : return nt_status;
6875 : }
6876 :
6877 0 : static int rpc_trustdom_vampire(struct net_context *c, int argc,
6878 : const char **argv)
6879 : {
6880 : /* common variables */
6881 : TALLOC_CTX* mem_ctx;
6882 0 : struct cli_state *cli = NULL;
6883 0 : struct rpc_pipe_client *pipe_hnd = NULL;
6884 : NTSTATUS nt_status, result;
6885 0 : const char *domain_name = NULL;
6886 : struct policy_handle connect_hnd;
6887 0 : union lsa_PolicyInformation *info = NULL;
6888 :
6889 : /* trusted domains listing variables */
6890 0 : unsigned int enum_ctx = 0;
6891 : struct lsa_DomainList dom_list;
6892 : fstring pdc_name;
6893 : struct dcerpc_binding_handle *b;
6894 :
6895 0 : if (c->display_usage) {
6896 0 : d_printf( "%s\n"
6897 : "net rpc trustdom vampire\n"
6898 : " %s\n",
6899 : _("Usage:"),
6900 : _("Vampire trust relationship from remote server"));
6901 0 : return 0;
6902 : }
6903 :
6904 : /*
6905 : * Listing trusted domains (stored in secrets.tdb, if local)
6906 : */
6907 :
6908 0 : mem_ctx = talloc_init("trust relationships vampire");
6909 :
6910 : /*
6911 : * set domain and pdc name to local samba server (default)
6912 : * or to remote one given in command line
6913 : */
6914 :
6915 0 : if (strcasecmp_m(c->opt_workgroup, lp_workgroup())) {
6916 0 : domain_name = c->opt_workgroup;
6917 0 : c->opt_target_workgroup = c->opt_workgroup;
6918 : } else {
6919 0 : fstrcpy(pdc_name, lp_netbios_name());
6920 0 : domain_name = talloc_strdup(mem_ctx, lp_workgroup());
6921 0 : c->opt_target_workgroup = domain_name;
6922 : };
6923 :
6924 : /* open \PIPE\lsarpc and open policy handle */
6925 0 : nt_status = net_make_ipc_connection(c, NET_FLAGS_PDC, &cli);
6926 0 : if (!NT_STATUS_IS_OK(nt_status)) {
6927 0 : DEBUG(0, ("Couldn't connect to domain controller: %s\n",
6928 : nt_errstr(nt_status)));
6929 0 : talloc_destroy(mem_ctx);
6930 0 : return -1;
6931 : };
6932 :
6933 0 : nt_status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc,
6934 : &pipe_hnd);
6935 0 : if (!NT_STATUS_IS_OK(nt_status)) {
6936 0 : DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n",
6937 : nt_errstr(nt_status) ));
6938 0 : cli_shutdown(cli);
6939 0 : talloc_destroy(mem_ctx);
6940 0 : return -1;
6941 : };
6942 :
6943 0 : b = pipe_hnd->binding_handle;
6944 :
6945 0 : nt_status = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, false, KEY_QUERY_VALUE,
6946 : &connect_hnd);
6947 0 : if (NT_STATUS_IS_ERR(nt_status)) {
6948 0 : DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
6949 : nt_errstr(nt_status)));
6950 0 : cli_shutdown(cli);
6951 0 : talloc_destroy(mem_ctx);
6952 0 : return -1;
6953 : };
6954 :
6955 : /* query info level 5 to obtain sid of a domain being queried */
6956 0 : nt_status = dcerpc_lsa_QueryInfoPolicy(b, mem_ctx,
6957 : &connect_hnd,
6958 : LSA_POLICY_INFO_ACCOUNT_DOMAIN,
6959 : &info,
6960 : &result);
6961 :
6962 0 : if (NT_STATUS_IS_ERR(nt_status)) {
6963 0 : DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
6964 : nt_errstr(nt_status)));
6965 0 : cli_shutdown(cli);
6966 0 : talloc_destroy(mem_ctx);
6967 0 : return -1;
6968 : }
6969 0 : if (NT_STATUS_IS_ERR(result)) {
6970 0 : DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
6971 : nt_errstr(result)));
6972 0 : cli_shutdown(cli);
6973 0 : talloc_destroy(mem_ctx);
6974 0 : return -1;
6975 : }
6976 :
6977 : /*
6978 : * Keep calling LsaEnumTrustdom over opened pipe until
6979 : * the end of enumeration is reached
6980 : */
6981 :
6982 0 : d_printf(_("Vampire trusted domains:\n\n"));
6983 :
6984 : do {
6985 : uint32_t i;
6986 :
6987 0 : nt_status = dcerpc_lsa_EnumTrustDom(b, mem_ctx,
6988 : &connect_hnd,
6989 : &enum_ctx,
6990 : &dom_list,
6991 : (uint32_t)-1,
6992 : &result);
6993 0 : if (NT_STATUS_IS_ERR(nt_status)) {
6994 0 : DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
6995 : nt_errstr(nt_status)));
6996 0 : cli_shutdown(cli);
6997 0 : talloc_destroy(mem_ctx);
6998 0 : return -1;
6999 : };
7000 0 : if (NT_STATUS_IS_ERR(result)) {
7001 0 : nt_status = result;
7002 0 : DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
7003 : nt_errstr(result)));
7004 0 : cli_shutdown(cli);
7005 0 : talloc_destroy(mem_ctx);
7006 0 : return -1;
7007 : };
7008 :
7009 :
7010 0 : for (i = 0; i < dom_list.count; i++) {
7011 :
7012 0 : print_trusted_domain(dom_list.domains[i].sid,
7013 0 : dom_list.domains[i].name.string);
7014 :
7015 0 : nt_status = vampire_trusted_domain(pipe_hnd, mem_ctx, &connect_hnd,
7016 0 : *dom_list.domains[i].sid,
7017 0 : dom_list.domains[i].name.string);
7018 0 : if (!NT_STATUS_IS_OK(nt_status)) {
7019 0 : cli_shutdown(cli);
7020 0 : talloc_destroy(mem_ctx);
7021 0 : return -1;
7022 : }
7023 : };
7024 :
7025 : /*
7026 : * in case of no trusted domains say something rather
7027 : * than just display blank line
7028 : */
7029 0 : if (!dom_list.count) d_printf(_("none\n"));
7030 :
7031 0 : } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
7032 :
7033 : /* close this connection before doing next one */
7034 0 : nt_status = dcerpc_lsa_Close(b, mem_ctx, &connect_hnd, &result);
7035 0 : if (NT_STATUS_IS_ERR(nt_status)) {
7036 0 : DEBUG(0, ("Couldn't properly close lsa policy handle. Error was %s\n",
7037 : nt_errstr(nt_status)));
7038 0 : cli_shutdown(cli);
7039 0 : talloc_destroy(mem_ctx);
7040 0 : return -1;
7041 : };
7042 :
7043 : /* close lsarpc pipe and connection to IPC$ */
7044 0 : cli_shutdown(cli);
7045 :
7046 0 : talloc_destroy(mem_ctx);
7047 0 : return 0;
7048 : }
7049 :
7050 0 : static int rpc_trustdom_list(struct net_context *c, int argc, const char **argv)
7051 : {
7052 : /* common variables */
7053 : TALLOC_CTX* mem_ctx;
7054 0 : struct cli_state *cli = NULL, *remote_cli = NULL;
7055 0 : struct rpc_pipe_client *pipe_hnd = NULL;
7056 : NTSTATUS nt_status, result;
7057 0 : const char *domain_name = NULL;
7058 : struct dom_sid *queried_dom_sid;
7059 : int ascii_dom_name_len;
7060 : struct policy_handle connect_hnd;
7061 0 : union lsa_PolicyInformation *info = NULL;
7062 0 : struct dcerpc_binding_handle *b = NULL;
7063 :
7064 : /* trusted domains listing variables */
7065 0 : unsigned int num_domains, enum_ctx = 0;
7066 : uint32_t i;
7067 : struct lsa_DomainList dom_list;
7068 : fstring pdc_name;
7069 : bool found_domain;
7070 :
7071 : /* trusting domains listing variables */
7072 : struct policy_handle domain_hnd;
7073 0 : struct samr_SamArray *trusts = NULL;
7074 :
7075 0 : if (c->display_usage) {
7076 0 : d_printf( "%s\n"
7077 : "net rpc trustdom list\n"
7078 : " %s\n",
7079 : _("Usage:"),
7080 : _("List incoming and outgoing trust relationships"));
7081 0 : return 0;
7082 : }
7083 :
7084 : /*
7085 : * Listing trusted domains (stored in secrets.tdb, if local)
7086 : */
7087 :
7088 0 : mem_ctx = talloc_init("trust relationships listing");
7089 :
7090 : /*
7091 : * set domain and pdc name to local samba server (default)
7092 : * or to remote one given in command line
7093 : */
7094 :
7095 0 : if (strcasecmp_m(c->opt_workgroup, lp_workgroup())) {
7096 0 : domain_name = c->opt_workgroup;
7097 0 : c->opt_target_workgroup = c->opt_workgroup;
7098 : } else {
7099 0 : fstrcpy(pdc_name, lp_netbios_name());
7100 0 : domain_name = talloc_strdup(mem_ctx, lp_workgroup());
7101 0 : c->opt_target_workgroup = domain_name;
7102 : };
7103 :
7104 : /* open \PIPE\lsarpc and open policy handle */
7105 0 : nt_status = net_make_ipc_connection(c, NET_FLAGS_PDC, &cli);
7106 0 : if (!NT_STATUS_IS_OK(nt_status)) {
7107 0 : DEBUG(0, ("Couldn't connect to domain controller: %s\n",
7108 : nt_errstr(nt_status)));
7109 0 : talloc_destroy(mem_ctx);
7110 0 : return -1;
7111 : };
7112 :
7113 0 : nt_status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc,
7114 : &pipe_hnd);
7115 0 : if (!NT_STATUS_IS_OK(nt_status)) {
7116 0 : DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n",
7117 : nt_errstr(nt_status) ));
7118 0 : cli_shutdown(cli);
7119 0 : talloc_destroy(mem_ctx);
7120 0 : return -1;
7121 : };
7122 :
7123 0 : b = pipe_hnd->binding_handle;
7124 :
7125 0 : nt_status = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, false, KEY_QUERY_VALUE,
7126 : &connect_hnd);
7127 0 : if (NT_STATUS_IS_ERR(nt_status)) {
7128 0 : DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
7129 : nt_errstr(nt_status)));
7130 0 : cli_shutdown(cli);
7131 0 : talloc_destroy(mem_ctx);
7132 0 : return -1;
7133 : };
7134 :
7135 : /* query info level 5 to obtain sid of a domain being queried */
7136 0 : nt_status = dcerpc_lsa_QueryInfoPolicy(b, mem_ctx,
7137 : &connect_hnd,
7138 : LSA_POLICY_INFO_ACCOUNT_DOMAIN,
7139 : &info,
7140 : &result);
7141 :
7142 0 : if (NT_STATUS_IS_ERR(nt_status)) {
7143 0 : DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
7144 : nt_errstr(nt_status)));
7145 0 : cli_shutdown(cli);
7146 0 : talloc_destroy(mem_ctx);
7147 0 : return -1;
7148 : }
7149 0 : if (NT_STATUS_IS_ERR(result)) {
7150 0 : DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
7151 : nt_errstr(result)));
7152 0 : cli_shutdown(cli);
7153 0 : talloc_destroy(mem_ctx);
7154 0 : return -1;
7155 : }
7156 :
7157 0 : queried_dom_sid = info->account_domain.sid;
7158 :
7159 : /*
7160 : * Keep calling LsaEnumTrustdom over opened pipe until
7161 : * the end of enumeration is reached
7162 : */
7163 :
7164 0 : d_printf(_("Trusted domains list:\n\n"));
7165 :
7166 0 : found_domain = false;
7167 :
7168 : do {
7169 0 : nt_status = dcerpc_lsa_EnumTrustDom(b, mem_ctx,
7170 : &connect_hnd,
7171 : &enum_ctx,
7172 : &dom_list,
7173 : (uint32_t)-1,
7174 : &result);
7175 0 : if (NT_STATUS_IS_ERR(nt_status)) {
7176 0 : DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
7177 : nt_errstr(nt_status)));
7178 0 : cli_shutdown(cli);
7179 0 : talloc_destroy(mem_ctx);
7180 0 : return -1;
7181 : };
7182 0 : if (NT_STATUS_IS_ERR(result)) {
7183 0 : DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
7184 : nt_errstr(result)));
7185 0 : cli_shutdown(cli);
7186 0 : talloc_destroy(mem_ctx);
7187 0 : return -1;
7188 : };
7189 :
7190 :
7191 0 : for (i = 0; i < dom_list.count; i++) {
7192 0 : print_trusted_domain(dom_list.domains[i].sid,
7193 0 : dom_list.domains[i].name.string);
7194 0 : found_domain = true;
7195 : };
7196 :
7197 :
7198 0 : } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
7199 :
7200 : /*
7201 : * in case of no trusted domains say something rather
7202 : * than just display blank line
7203 : */
7204 0 : if (!found_domain) {
7205 0 : d_printf(_("none\n"));
7206 : }
7207 :
7208 : /* close this connection before doing next one */
7209 0 : nt_status = dcerpc_lsa_Close(b, mem_ctx, &connect_hnd, &result);
7210 0 : if (NT_STATUS_IS_ERR(nt_status)) {
7211 0 : DEBUG(0, ("Couldn't properly close lsa policy handle. Error was %s\n",
7212 : nt_errstr(nt_status)));
7213 0 : cli_shutdown(cli);
7214 0 : talloc_destroy(mem_ctx);
7215 0 : return -1;
7216 : };
7217 :
7218 0 : TALLOC_FREE(pipe_hnd);
7219 :
7220 : /*
7221 : * Listing trusting domains (stored in passdb backend, if local)
7222 : */
7223 :
7224 0 : d_printf(_("\nTrusting domains list:\n\n"));
7225 :
7226 : /*
7227 : * Open \PIPE\samr and get needed policy handles
7228 : */
7229 0 : nt_status = cli_rpc_pipe_open_noauth(cli, &ndr_table_samr,
7230 : &pipe_hnd);
7231 0 : if (!NT_STATUS_IS_OK(nt_status)) {
7232 0 : DEBUG(0, ("Could not initialise samr pipe. Error was %s\n", nt_errstr(nt_status)));
7233 0 : cli_shutdown(cli);
7234 0 : talloc_destroy(mem_ctx);
7235 0 : return -1;
7236 : };
7237 :
7238 0 : b = pipe_hnd->binding_handle;
7239 :
7240 : /* SamrConnect2 */
7241 0 : nt_status = dcerpc_samr_Connect2(b, mem_ctx,
7242 0 : pipe_hnd->desthost,
7243 : SAMR_ACCESS_LOOKUP_DOMAIN,
7244 : &connect_hnd,
7245 : &result);
7246 0 : if (!NT_STATUS_IS_OK(nt_status)) {
7247 0 : DEBUG(0, ("Couldn't open SAMR policy handle. Error was %s\n",
7248 : nt_errstr(nt_status)));
7249 0 : cli_shutdown(cli);
7250 0 : talloc_destroy(mem_ctx);
7251 0 : return -1;
7252 : };
7253 0 : if (!NT_STATUS_IS_OK(result)) {
7254 0 : nt_status = result;
7255 0 : DEBUG(0, ("Couldn't open SAMR policy handle. Error was %s\n",
7256 : nt_errstr(result)));
7257 0 : cli_shutdown(cli);
7258 0 : talloc_destroy(mem_ctx);
7259 0 : return -1;
7260 : };
7261 :
7262 : /* SamrOpenDomain - we have to open domain policy handle in order to be
7263 : able to enumerate accounts*/
7264 0 : nt_status = dcerpc_samr_OpenDomain(b, mem_ctx,
7265 : &connect_hnd,
7266 : SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
7267 : queried_dom_sid,
7268 : &domain_hnd,
7269 : &result);
7270 0 : if (!NT_STATUS_IS_OK(nt_status)) {
7271 0 : DEBUG(0, ("Couldn't open domain object. Error was %s\n",
7272 : nt_errstr(nt_status)));
7273 0 : cli_shutdown(cli);
7274 0 : talloc_destroy(mem_ctx);
7275 0 : return -1;
7276 : };
7277 0 : if (!NT_STATUS_IS_OK(result)) {
7278 0 : nt_status = result;
7279 0 : DEBUG(0, ("Couldn't open domain object. Error was %s\n",
7280 : nt_errstr(result)));
7281 0 : cli_shutdown(cli);
7282 0 : talloc_destroy(mem_ctx);
7283 0 : return -1;
7284 : };
7285 :
7286 : /*
7287 : * perform actual enumeration
7288 : */
7289 :
7290 0 : found_domain = false;
7291 :
7292 0 : enum_ctx = 0; /* reset enumeration context from last enumeration */
7293 : do {
7294 :
7295 0 : nt_status = dcerpc_samr_EnumDomainUsers(b, mem_ctx,
7296 : &domain_hnd,
7297 : &enum_ctx,
7298 : ACB_DOMTRUST,
7299 : &trusts,
7300 : 0xffff,
7301 : &num_domains,
7302 : &result);
7303 0 : if (NT_STATUS_IS_ERR(nt_status)) {
7304 0 : DEBUG(0, ("Couldn't enumerate accounts. Error was: %s\n",
7305 : nt_errstr(nt_status)));
7306 0 : cli_shutdown(cli);
7307 0 : talloc_destroy(mem_ctx);
7308 0 : return -1;
7309 : };
7310 0 : if (NT_STATUS_IS_ERR(result)) {
7311 0 : nt_status = result;
7312 0 : DEBUG(0, ("Couldn't enumerate accounts. Error was: %s\n",
7313 : nt_errstr(result)));
7314 0 : cli_shutdown(cli);
7315 0 : talloc_destroy(mem_ctx);
7316 0 : return -1;
7317 : };
7318 :
7319 0 : for (i = 0; i < num_domains; i++) {
7320 :
7321 0 : char *str = discard_const_p(char, trusts->entries[i].name.string);
7322 :
7323 0 : found_domain = true;
7324 :
7325 : /*
7326 : * get each single domain's sid (do we _really_ need this ?):
7327 : * 1) connect to domain's pdc
7328 : * 2) query the pdc for domain's sid
7329 : */
7330 :
7331 : /* get rid of '$' tail */
7332 0 : ascii_dom_name_len = strlen(str);
7333 0 : if (ascii_dom_name_len && ascii_dom_name_len < FSTRING_LEN)
7334 0 : str[ascii_dom_name_len - 1] = '\0';
7335 :
7336 : /* set opt_* variables to remote domain */
7337 0 : if (!strupper_m(str)) {
7338 0 : cli_shutdown(cli);
7339 0 : talloc_destroy(mem_ctx);
7340 0 : return -1;
7341 : }
7342 0 : c->opt_workgroup = talloc_strdup(mem_ctx, str);
7343 0 : c->opt_target_workgroup = c->opt_workgroup;
7344 :
7345 0 : d_printf("%-20s", str);
7346 :
7347 : /* connect to remote domain controller */
7348 0 : nt_status = net_make_ipc_connection(c,
7349 : NET_FLAGS_PDC | NET_FLAGS_ANONYMOUS,
7350 : &remote_cli);
7351 0 : if (NT_STATUS_IS_OK(nt_status)) {
7352 : /* query for domain's sid */
7353 0 : if (run_rpc_command(
7354 : c, remote_cli,
7355 : &ndr_table_lsarpc, 0,
7356 : rpc_query_domain_sid, argc,
7357 : argv))
7358 0 : d_printf(_("strange - couldn't get domain's sid\n"));
7359 :
7360 0 : cli_shutdown(remote_cli);
7361 :
7362 : } else {
7363 0 : d_fprintf(stderr, _("domain controller is not "
7364 : "responding: %s\n"),
7365 : nt_errstr(nt_status));
7366 0 : d_printf(_("couldn't get domain's sid\n"));
7367 : }
7368 : }
7369 :
7370 0 : } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
7371 :
7372 0 : if (!found_domain) {
7373 0 : d_printf("none\n");
7374 : }
7375 :
7376 : /* close opened samr and domain policy handles */
7377 0 : nt_status = dcerpc_samr_Close(b, mem_ctx, &domain_hnd, &result);
7378 0 : if (!NT_STATUS_IS_OK(nt_status)) {
7379 0 : DEBUG(0, ("Couldn't properly close domain policy handle for domain %s\n", domain_name));
7380 : };
7381 :
7382 0 : nt_status = dcerpc_samr_Close(b, mem_ctx, &connect_hnd, &result);
7383 0 : if (!NT_STATUS_IS_OK(nt_status)) {
7384 0 : DEBUG(0, ("Couldn't properly close samr policy handle for domain %s\n", domain_name));
7385 : };
7386 :
7387 : /* close samr pipe and connection to IPC$ */
7388 0 : cli_shutdown(cli);
7389 :
7390 0 : talloc_destroy(mem_ctx);
7391 0 : return 0;
7392 : }
7393 :
7394 : /**
7395 : * Entrypoint for 'net rpc trustdom' code.
7396 : *
7397 : * @param argc Standard argc.
7398 : * @param argv Standard argv without initial components.
7399 : *
7400 : * @return Integer status (0 means success).
7401 : */
7402 :
7403 0 : static int rpc_trustdom(struct net_context *c, int argc, const char **argv)
7404 : {
7405 0 : struct functable func[] = {
7406 : {
7407 : "add",
7408 : rpc_trustdom_add,
7409 : NET_TRANSPORT_RPC,
7410 : N_("Add trusting domain's account"),
7411 : N_("net rpc trustdom add\n"
7412 : " Add trusting domain's account")
7413 : },
7414 : {
7415 : "del",
7416 : rpc_trustdom_del,
7417 : NET_TRANSPORT_RPC,
7418 : N_("Remove trusting domain's account"),
7419 : N_("net rpc trustdom del\n"
7420 : " Remove trusting domain's account")
7421 : },
7422 : {
7423 : "establish",
7424 : rpc_trustdom_establish,
7425 : NET_TRANSPORT_RPC,
7426 : N_("Establish outgoing trust relationship"),
7427 : N_("net rpc trustdom establish\n"
7428 : " Establish outgoing trust relationship")
7429 : },
7430 : {
7431 : "revoke",
7432 : rpc_trustdom_revoke,
7433 : NET_TRANSPORT_RPC,
7434 : N_("Revoke outgoing trust relationship"),
7435 : N_("net rpc trustdom revoke\n"
7436 : " Revoke outgoing trust relationship")
7437 : },
7438 : {
7439 : "list",
7440 : rpc_trustdom_list,
7441 : NET_TRANSPORT_RPC,
7442 : N_("List in- and outgoing domain trusts"),
7443 : N_("net rpc trustdom list\n"
7444 : " List in- and outgoing domain trusts")
7445 : },
7446 : {
7447 : "vampire",
7448 : rpc_trustdom_vampire,
7449 : NET_TRANSPORT_RPC,
7450 : N_("Vampire trusts from remote server"),
7451 : N_("net rpc trustdom vampire\n"
7452 : " Vampire trusts from remote server")
7453 : },
7454 : {NULL, NULL, 0, NULL, NULL}
7455 : };
7456 :
7457 0 : return net_run_function(c, argc, argv, "net rpc trustdom", func);
7458 : }
7459 :
7460 : /**
7461 : * Check if a server will take rpc commands
7462 : * @param flags Type of server to connect to (PDC, DMB, localhost)
7463 : * if the host is not explicitly specified
7464 : * @return bool (true means rpc supported)
7465 : */
7466 0 : bool net_rpc_check(struct net_context *c, unsigned flags)
7467 : {
7468 : struct cli_state *cli;
7469 0 : bool ret = false;
7470 : struct sockaddr_storage server_ss;
7471 0 : char *server_name = NULL;
7472 : NTSTATUS status;
7473 :
7474 : /* flags (i.e. server type) may depend on command */
7475 0 : if (!net_find_server(c, NULL, flags, &server_ss, &server_name))
7476 0 : return false;
7477 :
7478 0 : status = cli_connect_nb(server_name, &server_ss, 0, 0x20,
7479 : lp_netbios_name(), SMB_SIGNING_IPC_DEFAULT,
7480 : 0, &cli);
7481 0 : if (!NT_STATUS_IS_OK(status)) {
7482 0 : if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
7483 0 : DBG_ERR("NetBIOS support disabled, unable to connect\n");
7484 : }
7485 0 : return false;
7486 : }
7487 0 : status = smbXcli_negprot(cli->conn, cli->timeout,
7488 0 : lp_client_min_protocol(),
7489 0 : lp_client_max_protocol());
7490 0 : if (!NT_STATUS_IS_OK(status))
7491 0 : goto done;
7492 0 : if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_NT1)
7493 0 : goto done;
7494 :
7495 0 : ret = true;
7496 0 : done:
7497 0 : cli_shutdown(cli);
7498 0 : return ret;
7499 : }
7500 :
7501 : /* syncronise sam database via samsync rpc calls */
7502 0 : static int rpc_vampire(struct net_context *c, int argc, const char **argv)
7503 : {
7504 0 : struct functable func[] = {
7505 : {
7506 : "keytab",
7507 : rpc_vampire_keytab,
7508 : NET_TRANSPORT_RPC,
7509 : N_("Dump remote SAM database to Kerberos Keytab"),
7510 : N_("net rpc vampire keytab\n"
7511 : " Dump remote SAM database to Kerberos keytab "
7512 : "file")
7513 : },
7514 : {
7515 : "passdb",
7516 : rpc_vampire_passdb,
7517 : NET_TRANSPORT_RPC,
7518 : N_("Dump remote SAM database to passdb"),
7519 : N_("net rpc vampire passdb\n"
7520 : " Dump remote SAM database to passdb")
7521 : },
7522 :
7523 : {NULL, NULL, 0, NULL, NULL}
7524 : };
7525 :
7526 0 : if (argc == 0) {
7527 0 : if (c->display_usage) {
7528 0 : d_printf( "%s\n"
7529 : "net rpc vampire\n"
7530 : " %s\n",
7531 : _("Usage:"),
7532 : _("Vampire remote SAM database"));
7533 0 : return 0;
7534 : }
7535 :
7536 0 : return rpc_vampire_passdb(c, argc, argv);
7537 : }
7538 :
7539 0 : return net_run_function(c, argc, argv, "net rpc vampire", func);
7540 : }
7541 :
7542 : /**
7543 : * Migrate everything from a print server.
7544 : *
7545 : * @param c A net_context structure.
7546 : * @param argc Standard main() style argc.
7547 : * @param argv Standard main() style argv. Initial components are already
7548 : * stripped.
7549 : *
7550 : * @return A shell status integer (0 for success).
7551 : *
7552 : * The order is important !
7553 : * To successfully add drivers the print queues have to exist !
7554 : * Applying ACLs should be the last step, because you're easily locked out.
7555 : *
7556 : **/
7557 0 : static int rpc_printer_migrate_all(struct net_context *c, int argc,
7558 : const char **argv)
7559 : {
7560 : int ret;
7561 :
7562 0 : if (c->display_usage) {
7563 0 : d_printf( "%s\n"
7564 : "net rpc printer migrate all\n"
7565 : " %s\n",
7566 : _("Usage:"),
7567 : _("Migrate everything from a print server"));
7568 0 : return 0;
7569 : }
7570 :
7571 0 : if (!c->opt_host) {
7572 0 : d_printf(_("no server to migrate\n"));
7573 0 : return -1;
7574 : }
7575 :
7576 0 : ret = run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7577 : rpc_printer_migrate_printers_internals, argc,
7578 : argv);
7579 0 : if (ret)
7580 0 : return ret;
7581 :
7582 0 : ret = run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7583 : rpc_printer_migrate_drivers_internals, argc,
7584 : argv);
7585 0 : if (ret)
7586 0 : return ret;
7587 :
7588 0 : ret = run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7589 : rpc_printer_migrate_forms_internals, argc, argv);
7590 0 : if (ret)
7591 0 : return ret;
7592 :
7593 0 : ret = run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7594 : rpc_printer_migrate_settings_internals, argc,
7595 : argv);
7596 0 : if (ret)
7597 0 : return ret;
7598 :
7599 0 : return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7600 : rpc_printer_migrate_security_internals, argc,
7601 : argv);
7602 :
7603 : }
7604 :
7605 : /**
7606 : * Migrate print drivers from a print server.
7607 : *
7608 : * @param c A net_context structure.
7609 : * @param argc Standard main() style argc.
7610 : * @param argv Standard main() style argv. Initial components are already
7611 : * stripped.
7612 : *
7613 : * @return A shell status integer (0 for success).
7614 : **/
7615 0 : static int rpc_printer_migrate_drivers(struct net_context *c, int argc,
7616 : const char **argv)
7617 : {
7618 0 : if (c->display_usage) {
7619 0 : d_printf( "%s\n"
7620 : "net rpc printer migrate drivers\n"
7621 : " %s\n",
7622 : _("Usage:"),
7623 : _("Migrate print-drivers from a print-server"));
7624 0 : return 0;
7625 : }
7626 :
7627 0 : if (!c->opt_host) {
7628 0 : d_printf(_("no server to migrate\n"));
7629 0 : return -1;
7630 : }
7631 :
7632 0 : return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7633 : rpc_printer_migrate_drivers_internals,
7634 : argc, argv);
7635 : }
7636 :
7637 : /**
7638 : * Migrate print-forms from a print-server.
7639 : *
7640 : * @param c A net_context structure.
7641 : * @param argc Standard main() style argc.
7642 : * @param argv Standard main() style argv. Initial components are already
7643 : * stripped.
7644 : *
7645 : * @return A shell status integer (0 for success).
7646 : **/
7647 0 : static int rpc_printer_migrate_forms(struct net_context *c, int argc,
7648 : const char **argv)
7649 : {
7650 0 : if (c->display_usage) {
7651 0 : d_printf( "%s\n"
7652 : "net rpc printer migrate forms\n"
7653 : " %s\n",
7654 : _("Usage:"),
7655 : _("Migrate print-forms from a print-server"));
7656 0 : return 0;
7657 : }
7658 :
7659 0 : if (!c->opt_host) {
7660 0 : d_printf(_("no server to migrate\n"));
7661 0 : return -1;
7662 : }
7663 :
7664 0 : return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7665 : rpc_printer_migrate_forms_internals,
7666 : argc, argv);
7667 : }
7668 :
7669 : /**
7670 : * Migrate printers from a print-server.
7671 : *
7672 : * @param c A net_context structure.
7673 : * @param argc Standard main() style argc.
7674 : * @param argv Standard main() style argv. Initial components are already
7675 : * stripped.
7676 : *
7677 : * @return A shell status integer (0 for success).
7678 : **/
7679 0 : static int rpc_printer_migrate_printers(struct net_context *c, int argc,
7680 : const char **argv)
7681 : {
7682 0 : if (c->display_usage) {
7683 0 : d_printf( "%s\n"
7684 : "net rpc printer migrate printers\n"
7685 : " %s\n",
7686 : _("Usage:"),
7687 : _("Migrate printers from a print-server"));
7688 0 : return 0;
7689 : }
7690 :
7691 0 : if (!c->opt_host) {
7692 0 : d_printf(_("no server to migrate\n"));
7693 0 : return -1;
7694 : }
7695 :
7696 0 : return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7697 : rpc_printer_migrate_printers_internals,
7698 : argc, argv);
7699 : }
7700 :
7701 : /**
7702 : * Migrate printer-ACLs from a print-server
7703 : *
7704 : * @param c A net_context structure.
7705 : * @param argc Standard main() style argc.
7706 : * @param argv Standard main() style argv. Initial components are already
7707 : * stripped.
7708 : *
7709 : * @return A shell status integer (0 for success).
7710 : **/
7711 0 : static int rpc_printer_migrate_security(struct net_context *c, int argc,
7712 : const char **argv)
7713 : {
7714 0 : if (c->display_usage) {
7715 0 : d_printf( "%s\n"
7716 : "net rpc printer migrate security\n"
7717 : " %s\n",
7718 : _("Usage:"),
7719 : _("Migrate printer-ACLs from a print-server"));
7720 0 : return 0;
7721 : }
7722 :
7723 0 : if (!c->opt_host) {
7724 0 : d_printf(_("no server to migrate\n"));
7725 0 : return -1;
7726 : }
7727 :
7728 0 : return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7729 : rpc_printer_migrate_security_internals,
7730 : argc, argv);
7731 : }
7732 :
7733 : /**
7734 : * Migrate printer-settings from a print-server.
7735 : *
7736 : * @param c A net_context structure.
7737 : * @param argc Standard main() style argc.
7738 : * @param argv Standard main() style argv. Initial components are already
7739 : * stripped.
7740 : *
7741 : * @return A shell status integer (0 for success).
7742 : **/
7743 0 : static int rpc_printer_migrate_settings(struct net_context *c, int argc,
7744 : const char **argv)
7745 : {
7746 0 : if (c->display_usage) {
7747 0 : d_printf( "%s\n"
7748 : "net rpc printer migrate settings\n"
7749 : " %s\n",
7750 : _("Usage:"),
7751 : _("Migrate printer-settings from a "
7752 : "print-server"));
7753 0 : return 0;
7754 : }
7755 :
7756 0 : if (!c->opt_host) {
7757 0 : d_printf(_("no server to migrate\n"));
7758 0 : return -1;
7759 : }
7760 :
7761 0 : return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7762 : rpc_printer_migrate_settings_internals,
7763 : argc, argv);
7764 : }
7765 :
7766 : /**
7767 : * 'net rpc printer' entrypoint.
7768 : *
7769 : * @param c A net_context structure.
7770 : * @param argc Standard main() style argc.
7771 : * @param argv Standard main() style argv. Initial components are already
7772 : * stripped.
7773 : **/
7774 :
7775 0 : int rpc_printer_migrate(struct net_context *c, int argc, const char **argv)
7776 : {
7777 :
7778 : /* ouch: when addriver and setdriver are called from within
7779 : rpc_printer_migrate_drivers_internals, the printer-queue already
7780 : *has* to exist */
7781 :
7782 0 : struct functable func[] = {
7783 : {
7784 : "all",
7785 : rpc_printer_migrate_all,
7786 : NET_TRANSPORT_RPC,
7787 : N_("Migrate all from remote to local print server"),
7788 : N_("net rpc printer migrate all\n"
7789 : " Migrate all from remote to local print server")
7790 : },
7791 : {
7792 : "drivers",
7793 : rpc_printer_migrate_drivers,
7794 : NET_TRANSPORT_RPC,
7795 : N_("Migrate drivers to local server"),
7796 : N_("net rpc printer migrate drivers\n"
7797 : " Migrate drivers to local server")
7798 : },
7799 : {
7800 : "forms",
7801 : rpc_printer_migrate_forms,
7802 : NET_TRANSPORT_RPC,
7803 : N_("Migrate froms to local server"),
7804 : N_("net rpc printer migrate forms\n"
7805 : " Migrate froms to local server")
7806 : },
7807 : {
7808 : "printers",
7809 : rpc_printer_migrate_printers,
7810 : NET_TRANSPORT_RPC,
7811 : N_("Migrate printers to local server"),
7812 : N_("net rpc printer migrate printers\n"
7813 : " Migrate printers to local server")
7814 : },
7815 : {
7816 : "security",
7817 : rpc_printer_migrate_security,
7818 : NET_TRANSPORT_RPC,
7819 : N_("Migrate printer ACLs to local server"),
7820 : N_("net rpc printer migrate security\n"
7821 : " Migrate printer ACLs to local server")
7822 : },
7823 : {
7824 : "settings",
7825 : rpc_printer_migrate_settings,
7826 : NET_TRANSPORT_RPC,
7827 : N_("Migrate printer settings to local server"),
7828 : N_("net rpc printer migrate settings\n"
7829 : " Migrate printer settings to local server")
7830 : },
7831 : {NULL, NULL, 0, NULL, NULL}
7832 : };
7833 :
7834 0 : return net_run_function(c, argc, argv, "net rpc printer migrate",func);
7835 : }
7836 :
7837 :
7838 : /**
7839 : * List printers on a remote RPC server.
7840 : *
7841 : * @param c A net_context structure.
7842 : * @param argc Standard main() style argc.
7843 : * @param argv Standard main() style argv. Initial components are already
7844 : * stripped.
7845 : *
7846 : * @return A shell status integer (0 for success).
7847 : **/
7848 0 : static int rpc_printer_list(struct net_context *c, int argc, const char **argv)
7849 : {
7850 0 : if (c->display_usage) {
7851 0 : d_printf( "%s\n"
7852 : "net rpc printer list\n"
7853 : " %s\n",
7854 : _("Usage:"),
7855 : _("List printers on a remote RPC server"));
7856 0 : return 0;
7857 : }
7858 :
7859 0 : return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7860 : rpc_printer_list_internals,
7861 : argc, argv);
7862 : }
7863 :
7864 : /**
7865 : * List printer-drivers on a remote RPC server.
7866 : *
7867 : * @param c A net_context structure.
7868 : * @param argc Standard main() style argc.
7869 : * @param argv Standard main() style argv. Initial components are already
7870 : * stripped.
7871 : *
7872 : * @return A shell status integer (0 for success).
7873 : **/
7874 0 : static int rpc_printer_driver_list(struct net_context *c, int argc,
7875 : const char **argv)
7876 : {
7877 0 : if (c->display_usage) {
7878 0 : d_printf( "%s\n"
7879 : "net rpc printer driver\n"
7880 : " %s\n",
7881 : _("Usage:"),
7882 : _("List printer-drivers on a remote RPC server"));
7883 0 : return 0;
7884 : }
7885 :
7886 0 : return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7887 : rpc_printer_driver_list_internals,
7888 : argc, argv);
7889 : }
7890 :
7891 : /**
7892 : * Publish printer in ADS via MSRPC.
7893 : *
7894 : * @param c A net_context structure.
7895 : * @param argc Standard main() style argc.
7896 : * @param argv Standard main() style argv. Initial components are already
7897 : * stripped.
7898 : *
7899 : * @return A shell status integer (0 for success).
7900 : **/
7901 0 : static int rpc_printer_publish_publish(struct net_context *c, int argc,
7902 : const char **argv)
7903 : {
7904 0 : if (c->display_usage) {
7905 0 : d_printf( "%s\n"
7906 : "net rpc printer publish publish\n"
7907 : " %s\n",
7908 : _("Usage:"),
7909 : _("Publish printer in ADS via MSRPC"));
7910 0 : return 0;
7911 : }
7912 :
7913 0 : return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7914 : rpc_printer_publish_publish_internals,
7915 : argc, argv);
7916 : }
7917 :
7918 : /**
7919 : * Update printer in ADS via MSRPC.
7920 : *
7921 : * @param c A net_context structure.
7922 : * @param argc Standard main() style argc.
7923 : * @param argv Standard main() style argv. Initial components are already
7924 : * stripped.
7925 : *
7926 : * @return A shell status integer (0 for success).
7927 : **/
7928 0 : static int rpc_printer_publish_update(struct net_context *c, int argc, const char **argv)
7929 : {
7930 0 : if (c->display_usage) {
7931 0 : d_printf( "%s\n"
7932 : "net rpc printer publish update\n"
7933 : " %s\n",
7934 : _("Usage:"),
7935 : _("Update printer in ADS via MSRPC"));
7936 0 : return 0;
7937 : }
7938 :
7939 0 : return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7940 : rpc_printer_publish_update_internals,
7941 : argc, argv);
7942 : }
7943 :
7944 : /**
7945 : * UnPublish printer in ADS via MSRPC.
7946 : *
7947 : * @param c A net_context structure.
7948 : * @param argc Standard main() style argc.
7949 : * @param argv Standard main() style argv. Initial components are already
7950 : * stripped.
7951 : *
7952 : * @return A shell status integer (0 for success).
7953 : **/
7954 0 : static int rpc_printer_publish_unpublish(struct net_context *c, int argc,
7955 : const char **argv)
7956 : {
7957 0 : if (c->display_usage) {
7958 0 : d_printf( "%s\n"
7959 : "net rpc printer publish unpublish\n"
7960 : " %s\n",
7961 : _("Usage:\n"),
7962 : _("UnPublish printer in ADS via MSRPC"));
7963 0 : return 0;
7964 : }
7965 :
7966 0 : return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7967 : rpc_printer_publish_unpublish_internals,
7968 : argc, argv);
7969 : }
7970 :
7971 : /**
7972 : * List published printers via MSRPC.
7973 : *
7974 : * @param c A net_context structure.
7975 : * @param argc Standard main() style argc.
7976 : * @param argv Standard main() style argv. Initial components are already
7977 : * stripped.
7978 : *
7979 : * @return A shell status integer (0 for success).
7980 : **/
7981 0 : static int rpc_printer_publish_list(struct net_context *c, int argc,
7982 : const char **argv)
7983 : {
7984 0 : if (c->display_usage) {
7985 0 : d_printf( "%s\n"
7986 : "net rpc printer publish list\n"
7987 : " %s\n",
7988 : _("Usage:"),
7989 : _("List published printers via MSRPC"));
7990 0 : return 0;
7991 : }
7992 :
7993 0 : return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7994 : rpc_printer_publish_list_internals,
7995 : argc, argv);
7996 : }
7997 :
7998 :
7999 : /**
8000 : * Publish printer in ADS.
8001 : *
8002 : * @param c A net_context structure.
8003 : * @param argc Standard main() style argc.
8004 : * @param argv Standard main() style argv. Initial components are already
8005 : * stripped.
8006 : *
8007 : * @return A shell status integer (0 for success).
8008 : **/
8009 0 : static int rpc_printer_publish(struct net_context *c, int argc,
8010 : const char **argv)
8011 : {
8012 :
8013 0 : struct functable func[] = {
8014 : {
8015 : "publish",
8016 : rpc_printer_publish_publish,
8017 : NET_TRANSPORT_RPC,
8018 : N_("Publish printer in AD"),
8019 : N_("net rpc printer publish publish\n"
8020 : " Publish printer in AD")
8021 : },
8022 : {
8023 : "update",
8024 : rpc_printer_publish_update,
8025 : NET_TRANSPORT_RPC,
8026 : N_("Update printer in AD"),
8027 : N_("net rpc printer publish update\n"
8028 : " Update printer in AD")
8029 : },
8030 : {
8031 : "unpublish",
8032 : rpc_printer_publish_unpublish,
8033 : NET_TRANSPORT_RPC,
8034 : N_("Unpublish printer"),
8035 : N_("net rpc printer publish unpublish\n"
8036 : " Unpublish printer")
8037 : },
8038 : {
8039 : "list",
8040 : rpc_printer_publish_list,
8041 : NET_TRANSPORT_RPC,
8042 : N_("List published printers"),
8043 : N_("net rpc printer publish list\n"
8044 : " List published printers")
8045 : },
8046 : {NULL, NULL, 0, NULL, NULL}
8047 : };
8048 :
8049 0 : if (argc == 0) {
8050 0 : if (c->display_usage) {
8051 0 : d_printf(_("Usage:\n"));
8052 0 : d_printf(_("net rpc printer publish\n"
8053 : " List published printers\n"
8054 : " Alias of net rpc printer publish "
8055 : "list\n"));
8056 0 : net_display_usage_from_functable(func);
8057 0 : return 0;
8058 : }
8059 0 : return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
8060 : rpc_printer_publish_list_internals,
8061 : argc, argv);
8062 : }
8063 :
8064 0 : return net_run_function(c, argc, argv, "net rpc printer publish",func);
8065 :
8066 : }
8067 :
8068 :
8069 : /**
8070 : * Display rpc printer help page.
8071 : *
8072 : * @param c A net_context structure.
8073 : * @param argc Standard main() style argc.
8074 : * @param argv Standard main() style argv. Initial components are already
8075 : * stripped.
8076 : **/
8077 0 : int rpc_printer_usage(struct net_context *c, int argc, const char **argv)
8078 : {
8079 0 : d_printf(_("net rpc printer LIST [printer] [misc. options] [targets]\n"
8080 : "\tlists all printers on print-server\n\n"));
8081 0 : d_printf(_("net rpc printer DRIVER [printer] [misc. options] [targets]\n"
8082 : "\tlists all printer-drivers on print-server\n\n"));
8083 0 : d_printf(_("net rpc printer PUBLISH action [printer] [misc. options] [targets]\n"
8084 : "\tpublishes printer settings in Active Directory\n"
8085 : "\taction can be one of PUBLISH, UPDATE, UNPUBLISH or LIST\n\n"));
8086 0 : d_printf(_("net rpc printer MIGRATE PRINTERS [printer] [misc. options] [targets]"
8087 : "\n\tmigrates printers from remote to local server\n\n"));
8088 0 : d_printf(_("net rpc printer MIGRATE SETTINGS [printer] [misc. options] [targets]"
8089 : "\n\tmigrates printer-settings from remote to local server\n\n"));
8090 0 : d_printf(_("net rpc printer MIGRATE DRIVERS [printer] [misc. options] [targets]"
8091 : "\n\tmigrates printer-drivers from remote to local server\n\n"));
8092 0 : d_printf(_("net rpc printer MIGRATE FORMS [printer] [misc. options] [targets]"
8093 : "\n\tmigrates printer-forms from remote to local server\n\n"));
8094 0 : d_printf(_("net rpc printer MIGRATE SECURITY [printer] [misc. options] [targets]"
8095 : "\n\tmigrates printer-ACLs from remote to local server\n\n"));
8096 0 : d_printf(_("net rpc printer MIGRATE ALL [printer] [misc. options] [targets]"
8097 : "\n\tmigrates drivers, forms, queues, settings and acls from\n"
8098 : "\tremote to local print-server\n\n"));
8099 0 : net_common_methods_usage(c, argc, argv);
8100 0 : net_common_flags_usage(c, argc, argv);
8101 0 : d_printf(_(
8102 : "\t-v or --verbose\t\t\tgive verbose output\n"
8103 : "\t --destination\t\tmigration target server (default: localhost)\n"));
8104 :
8105 0 : return -1;
8106 : }
8107 :
8108 : /**
8109 : * 'net rpc printer' entrypoint.
8110 : *
8111 : * @param c A net_context structure.
8112 : * @param argc Standard main() style argc.
8113 : * @param argv Standard main() style argv. Initial components are already
8114 : * stripped.
8115 : **/
8116 0 : int net_rpc_printer(struct net_context *c, int argc, const char **argv)
8117 : {
8118 0 : struct functable func[] = {
8119 : {
8120 : "list",
8121 : rpc_printer_list,
8122 : NET_TRANSPORT_RPC,
8123 : N_("List all printers on print server"),
8124 : N_("net rpc printer list\n"
8125 : " List all printers on print server")
8126 : },
8127 : {
8128 : "migrate",
8129 : rpc_printer_migrate,
8130 : NET_TRANSPORT_RPC,
8131 : N_("Migrate printer to local server"),
8132 : N_("net rpc printer migrate\n"
8133 : " Migrate printer to local server")
8134 : },
8135 : {
8136 : "driver",
8137 : rpc_printer_driver_list,
8138 : NET_TRANSPORT_RPC,
8139 : N_("List printer drivers"),
8140 : N_("net rpc printer driver\n"
8141 : " List printer drivers")
8142 : },
8143 : {
8144 : "publish",
8145 : rpc_printer_publish,
8146 : NET_TRANSPORT_RPC,
8147 : N_("Publish printer in AD"),
8148 : N_("net rpc printer publish\n"
8149 : " Publish printer in AD")
8150 : },
8151 : {NULL, NULL, 0, NULL, NULL}
8152 : };
8153 :
8154 0 : if (argc == 0) {
8155 0 : if (c->display_usage) {
8156 0 : d_printf(_("Usage:\n"));
8157 0 : d_printf(_("net rpc printer\n"
8158 : " List printers\n"));
8159 0 : net_display_usage_from_functable(func);
8160 0 : return 0;
8161 : }
8162 0 : return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
8163 : rpc_printer_list_internals,
8164 : argc, argv);
8165 : }
8166 :
8167 0 : return net_run_function(c, argc, argv, "net rpc printer", func);
8168 : }
8169 :
8170 : /**
8171 : * 'net rpc' entrypoint.
8172 : *
8173 : * @param c A net_context structure.
8174 : * @param argc Standard main() style argc.
8175 : * @param argv Standard main() style argv. Initial components are already
8176 : * stripped.
8177 : **/
8178 :
8179 223 : int net_rpc(struct net_context *c, int argc, const char **argv)
8180 : {
8181 : NET_API_STATUS status;
8182 :
8183 223 : struct functable func[] = {
8184 : {
8185 : "audit",
8186 : net_rpc_audit,
8187 : NET_TRANSPORT_RPC,
8188 : N_("Modify global audit settings"),
8189 : N_("net rpc audit\n"
8190 : " Modify global audit settings")
8191 : },
8192 : {
8193 : "info",
8194 : net_rpc_info,
8195 : NET_TRANSPORT_RPC,
8196 : N_("Show basic info about a domain"),
8197 : N_("net rpc info\n"
8198 : " Show basic info about a domain")
8199 : },
8200 : {
8201 : "join",
8202 : net_rpc_join,
8203 : NET_TRANSPORT_RPC,
8204 : N_("Join a domain"),
8205 : N_("net rpc join\n"
8206 : " Join a domain")
8207 : },
8208 : {
8209 : "oldjoin",
8210 : net_rpc_oldjoin,
8211 : NET_TRANSPORT_RPC,
8212 : N_("Join a domain created in server manager"),
8213 : N_("net rpc oldjoin\n"
8214 : " Join a domain created in server manager")
8215 : },
8216 : {
8217 : "testjoin",
8218 : net_rpc_testjoin,
8219 : NET_TRANSPORT_RPC,
8220 : N_("Test that a join is valid"),
8221 : N_("net rpc testjoin\n"
8222 : " Test that a join is valid")
8223 : },
8224 : {
8225 : "user",
8226 : net_rpc_user,
8227 : NET_TRANSPORT_RPC,
8228 : N_("List/modify users"),
8229 : N_("net rpc user\n"
8230 : " List/modify users")
8231 : },
8232 : {
8233 : "password",
8234 : rpc_user_password,
8235 : NET_TRANSPORT_RPC,
8236 : N_("Change a user password"),
8237 : N_("net rpc password\n"
8238 : " Change a user password\n"
8239 : " Alias for net rpc user password")
8240 : },
8241 : {
8242 : "group",
8243 : net_rpc_group,
8244 : NET_TRANSPORT_RPC,
8245 : N_("List/modify groups"),
8246 : N_("net rpc group\n"
8247 : " List/modify groups")
8248 : },
8249 : {
8250 : "share",
8251 : net_rpc_share,
8252 : NET_TRANSPORT_RPC,
8253 : N_("List/modify shares"),
8254 : N_("net rpc share\n"
8255 : " List/modify shares")
8256 : },
8257 : {
8258 : "file",
8259 : net_rpc_file,
8260 : NET_TRANSPORT_RPC,
8261 : N_("List open files"),
8262 : N_("net rpc file\n"
8263 : " List open files")
8264 : },
8265 : {
8266 : "printer",
8267 : net_rpc_printer,
8268 : NET_TRANSPORT_RPC,
8269 : N_("List/modify printers"),
8270 : N_("net rpc printer\n"
8271 : " List/modify printers")
8272 : },
8273 : {
8274 : "changetrustpw",
8275 : net_rpc_changetrustpw,
8276 : NET_TRANSPORT_RPC,
8277 : N_("Change trust account password"),
8278 : N_("net rpc changetrustpw\n"
8279 : " Change trust account password")
8280 : },
8281 : {
8282 : "trustdom",
8283 : rpc_trustdom,
8284 : NET_TRANSPORT_RPC,
8285 : N_("Modify domain trusts"),
8286 : N_("net rpc trustdom\n"
8287 : " Modify domain trusts")
8288 : },
8289 : {
8290 : "abortshutdown",
8291 : rpc_shutdown_abort,
8292 : NET_TRANSPORT_RPC,
8293 : N_("Abort a remote shutdown"),
8294 : N_("net rpc abortshutdown\n"
8295 : " Abort a remote shutdown")
8296 : },
8297 : {
8298 : "shutdown",
8299 : rpc_shutdown,
8300 : NET_TRANSPORT_RPC,
8301 : N_("Shutdown a remote server"),
8302 : N_("net rpc shutdown\n"
8303 : " Shutdown a remote server")
8304 : },
8305 : {
8306 : "vampire",
8307 : rpc_vampire,
8308 : NET_TRANSPORT_RPC,
8309 : N_("Sync a remote NT PDC's data into local passdb"),
8310 : N_("net rpc vampire\n"
8311 : " Sync a remote NT PDC's data into local passdb")
8312 : },
8313 : {
8314 : "getsid",
8315 : net_rpc_getsid,
8316 : NET_TRANSPORT_RPC,
8317 : N_("Fetch the domain sid into local secrets.tdb"),
8318 : N_("net rpc getsid\n"
8319 : " Fetch the domain sid into local secrets.tdb")
8320 : },
8321 : {
8322 : "rights",
8323 : net_rpc_rights,
8324 : NET_TRANSPORT_RPC,
8325 : N_("Manage privileges assigned to SID"),
8326 : N_("net rpc rights\n"
8327 : " Manage privileges assigned to SID")
8328 : },
8329 : {
8330 : "service",
8331 : net_rpc_service,
8332 : NET_TRANSPORT_RPC,
8333 : N_("Start/stop/query remote services"),
8334 : N_("net rpc service\n"
8335 : " Start/stop/query remote services")
8336 : },
8337 : {
8338 : "registry",
8339 : net_rpc_registry,
8340 : NET_TRANSPORT_RPC,
8341 : N_("Manage registry hives"),
8342 : N_("net rpc registry\n"
8343 : " Manage registry hives")
8344 : },
8345 : {
8346 : "shell",
8347 : net_rpc_shell,
8348 : NET_TRANSPORT_RPC,
8349 : N_("Open interactive shell on remote server"),
8350 : N_("net rpc shell\n"
8351 : " Open interactive shell on remote server")
8352 : },
8353 : {
8354 : "trust",
8355 : net_rpc_trust,
8356 : NET_TRANSPORT_RPC,
8357 : N_("Manage trusts"),
8358 : N_("net rpc trust\n"
8359 : " Manage trusts")
8360 : },
8361 : {
8362 : "conf",
8363 : net_rpc_conf,
8364 : NET_TRANSPORT_RPC,
8365 : N_("Configure a remote samba server"),
8366 : N_("net rpc conf\n"
8367 : " Configure a remote samba server")
8368 : },
8369 : {NULL, NULL, 0, NULL, NULL}
8370 : };
8371 :
8372 223 : status = libnetapi_net_init(&c->netapi_ctx);
8373 223 : if (status != 0) {
8374 0 : return -1;
8375 : }
8376 :
8377 223 : status = libnetapi_set_creds(c->netapi_ctx, c->creds);
8378 223 : if (status != 0) {
8379 0 : return -1;
8380 : }
8381 :
8382 223 : return net_run_function(c, argc, argv, "net rpc", func);
8383 : }
|