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