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