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