added useful 'net rpc info' command
[Samba/bb.git] / source3 / utils / net_rpc.c
blobdc50c438d494162cfefd39cdd4bd977050245183
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)
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
21 #include "includes.h"
22 #include "../utils/net.h"
24 extern pstring global_myname;
26 /**
27 * @file net_rpc.c
29 * @brief RPC based subcommands for the 'net' utility.
31 * This file should contain much of the functionality that used to
32 * be found in rpcclient, execpt that the commands should change
33 * less often, and the fucntionality should be sane (the user is not
34 * expected to know a rid/sid before they conduct an operation etc.)
36 * @todo Perhaps eventually these should be split out into a number
37 * of files, as this could get quite big.
38 **/
41 /* A function of this type is passed to the 'run_rpc_command' wrapper */
42 typedef NTSTATUS (*rpc_command_fn)(const DOM_SID *, struct cli_state *, TALLOC_CTX *, int, const char **);
44 /**
45 * Many of the RPC functions need the domain sid. This function gets
46 * it at the start of every run
48 * @param cli A cli_state already connected to the remote machine
50 * @return The Domain SID of the remote machine.
51 **/
53 static DOM_SID *net_get_remote_domain_sid(struct cli_state *cli)
55 DOM_SID *domain_sid;
56 POLICY_HND pol;
57 NTSTATUS result = NT_STATUS_OK;
58 uint32 info_class = 5;
59 fstring domain_name;
60 TALLOC_CTX *mem_ctx;
62 if (!(domain_sid = malloc(sizeof(DOM_SID)))){
63 DEBUG(0,("net_get_remote_domain_sid: malloc returned NULL!\n"));
64 goto error;
67 if (!(mem_ctx=talloc_init()))
69 DEBUG(0,("net_get_remote_domain_sid: talloc_init returned NULL!\n"));
70 goto error;
74 if (!cli_nt_session_open (cli, PIPE_LSARPC)) {
75 fprintf(stderr, "could not initialise lsa pipe\n");
76 goto error;
79 result = cli_lsa_open_policy(cli, mem_ctx, True,
80 SEC_RIGHTS_MAXIMUM_ALLOWED,
81 &pol);
82 if (!NT_STATUS_IS_OK(result)) {
83 goto error;
86 result = cli_lsa_query_info_policy(cli, mem_ctx, &pol, info_class,
87 domain_name, domain_sid);
88 if (!NT_STATUS_IS_OK(result)) {
89 goto error;
92 cli_lsa_close(cli, mem_ctx, &pol);
93 cli_nt_session_close(cli);
94 talloc_destroy(mem_ctx);
96 return domain_sid;
98 error:
99 fprintf(stderr, "could not obtain sid for domain %s\n", cli->domain);
101 if (!NT_STATUS_IS_OK(result)) {
102 fprintf(stderr, "error: %s\n", nt_errstr(result));
105 exit(1);
109 * Run a single RPC command, from start to finish.
111 * @param pipe_name the pipe to connect to (usually a PIPE_ constant)
112 * @param conn_flag a NET_FLAG_ combination. Passed to
113 * net_make_ipc_connection.
114 * @param argc Standard main() style argc
115 * @param argc Standard main() style argv. Initial components are already
116 * stripped
117 * @return A shell status integer (0 for success)
120 static int run_rpc_command(const char *pipe_name, int conn_flags,
121 rpc_command_fn fn,
122 int argc, const char **argv)
124 struct cli_state *cli = net_make_ipc_connection(conn_flags);
125 TALLOC_CTX *mem_ctx;
126 NTSTATUS nt_status;
127 DOM_SID *domain_sid;
129 if (!cli) {
130 return -1;
133 domain_sid = net_get_remote_domain_sid(cli);
135 /* Create mem_ctx */
137 if (!(mem_ctx = talloc_init())) {
138 DEBUG(0, ("talloc_init() failed\n"));
139 cli_shutdown(cli);
140 return -1;
143 if (!cli_nt_session_open(cli, pipe_name)) {
144 DEBUG(0, ("Could not initialise samr pipe\n"));
147 nt_status = fn(domain_sid, cli, mem_ctx, argc, argv);
149 if (!NT_STATUS_IS_OK(nt_status)) {
150 DEBUG(1, ("rpc command function failed! (%s)\n", nt_errstr(nt_status)));
151 } else {
152 DEBUG(5, ("rpc command function succedded\n"));
156 if (cli->nt_pipe_fnum)
157 cli_nt_session_close(cli);
159 talloc_destroy(mem_ctx);
161 return (!NT_STATUS_IS_OK(nt_status));
165 /****************************************************************************/
168 /**
169 * Force a change of the trust acccount password.
171 * All paramaters are provided by the run_rpc_command funcion, except for
172 * argc, argv which are passes through.
174 * @param domain_sid The domain sid aquired from the remote server
175 * @param cli A cli_state connected to the server.
176 * @param mem_ctx Talloc context, destoyed on compleation of the function.
177 * @param argc Standard main() style argc
178 * @param argc Standard main() style argv. Initial components are already
179 * stripped
181 * @return Normal NTSTATUS return.
184 static NTSTATUS rpc_changetrustpw_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx,
185 int argc, const char **argv) {
187 return trust_pw_find_change_and_store_it(cli, mem_ctx, opt_target_workgroup);
190 /**
191 * Force a change of the trust acccount password.
193 * @param argc Standard main() style argc
194 * @param argc Standard main() style argv. Initial components are already
195 * stripped
197 * @return A shell status integer (0 for success)
200 static int rpc_changetrustpw(int argc, const char **argv)
202 return run_rpc_command(PIPE_NETLOGON, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, rpc_changetrustpw_internals,
203 argc, argv);
207 /****************************************************************************/
210 /**
211 * Join a domain, the old way.
213 * This uses 'machinename' as the inital password, and changes it.
215 * The password should be created with 'server manager' or eqiv first.
217 * All paramaters are provided by the run_rpc_command funcion, except for
218 * argc, argv which are passes through.
220 * @param domain_sid The domain sid aquired from the remote server
221 * @param cli A cli_state connected to the server.
222 * @param mem_ctx Talloc context, destoyed on compleation of the function.
223 * @param argc Standard main() style argc
224 * @param argc Standard main() style argv. Initial components are already
225 * stripped
227 * @return Normal NTSTATUS return.
230 static NTSTATUS rpc_join_oldstyle_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx,
231 int argc, const char **argv) {
233 extern pstring global_myname;
234 fstring trust_passwd;
235 unsigned char orig_trust_passwd_hash[16];
237 fstrcpy(trust_passwd, global_myname);
238 strlower(trust_passwd);
241 * Machine names can be 15 characters, but the max length on
242 * a password is 14. --jerry
245 trust_passwd[14] = '\0';
247 E_md4hash( (uchar *)trust_passwd, orig_trust_passwd_hash);
249 return trust_pw_change_and_store_it(cli, mem_ctx, orig_trust_passwd_hash);
252 /**
253 * Join a domain, the old way.
255 * @param argc Standard main() style argc
256 * @param argc Standard main() style argv. Initial components are already
257 * stripped
259 * @return A shell status integer (0 for success)
262 static int net_rpc_join_oldstyle(int argc, const char **argv)
264 return run_rpc_command(PIPE_NETLOGON, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, rpc_join_oldstyle_internals,
265 argc, argv);
268 /**
269 * Basic usage function for 'net rpc join'
270 * @param argc Standard main() style argc
271 * @param argc Standard main() style argv. Initial components are already
272 * stripped
275 static int rpc_join_usage(int argc, const char **argv)
277 d_printf("net rpc join -U <username>[%%password] [options]\n"\
278 "\t to join a domain with admin username & password\n"\
279 "\t\t password will be prompted if none is specified\n");
280 d_printf("net rpc join [options except -U]\n"\
281 "\t to join a domain created in server manager\n\n\n");
283 net_common_flags_usage(argc, argv);
284 return -1;
287 /**
288 * 'net rpc join' entrypoint.
289 * @param argc Standard main() style argc
290 * @param argc Standard main() style argv. Initial components are already
291 * stripped
293 * Main 'net_rpc_join()' (where the admain username/password is used) is
294 * in net_rpc_join.c
295 * Assume if a -U is specified, it's the new style, otherwise it's the
296 * old style
299 int net_rpc_join(int argc, const char **argv)
301 if ((net_rpc_join_oldstyle(argc, argv) == 0))
302 return 0;
304 return net_rpc_join_newstyle(argc, argv);
309 /**
310 * display info about a rpc domain
312 * All paramaters are provided by the run_rpc_command function, except for
313 * argc, argv which are passes through.
315 * @param domain_sid The domain sid acquired from the remote server
316 * @param cli A cli_state connected to the server.
317 * @param mem_ctx Talloc context, destoyed on completion of the function.
318 * @param argc Standard main() style argc
319 * @param argv Standard main() style argv. Initial components are already
320 * stripped
322 * @return Normal NTSTATUS return.
325 static NTSTATUS
326 rpc_info_internals(const DOM_SID *domain_sid, struct cli_state *cli,
327 TALLOC_CTX *mem_ctx, int argc, const char **argv)
329 POLICY_HND connect_pol, domain_pol;
330 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
331 SAM_UNK_CTR ctr;
333 /* Get sam policy handle */
334 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
335 &connect_pol);
336 if (!NT_STATUS_IS_OK(result)) {
337 goto done;
340 /* Get domain policy handle */
341 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
342 MAXIMUM_ALLOWED_ACCESS,
343 domain_sid, &domain_pol);
344 if (!NT_STATUS_IS_OK(result)) {
345 goto done;
348 ZERO_STRUCT(ctr);
349 result = cli_samr_query_dom_info(cli, mem_ctx, &domain_pol,
350 2, &ctr);
351 if (NT_STATUS_IS_OK(result)) {
352 TALLOC_CTX *ctx = talloc_init();
353 d_printf("Domain Name: %s\n", unistr2_tdup(ctx, &ctr.info.inf2.uni_domain));
354 d_printf("Sequence number: %u\n", ctr.info.inf2.seq_num);
355 d_printf("Num users: %u\n", ctr.info.inf2.num_domain_usrs);
356 d_printf("Num domain groups: %u\n", ctr.info.inf2.num_domain_grps);
357 d_printf("Num local groups: %u\n", ctr.info.inf2.num_local_grps);
358 talloc_destroy(ctx);
361 done:
362 return result;
366 /**
367 * 'net rpc info' entrypoint.
368 * @param argc Standard main() style argc
369 * @param argc Standard main() style argv. Initial components are already
370 * stripped
372 int net_rpc_info(int argc, const char **argv)
374 return run_rpc_command(PIPE_SAMR, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC,
375 rpc_info_internals,
376 argc, argv);
382 /****************************************************************************/
385 * Basic usage function for 'net rpc user'
386 * @param argc Standard main() style argc.
387 * @param argv Standard main() style argv. Initial components are already
388 * stripped.
391 static int rpc_user_usage(int argc, const char **argv)
393 return net_help_user(argc, argv);
396 /**
397 * Add a new user to a remote RPC server
399 * All paramaters are provided by the run_rpc_command funcion, except for
400 * argc, argv which are passes through.
402 * @param domain_sid The domain sid acquired from the remote server
403 * @param cli A cli_state connected to the server.
404 * @param mem_ctx Talloc context, destoyed on completion of the function.
405 * @param argc Standard main() style argc
406 * @param argv Standard main() style argv. Initial components are already
407 * stripped
409 * @return Normal NTSTATUS return.
412 static NTSTATUS rpc_user_add_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx,
413 int argc, const char **argv) {
415 POLICY_HND connect_pol, domain_pol, user_pol;
416 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
417 const char *acct_name;
418 uint16 acb_info;
419 uint32 unknown, user_rid;
421 if (argc != 1) {
422 d_printf("User must be specified\n");
423 rpc_user_usage(argc, argv);
424 return NT_STATUS_OK;
427 acct_name = argv[0];
429 /* Get sam policy handle */
431 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
432 &connect_pol);
433 if (!NT_STATUS_IS_OK(result)) {
434 goto done;
437 /* Get domain policy handle */
439 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
440 MAXIMUM_ALLOWED_ACCESS,
441 domain_sid, &domain_pol);
442 if (!NT_STATUS_IS_OK(result)) {
443 goto done;
446 /* Create domain user */
448 acb_info = ACB_NORMAL;
449 unknown = 0xe005000b; /* No idea what this is - a permission mask? */
451 result = cli_samr_create_dom_user(cli, mem_ctx, &domain_pol,
452 acct_name, acb_info, unknown,
453 &user_pol, &user_rid);
454 if (!NT_STATUS_IS_OK(result)) {
455 goto done;
458 done:
459 if (!NT_STATUS_IS_OK(result)) {
460 d_printf("Failed to add user %s - %s\n", acct_name,
461 nt_errstr(result));
462 } else {
463 d_printf("Added user %s\n", acct_name);
465 return result;
468 /**
469 * Add a new user to a remote RPC server
471 * @param argc Standard main() style argc
472 * @param argv Standard main() style argv. Initial components are already
473 * stripped
475 * @return A shell status integer (0 for success)
478 static int rpc_user_add(int argc, const char **argv)
480 return run_rpc_command(PIPE_SAMR, 0, rpc_user_add_internals,
481 argc, argv);
484 /**
485 * Delete a user from a remote RPC server
487 * All paramaters are provided by the run_rpc_command funcion, except for
488 * argc, argv which are passes through.
490 * @param domain_sid The domain sid acquired from the remote server
491 * @param cli A cli_state connected to the server.
492 * @param mem_ctx Talloc context, destoyed on completion of the function.
493 * @param argc Standard main() style argc
494 * @param argv Standard main() style argv. Initial components are already
495 * stripped
497 * @return Normal NTSTATUS return.
500 static NTSTATUS rpc_user_del_internals(const DOM_SID *domain_sid,
501 struct cli_state *cli,
502 TALLOC_CTX *mem_ctx,
503 int argc, const char **argv)
505 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
506 POLICY_HND connect_pol, domain_pol, user_pol;
508 if (argc < 1) {
509 d_printf("User must be specified\n");
510 rpc_user_usage(argc, argv);
511 return NT_STATUS_OK;
513 /* Get sam policy and domain handles */
515 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
516 &connect_pol);
518 if (!NT_STATUS_IS_OK(result)) {
519 goto done;
522 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
523 MAXIMUM_ALLOWED_ACCESS,
524 domain_sid, &domain_pol);
526 if (!NT_STATUS_IS_OK(result)) {
527 goto done;
530 /* Get handle on user */
533 uint32 *user_rids, num_rids, *name_types;
534 uint32 flags = 0x000003e8; /* Unknown */
536 result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol,
537 flags, 1, &argv[0],
538 &num_rids, &user_rids,
539 &name_types);
541 if (!NT_STATUS_IS_OK(result)) {
542 goto done;
545 result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
546 MAXIMUM_ALLOWED_ACCESS,
547 user_rids[0], &user_pol);
549 if (!NT_STATUS_IS_OK(result)) {
550 goto done;
554 /* Delete user */
556 result = cli_samr_delete_dom_user(cli, mem_ctx, &user_pol);
558 if (!NT_STATUS_IS_OK(result)) {
559 goto done;
562 /* Display results */
564 done:
565 return result;
569 /**
570 * Delete a user from a remote RPC server
572 * @param argc Standard main() style argc
573 * @param argv Standard main() style argv. Initial components are already
574 * stripped
576 * @return A shell status integer (0 for success)
579 static int rpc_user_delete(int argc, const char **argv)
581 return run_rpc_command(PIPE_SAMR, 0, rpc_user_del_internals,
582 argc, argv);
585 /**
586 * List user's groups on a remote RPC server
588 * All paramaters are provided by the run_rpc_command funcion, except for
589 * argc, argv which are passes through.
591 * @param domain_sid The domain sid acquired from the remote server
592 * @param cli A cli_state connected to the server.
593 * @param mem_ctx Talloc context, destoyed on completion of the function.
594 * @param argc Standard main() style argc
595 * @param argv Standard main() style argv. Initial components are already
596 * stripped
598 * @return Normal NTSTATUS return.
601 static NTSTATUS
602 rpc_user_info_internals(const DOM_SID *domain_sid, struct cli_state *cli,
603 TALLOC_CTX *mem_ctx, int argc, const char **argv)
605 POLICY_HND connect_pol, domain_pol, user_pol;
606 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
607 uint32 *rids, num_rids, *name_types, num_names;
608 uint32 flags = 0x000003e8; /* Unknown */
609 int i;
610 char **names;
611 DOM_GID *user_gids;
613 if (argc < 1) {
614 d_printf("User must be specified\n");
615 rpc_user_usage(argc, argv);
616 return NT_STATUS_OK;
618 /* Get sam policy handle */
620 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
621 &connect_pol);
622 if (!NT_STATUS_IS_OK(result)) goto done;
624 /* Get domain policy handle */
626 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
627 MAXIMUM_ALLOWED_ACCESS,
628 domain_sid, &domain_pol);
629 if (!NT_STATUS_IS_OK(result)) goto done;
631 /* Get handle on user */
633 result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol,
634 flags, 1, &argv[0],
635 &num_rids, &rids, &name_types);
637 if (!NT_STATUS_IS_OK(result)) goto done;
639 result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
640 MAXIMUM_ALLOWED_ACCESS,
641 rids[0], &user_pol);
642 if (!NT_STATUS_IS_OK(result)) goto done;
644 result = cli_samr_query_usergroups(cli, mem_ctx, &user_pol,
645 &num_rids, &user_gids);
647 /* Look up rids */
649 rids = (uint32 *)talloc(mem_ctx, sizeof(uint32) * num_rids);
651 for (i = 0; i < num_rids; i++)
652 rids[i] = user_gids[i].g_rid;
654 result = cli_samr_lookup_rids(cli, mem_ctx, &domain_pol,
655 flags, num_rids, rids,
656 &num_names, &names, &name_types);
658 if (!NT_STATUS_IS_OK(result)) {
659 goto done;
662 /* Display results */
664 for (i = 0; i < num_names; i++)
665 printf("%s\n", names[i]);
667 done:
668 return result;
671 /**
672 * List a user's groups from a remote RPC server
674 * @param argc Standard main() style argc
675 * @param argv Standard main() style argv. Initial components are already
676 * stripped
678 * @return A shell status integer (0 for success)
681 static int rpc_user_info(int argc, const char **argv)
683 return run_rpc_command(PIPE_SAMR, 0, rpc_user_info_internals,
684 argc, argv);
687 /**
688 * List users on a remote RPC server
690 * All paramaters are provided by the run_rpc_command function, except for
691 * argc, argv which are passes through.
693 * @param domain_sid The domain sid acquired from the remote server
694 * @param cli A cli_state connected to the server.
695 * @param mem_ctx Talloc context, destoyed on completion of the function.
696 * @param argc Standard main() style argc
697 * @param argv Standard main() style argv. Initial components are already
698 * stripped
700 * @return Normal NTSTATUS return.
703 static NTSTATUS
704 rpc_user_list_internals(const DOM_SID *domain_sid, struct cli_state *cli,
705 TALLOC_CTX *mem_ctx, int argc, const char **argv)
707 POLICY_HND connect_pol, domain_pol;
708 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
709 uint32 start_idx=0, max_entries=250, num_entries, i;
710 SAM_DISPINFO_CTR ctr;
711 SAM_DISPINFO_1 info1;
713 /* Get sam policy handle */
715 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
716 &connect_pol);
717 if (!NT_STATUS_IS_OK(result)) {
718 goto done;
721 /* Get domain policy handle */
723 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
724 MAXIMUM_ALLOWED_ACCESS,
725 domain_sid, &domain_pol);
726 if (!NT_STATUS_IS_OK(result)) {
727 goto done;
730 /* Query domain users */
731 ZERO_STRUCT(ctr);
732 ZERO_STRUCT(info1);
733 ctr.sam.info1 = &info1;
734 if (opt_long_list_entries)
735 d_printf("\nUser name Comment"\
736 "\n-----------------------------\n");
737 do {
738 fstring user, desc;
739 result = cli_samr_query_dispinfo(cli, mem_ctx, &domain_pol,
740 &start_idx, 1, &num_entries,
741 max_entries, &ctr);
742 for (i = 0; i < num_entries; i++) {
743 unistr2_to_ascii(user, &(&ctr.sam.info1->str[i])->uni_acct_name, sizeof(user)-1);
744 if (opt_long_list_entries)
745 unistr2_to_ascii(desc, &(&ctr.sam.info1->str[i])->uni_acct_desc, sizeof(desc)-1);
747 if (opt_long_list_entries)
748 printf("%-21.21s %-50.50s\n", user, desc);
749 else
750 printf("%s\n", user);
752 } while (!NT_STATUS_IS_OK(result));
754 done:
755 return result;
758 /**
759 * 'net rpc user' entrypoint.
760 * @param argc Standard main() style argc
761 * @param argc Standard main() style argv. Initial components are already
762 * stripped
765 int net_rpc_user(int argc, const char **argv)
767 struct functable func[] = {
768 {"add", rpc_user_add},
769 {"info", rpc_user_info},
770 {"delete", rpc_user_delete},
771 {NULL, NULL}
774 if (argc == 0) {
775 if (opt_long_list_entries) {
776 } else {
778 return run_rpc_command(PIPE_SAMR, 0,
779 rpc_user_list_internals,
780 argc, argv);
783 return net_run_function(argc, argv, func, rpc_user_usage);
787 /****************************************************************************/
790 * Basic usage function for 'net rpc group'
791 * @param argc Standard main() style argc.
792 * @param argv Standard main() style argv. Initial components are already
793 * stripped.
796 static int rpc_group_usage(int argc, const char **argv)
798 return net_help_group(argc, argv);
801 /**
802 * List groups on a remote RPC server
804 * All paramaters are provided by the run_rpc_command funcion, except for
805 * argc, argv which are passes through.
807 * @param domain_sid The domain sid acquired from the remote server
808 * @param cli A cli_state connected to the server.
809 * @param mem_ctx Talloc context, destoyed on completion of the function.
810 * @param argc Standard main() style argc
811 * @param argv Standard main() style argv. Initial components are already
812 * stripped
814 * @return Normal NTSTATUS return.
817 static NTSTATUS
818 rpc_group_list_internals(const DOM_SID *domain_sid, struct cli_state *cli,
819 TALLOC_CTX *mem_ctx, int argc, const char **argv)
821 POLICY_HND connect_pol, domain_pol;
822 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
823 uint32 start_idx=0, max_entries=250, num_entries, i;
824 struct acct_info *groups;
825 DOM_SID global_sid_Builtin;
827 string_to_sid(&global_sid_Builtin, "S-1-5-32");
829 /* Get sam policy handle */
831 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
832 &connect_pol);
833 if (!NT_STATUS_IS_OK(result)) {
834 goto done;
837 /* Get domain policy handle */
839 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
840 MAXIMUM_ALLOWED_ACCESS,
841 domain_sid, &domain_pol);
842 if (!NT_STATUS_IS_OK(result)) {
843 goto done;
846 /* Query domain groups */
847 if (opt_long_list_entries)
848 d_printf("\nGroup name Comment"\
849 "\n-----------------------------\n");
850 do {
851 result = cli_samr_enum_dom_groups(cli, mem_ctx, &domain_pol,
852 &start_idx, max_entries,
853 &groups, &num_entries);
855 for (i = 0; i < num_entries; i++) {
856 if (opt_long_list_entries)
857 printf("%-21.21s %-50.50s\n",
858 groups[i].acct_name,
859 groups[i].acct_desc);
860 else
861 printf("%-21.21s\n", groups[i].acct_name);
863 } while (!NT_STATUS_IS_OK(result));
864 /* query domain aliases */
865 do {
866 result = cli_samr_enum_als_groups(cli, mem_ctx, &domain_pol,
867 &start_idx, max_entries,
868 &groups, &num_entries);
870 for (i = 0; i < num_entries; i++) {
871 if (opt_long_list_entries)
872 printf("%-21.21s %-50.50s\n",
873 groups[i].acct_name,
874 groups[i].acct_desc);
875 else
876 printf("%-21.21s\n", groups[i].acct_name);
878 } while (!NT_STATUS_IS_OK(result));
879 cli_samr_close(cli, mem_ctx, &domain_pol);
880 /* Get builtin policy handle */
882 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
883 MAXIMUM_ALLOWED_ACCESS,
884 &global_sid_Builtin, &domain_pol);
885 if (!NT_STATUS_IS_OK(result)) {
886 goto done;
888 /* query builtin aliases */
889 do {
890 result = cli_samr_enum_als_groups(cli, mem_ctx, &domain_pol,
891 &start_idx, max_entries,
892 &groups, &num_entries);
894 for (i = 0; i < num_entries; i++) {
895 if (opt_long_list_entries)
896 printf("%-21.21s %-50.50s\n",
897 groups[i].acct_name,
898 groups[i].acct_desc);
899 else
900 printf("%s\n", groups[i].acct_name);
902 } while (!NT_STATUS_IS_OK(result));
904 done:
905 return result;
908 /**
909 * 'net rpc group' entrypoint.
910 * @param argc Standard main() style argc
911 * @param argc Standard main() style argv. Initial components are already
912 * stripped
915 int net_rpc_group(int argc, const char **argv)
917 struct functable func[] = {
918 #if 0
919 {"add", rpc_group_add},
920 {"delete", rpc_group_delete},
921 #endif
922 {NULL, NULL}
925 if (argc == 0) {
926 if (opt_long_list_entries) {
927 } else {
929 return run_rpc_command(PIPE_SAMR, 0,
930 rpc_group_list_internals,
931 argc, argv);
934 return net_run_function(argc, argv, func, rpc_group_usage);
937 /****************************************************************************/
939 static int rpc_share_usage(int argc, const char **argv)
941 return net_help_share(argc, argv);
944 /**
945 * Add a share on a remote RPC server
947 * All paramaters are provided by the run_rpc_command function, except for
948 * argc, argv which are passes through.
950 * @param domain_sid The domain sid acquired from the remote server
951 * @param cli A cli_state connected to the server.
952 * @param mem_ctx Talloc context, destoyed on completion of the function.
953 * @param argc Standard main() style argc
954 * @param argv Standard main() style argv. Initial components are already
955 * stripped
957 * @return Normal NTSTATUS return.
959 static NTSTATUS
960 rpc_share_add_internals(const DOM_SID *domain_sid, struct cli_state *cli,
961 TALLOC_CTX *mem_ctx,int argc, const char **argv)
963 WERROR result;
964 char *sharename=talloc_strdup(mem_ctx, argv[0]);
965 char *path;
966 uint32 type=0; /* only allow disk shares to be added */
967 uint32 num_users=0, perms=0;
968 char *password=NULL; /* don't allow a share password */
970 path = strchr(sharename, '=');
971 if (!path)
972 return NT_STATUS_UNSUCCESSFUL;
973 *path++ = '\0';
975 result = cli_srvsvc_net_share_add(cli, mem_ctx, sharename, type,
976 opt_comment, perms, opt_maxusers,
977 num_users, path, password);
978 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
981 static int rpc_share_add(int argc, const char **argv)
983 if ((argc < 1) || !strchr(argv[0], '=')) {
984 DEBUG(1,("Sharename or path not specified on add\n"));
985 return rpc_share_usage(argc, argv);
987 return run_rpc_command(PIPE_SRVSVC, 0,
988 rpc_share_add_internals,
989 argc, argv);
992 /**
993 * Delete a share on a remote RPC server
995 * All paramaters are provided by the run_rpc_command function, except for
996 * argc, argv which are passes through.
998 * @param domain_sid The domain sid acquired from the remote server
999 * @param cli A cli_state connected to the server.
1000 * @param mem_ctx Talloc context, destoyed on completion of the function.
1001 * @param argc Standard main() style argc
1002 * @param argv Standard main() style argv. Initial components are already
1003 * stripped
1005 * @return Normal NTSTATUS return.
1007 static NTSTATUS
1008 rpc_share_del_internals(const DOM_SID *domain_sid, struct cli_state *cli,
1009 TALLOC_CTX *mem_ctx,int argc, const char **argv)
1011 WERROR result;
1013 result = cli_srvsvc_net_share_del(cli, mem_ctx, argv[0]);
1014 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1017 /**
1018 * Delete a share on a remote RPC server
1020 * @param domain_sid The domain sid acquired from the remote server
1021 * @param argc Standard main() style argc
1022 * @param argv Standard main() style argv. Initial components are already
1023 * stripped
1025 * @return A shell status integer (0 for success)
1027 static int rpc_share_delete(int argc, const char **argv)
1029 if (argc < 1) {
1030 DEBUG(1,("Sharename not specified on delete\n"));
1031 return rpc_share_usage(argc, argv);
1033 return run_rpc_command(PIPE_SRVSVC, 0,
1034 rpc_share_del_internals,
1035 argc, argv);
1039 * Formatted print of share info
1041 * @param info1 pointer to SRV_SHARE_INFO_1 to format
1044 static void display_share_info_1(SRV_SHARE_INFO_1 *info1)
1046 fstring netname = "", remark = "";
1048 rpcstr_pull_unistr2_fstring(netname, &info1->info_1_str.uni_netname);
1049 rpcstr_pull_unistr2_fstring(remark, &info1->info_1_str.uni_remark);
1051 if (opt_long_list_entries) {
1052 d_printf("%-12.12s %-8.8s %-50.50s\n",
1053 netname, share_type[info1->info_1.type], remark);
1054 } else {
1055 d_printf("%-12.12s\n", netname);
1060 /**
1061 * List shares on a remote RPC server
1063 * All paramaters are provided by the run_rpc_command function, except for
1064 * argc, argv which are passes through.
1066 * @param domain_sid The domain sid acquired from the remote server
1067 * @param cli A cli_state connected to the server.
1068 * @param mem_ctx Talloc context, destoyed on completion of the function.
1069 * @param argc Standard main() style argc
1070 * @param argv Standard main() style argv. Initial components are already
1071 * stripped
1073 * @return Normal NTSTATUS return.
1076 static NTSTATUS
1077 rpc_share_list_internals(const DOM_SID *domain_sid, struct cli_state *cli,
1078 TALLOC_CTX *mem_ctx, int argc, const char **argv)
1080 SRV_SHARE_INFO_CTR ctr;
1081 WERROR result;
1082 ENUM_HND hnd;
1083 uint32 preferred_len = 0xffffffff, i;
1085 init_enum_hnd(&hnd, 0);
1087 result = cli_srvsvc_net_share_enum(
1088 cli, mem_ctx, 1, &ctr, preferred_len, &hnd);
1090 if (!W_ERROR_IS_OK(result))
1091 goto done;
1093 /* Display results */
1095 if (opt_long_list_entries) {
1096 d_printf(
1097 "\nEnumerating shared resources (exports) on remote server:\n\n"\
1098 "\nShare name Type Description\n"\
1099 "---------- ---- -----------\n");
1101 for (i = 0; i < ctr.num_entries; i++)
1102 display_share_info_1(&ctr.share.info1[i]);
1103 done:
1104 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1107 /**
1108 * 'net rpc share' entrypoint.
1109 * @param argc Standard main() style argc
1110 * @param argv Standard main() style argv. Initial components are already
1111 * stripped
1114 int net_rpc_share(int argc, const char **argv)
1116 struct functable func[] = {
1117 {"add", rpc_share_add},
1118 {"delete", rpc_share_delete},
1119 {NULL, NULL}
1122 if (argc == 0)
1123 return run_rpc_command(PIPE_SRVSVC, 0,
1124 rpc_share_list_internals,
1125 argc, argv);
1127 return net_run_function(argc, argv, func, rpc_share_usage);
1130 /****************************************************************************/
1132 static int rpc_file_usage(int argc, const char **argv)
1134 return net_help_file(argc, argv);
1137 /**
1138 * Close a file on a remote RPC server
1140 * All paramaters are provided by the run_rpc_command function, except for
1141 * argc, argv which are passes through.
1143 * @param domain_sid The domain sid acquired from the remote server
1144 * @param cli A cli_state connected to the server.
1145 * @param mem_ctx Talloc context, destoyed on completion of the function.
1146 * @param argc Standard main() style argc
1147 * @param argv Standard main() style argv. Initial components are already
1148 * stripped
1150 * @return Normal NTSTATUS return.
1152 static NTSTATUS
1153 rpc_file_close_internals(const DOM_SID *domain_sid, struct cli_state *cli,
1154 TALLOC_CTX *mem_ctx, int argc, const char **argv)
1156 WERROR result;
1157 result = cli_srvsvc_net_file_close(cli, mem_ctx, atoi(argv[0]));
1158 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1161 /**
1162 * Close a file on a remote RPC server
1164 * @param argc Standard main() style argc
1165 * @param argv Standard main() style argv. Initial components are already
1166 * stripped
1168 * @return A shell status integer (0 for success)
1170 static int rpc_file_close(int argc, const char **argv)
1172 if (argc < 1) {
1173 DEBUG(1, ("No fileid given on close\n"));
1174 return(rpc_file_usage(argc, argv));
1177 return run_rpc_command(PIPE_SRVSVC, 0,
1178 rpc_file_close_internals,
1179 argc, argv);
1182 /**
1183 * Formatted print of open file info
1185 * @param info3 FILE_INFO_3 contents
1186 * @param str3 strings for FILE_INFO_3
1189 static void display_file_info_3(FILE_INFO_3 *info3, FILE_INFO_3_STR *str3)
1191 fstring user = "", path = "";
1193 rpcstr_pull_unistr2_fstring(user, &str3->uni_user_name);
1194 rpcstr_pull_unistr2_fstring(path, &str3->uni_path_name);
1196 d_printf("%-7.1d %-20.20s 0x%-4.2x %-6.1d %s\n",
1197 info3->id, user, info3->perms, info3->num_locks, path);
1200 /**
1201 * List open files on a remote RPC server
1203 * All paramaters are provided by the run_rpc_command funcion, except for
1204 * argc, argv which are passes through.
1206 * @param domain_sid The domain sid acquired from the remote server
1207 * @param cli A cli_state connected to the server.
1208 * @param mem_ctx Talloc context, destoyed on completion of the function.
1209 * @param argc Standard main() style argc
1210 * @param argv Standard main() style argv. Initial components are already
1211 * stripped
1213 * @return Normal NTSTATUS return.
1216 static NTSTATUS
1217 rpc_file_list_internals(const DOM_SID *domain_sid, struct cli_state *cli,
1218 TALLOC_CTX *mem_ctx, int argc, const char **argv)
1220 SRV_FILE_INFO_CTR ctr;
1221 WERROR result;
1222 ENUM_HND hnd;
1223 uint32 preferred_len = 0xffffffff, i;
1224 char *username=NULL;
1226 init_enum_hnd(&hnd, 0);
1228 /* if argc > 0, must be user command */
1229 if (argc > 0)
1230 username = argv[0];
1232 result = cli_srvsvc_net_file_enum(
1233 cli, mem_ctx, 3, username, &ctr, preferred_len, &hnd);
1235 if (!W_ERROR_IS_OK(result))
1236 goto done;
1238 /* Display results */
1240 d_printf(
1241 "\nEnumerating open files on remote server:\n\n"\
1242 "\nFileId Opened by Perms Locks Path"\
1243 "\n------ --------- ----- ----- ---- \n");
1244 for (i = 0; i < ctr.num_entries; i++)
1245 display_file_info_3(&ctr.file.info3[i].info_3,
1246 &ctr.file.info3[i].info_3_str);
1247 done:
1248 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1252 /**
1253 * List files for a user on a remote RPC server
1255 * @param argc Standard main() style argc
1256 * @param argv Standard main() style argv. Initial components are already
1257 * stripped
1259 * @return A shell status integer (0 for success)
1261 static int rpc_file_user(int argc, const char **argv)
1263 if (argc < 1) {
1264 DEBUG(1, ("No username given\n"));
1265 return(rpc_file_usage(argc, argv));
1268 return run_rpc_command(PIPE_SRVSVC, 0,
1269 rpc_file_list_internals,
1270 argc, argv);
1274 /**
1275 * 'net rpc file' entrypoint.
1276 * @param argc Standard main() style argc
1277 * @param argv Standard main() style argv. Initial components are already
1278 * stripped
1281 int net_rpc_file(int argc, const char **argv)
1283 struct functable func[] = {
1284 {"close", rpc_file_close},
1285 {"user", rpc_file_user},
1286 #if 0
1287 {"info", rpc_file_info},
1288 #endif
1289 {NULL, NULL}
1292 if (argc == 0)
1293 return run_rpc_command(PIPE_SRVSVC, 0,
1294 rpc_file_list_internals,
1295 argc, argv);
1297 return net_run_function(argc, argv, func, rpc_file_usage);
1300 /****************************************************************************/
1304 /**
1305 * ABORT the shutdown of a remote RPC Server
1307 * All paramaters are provided by the run_rpc_command function, except for
1308 * argc, argv which are passed through.
1310 * @param domain_sid The domain sid aquired from the remote server
1311 * @param cli A cli_state connected to the server.
1312 * @param mem_ctx Talloc context, destoyed on compleation of the function.
1313 * @param argc Standard main() style argc
1314 * @param argv Standard main() style argv. Initial components are already
1315 * stripped
1317 * @return Normal NTSTATUS return.
1320 static NTSTATUS rpc_shutdown_abort_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx,
1321 int argc, const char **argv)
1323 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1325 result = cli_reg_abort_shutdown(cli, mem_ctx);
1327 if (NT_STATUS_IS_OK(result))
1328 DEBUG(5,("cmd_reg_abort_shutdown: query succeeded\n"));
1329 else
1330 DEBUG(5,("cmd_reg_abort_shutdown: query failed\n"));
1332 return result;
1336 /**
1337 * ABORT the Shut down of a remote RPC server
1339 * @param argc Standard main() style argc
1340 * @param argv Standard main() style argv. Initial components are already
1341 * stripped
1343 * @return A shell status integer (0 for success)
1346 static int rpc_shutdown_abort(int argc, const char **argv)
1348 return run_rpc_command(PIPE_WINREG, 0, rpc_shutdown_abort_internals,
1349 argc, argv);
1352 /**
1353 * Shut down a remote RPC Server
1355 * All paramaters are provided by the run_rpc_command funcion, except for
1356 * argc, argv which are passes through.
1358 * @param domain_sid The domain sid aquired from the remote server
1359 * @param cli A cli_state connected to the server.
1360 * @param mem_ctx Talloc context, destoyed on compleation of the function.
1361 * @param argc Standard main() style argc
1362 * @param argc Standard main() style argv. Initial components are already
1363 * stripped
1365 * @return Normal NTSTATUS return.
1368 static NTSTATUS rpc_shutdown_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx,
1369 int argc, const char **argv)
1371 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1372 char *msg = "This machine will be shutdown shortly";
1373 uint32 timeout = 20;
1374 uint16 flgs = 0;
1375 BOOL reboot = opt_reboot;
1376 BOOL force = opt_force;
1377 #if 0
1378 poptContext pc;
1379 int rc;
1381 struct poptOption long_options[] = {
1382 {"message", 'm', POPT_ARG_STRING, &msg},
1383 {"timeout", 't', POPT_ARG_INT, &timeout},
1384 {"reboot", 'r', POPT_ARG_NONE, &reboot},
1385 {"force", 'f', POPT_ARG_NONE, &force},
1386 { 0, 0, 0, 0}
1389 pc = poptGetContext(NULL, argc, (const char **) argv, long_options,
1390 POPT_CONTEXT_KEEP_FIRST);
1392 rc = poptGetNextOpt(pc);
1394 if (rc < -1) {
1395 /* an error occurred during option processing */
1396 DEBUG(0, ("%s: %s\n",
1397 poptBadOption(pc, POPT_BADOPTION_NOALIAS),
1398 poptStrerror(rc)));
1399 return NT_STATUS_INVALID_PARAMETER;
1401 #endif
1402 if (reboot) {
1403 flgs |= REG_REBOOT_ON_SHUTDOWN;
1405 if (force) {
1406 flgs |= REG_FORCE_SHUTDOWN;
1408 if (opt_comment) {
1409 msg = opt_comment;
1411 if (opt_timeout) {
1412 timeout = opt_timeout;
1415 /* create an entry */
1416 result = cli_reg_shutdown(cli, mem_ctx, msg, timeout, flgs);
1418 if (NT_STATUS_IS_OK(result))
1419 DEBUG(5,("Shutdown of remote machine succeeded\n"));
1420 else
1421 DEBUG(0,("Shutdown of remote machine failed!\n"));
1423 return result;
1426 /**
1427 * Shut down a remote RPC server
1429 * @param argc Standard main() style argc
1430 * @param argc Standard main() style argv. Initial components are already
1431 * stripped
1433 * @return A shell status integer (0 for success)
1436 static int rpc_shutdown(int argc, const char **argv)
1438 return run_rpc_command(PIPE_WINREG, 0, rpc_shutdown_internals,
1439 argc, argv);
1442 /***************************************************************************
1443 NT Domain trusts code (i.e. 'net rpc trustdom' functionality)
1445 ***************************************************************************/
1448 * Add interdomain trust account to the RPC server.
1449 * All parameters (except for argc and argv) are passed by run_rpc_command
1450 * function.
1452 * @param domain_sid The domain sid acquired from the server
1453 * @param cli A cli_state connected to the server.
1454 * @param mem_ctx Talloc context, destoyed on completion of the function.
1455 * @param argc Standard main() style argc
1456 * @param argc Standard main() style argv. Initial components are already
1457 * stripped
1459 * @return normal NTSTATUS return code
1462 static NTSTATUS rpc_trustdom_add_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx,
1463 int argc, const char **argv) {
1465 POLICY_HND connect_pol, domain_pol, user_pol;
1466 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1467 char *acct_name;
1468 uint16 acb_info;
1469 uint32 unknown, user_rid;
1471 if (argc != 1) {
1472 d_printf("Usage: net rpc trustdom add <domain_name>\n");
1473 return NT_STATUS_INVALID_PARAMETER;
1477 * Make valid trusting domain account (ie. uppercased and with '$' appended)
1480 if (asprintf(&acct_name, "%s$", argv[0]) < 0) {
1481 return NT_STATUS_NO_MEMORY;
1484 strupper(acct_name);
1486 /* Get sam policy handle */
1488 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1489 &connect_pol);
1490 if (!NT_STATUS_IS_OK(result)) {
1491 goto done;
1494 /* Get domain policy handle */
1496 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
1497 MAXIMUM_ALLOWED_ACCESS,
1498 domain_sid, &domain_pol);
1499 if (!NT_STATUS_IS_OK(result)) {
1500 goto done;
1503 /* Create trusting domain's account */
1505 acb_info = ACB_DOMTRUST;
1506 unknown = 0xe005000b; /* No idea what this is - a permission mask?
1507 Is it needed for interdomain account also ? */
1509 result = cli_samr_create_dom_user(cli, mem_ctx, &domain_pol,
1510 acct_name, acb_info, unknown,
1511 &user_pol, &user_rid);
1512 if (!NT_STATUS_IS_OK(result)) {
1513 goto done;
1516 done:
1517 SAFE_FREE(acct_name);
1518 return result;
1522 * Create interdomain trust account for a remote domain.
1524 * @param argc standard argc
1525 * @param argv standard argv without initial components
1527 * @return Integer status (0 means success)
1530 static int rpc_trustdom_add(int argc, const char **argv)
1532 return run_rpc_command(PIPE_SAMR, 0, rpc_trustdom_add_internals,
1533 argc, argv);
1538 * Delete interdomain trust account for a remote domain.
1540 * @param argc standard argc
1541 * @param argv standard argv without initial components
1543 * @return Integer status (0 means success)
1546 static int rpc_trustdom_del(int argc, const char **argv)
1548 d_printf("Sorry, not yet implemented.\n");
1549 return -1;
1554 * Establish trust relationship to a trusting domain.
1555 * Interdomain account must already be created on remote PDC.
1557 * @param argc standard argc
1558 * @param argv standard argv without initial components
1560 * @return Integer status (0 means success)
1563 extern char *opt_user_name;
1564 extern char *opt_password;
1566 static int rpc_trustdom_establish(int argc, const char **argv) {
1568 struct cli_state *cli;
1569 struct in_addr server_ip;
1570 POLICY_HND connect_hnd;
1571 TALLOC_CTX *mem_ctx;
1572 NTSTATUS nt_status;
1573 DOM_SID domain_sid;
1574 WKS_INFO_100 wks_info;
1576 char* domain_name;
1577 char* acct_name;
1578 fstring pdc_name;
1581 * Connect to \\server\ipc$ as 'our domain' account with password
1584 if (argc != 1) {
1585 d_printf("Usage: net rpc trustdom add <domain_name>\n");
1586 return -1;
1590 domain_name = smb_xstrdup(argv[0]);
1591 strupper(domain_name);
1593 asprintf(&acct_name, "%s$", lp_workgroup());
1594 strupper(acct_name);
1596 opt_user_name = (char*)malloc(strlen(acct_name) + 1);
1597 safe_strcpy(opt_user_name, acct_name, strlen(acct_name) + 1);
1599 /* find the domain controller */
1600 if (!net_find_dc(&server_ip, pdc_name, domain_name)) {
1601 DEBUG(0, ("Coulnd find domain controller for domain %s\n", domain_name));
1602 return -1;
1605 /* connect to ipc$ as username/password */
1606 nt_status = connect_to_ipc(&cli, &server_ip, pdc_name);
1607 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT)) {
1609 /* Is it trusting domain account for sure ? */
1610 DEBUG(0, ("Couldn't verify trusting domain account. Error was %s\n",
1611 nt_errstr(nt_status)));
1612 return -1;
1616 * Connect to \\server\ipc$ again (this time anonymously)
1619 nt_status = connect_to_ipc_anonymous(&cli, &server_ip, (char*)pdc_name);
1621 if (NT_STATUS_IS_ERR(nt_status)) {
1622 DEBUG(0, ("Couldn't connect to domain %s controller. Error was %s.\n",
1623 domain_name, nt_errstr(nt_status)));
1627 * Use NetServerEnum2 to make sure we're talking to a proper server
1630 if (!cli_get_pdc_name(cli, domain_name, (char*)pdc_name)) {
1631 DEBUG(0, ("NetServerEnum2 error: Couldn't find primary domain controller\
1632 for domain %s\n", domain_name));
1636 * Call WksQueryInfo to check remote server's capabilities
1637 * FIXME:Is really necessary ? nt serv does this, but from samba's
1638 * point of view it doesn't seem to make the difference
1639 * IDEA: It may be used to get info about type of pdc we're talking to
1640 * (e.g. WinNT or Win2k)
1643 if (!cli_nt_session_open(cli, PIPE_WKSSVC)) {
1644 DEBUG(0, ("Couldn't not initialise wkssvc pipe\n"));
1645 return -1;
1648 /* TODO: convert this call from rpc_client/cli_wkssvc.c
1649 to cli_wks_query_info() in libsmb/cli_wkssvc.c
1650 UPDATE: already done :)
1653 if (!(mem_ctx = talloc_init())) {
1654 DEBUG(0, ("talloc_init() failed\n"));
1655 cli_shutdown(cli);
1656 return -1;
1659 nt_status = cli_wks_query_info(cli, mem_ctx, &wks_info);
1661 if (NT_STATUS_IS_ERR(nt_status)) {
1662 DEBUG(0, ("WksQueryInfo call failed.\n"));
1663 return -1;
1666 if (cli->nt_pipe_fnum)
1667 cli_nt_session_close(cli);
1671 * Call LsaOpenPolicy and LsaQueryInfo
1674 if (!(mem_ctx = talloc_init())) {
1675 DEBUG(0, ("talloc_init() failed\n"));
1676 cli_shutdown(cli);
1677 return -1;
1680 if (!cli_nt_session_open(cli, PIPE_LSARPC)) {
1681 DEBUG(0, ("Could not initialise lsa pipe\n"));
1684 nt_status = cli_lsa_open_policy2(cli, mem_ctx, True, SEC_RIGHTS_QUERY_VALUE,
1685 &connect_hnd);
1686 if (NT_STATUS_IS_ERR(nt_status)) {
1687 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
1688 nt_errstr(nt_status)));
1689 return -1;
1692 /* Querying info level 5 */
1694 nt_status = cli_lsa_query_info_policy(cli, mem_ctx, &connect_hnd,
1695 5 /* info level */, domain_name, &domain_sid);
1696 if (NT_STATUS_IS_ERR(nt_status)) {
1697 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
1698 nt_errstr(nt_status)));
1699 return -1;
1703 /* There should be actually query info level 3 (following nt serv behaviour),
1704 but I still don't know if it's _really_ necessary */
1707 * Store the password in secrets db
1710 if (!secrets_store_trusted_domain_password(domain_name, wks_info.uni_lan_grp.buffer,
1711 wks_info.uni_lan_grp.uni_str_len, opt_password,
1712 domain_sid)) {
1713 DEBUG(0, ("Storing password for trusted domain failed.\n"));
1714 return -1;
1718 * Close the pipes and clean up
1721 nt_status = cli_lsa_close(cli, mem_ctx, &connect_hnd);
1722 if (NT_STATUS_IS_ERR(nt_status)) {
1723 DEBUG(0, ("Couldn't close LSA pipe. Error was %s\n",
1724 nt_errstr(nt_status)));
1725 return -1;
1728 if (cli->nt_pipe_fnum)
1729 cli_nt_session_close(cli);
1731 talloc_destroy(mem_ctx);
1733 DEBUG(0, ("Success!\n"));
1734 return 0;
1738 * Revoke trust relationship to the remote domain
1740 * @param argc standard argc
1741 * @param argv standard argv without initial components
1743 * @return Integer status (0 means success)
1746 static int rpc_trustdom_revoke(int argc, const char **argv) {
1748 char* domain_name;
1750 if (argc < 1) return -1;
1752 /* generate upper cased domain name */
1753 domain_name = smb_xstrdup(argv[0]);
1754 strupper(domain_name);
1756 /* delete password of the trust */
1757 if (!trusted_domain_password_delete(domain_name)) {
1758 DEBUG(0, ("Failed to revoke relationship to the trusted domain %s\n",
1759 domain_name));
1760 return -1;
1763 return 0;
1767 * Usage for 'net rpc trustdom' command
1769 * @param argc standard argc
1770 * @param argv standard argv without inital components
1772 * @return Integer status returned to shell
1775 static int rpc_trustdom_usage(int argc, const char **argv) {
1776 d_printf(" net rpc trustdom add \t\t add trusting domain's account\n");
1777 d_printf(" net rpc trustdom del \t\t delete trusting domain's account\n");
1778 d_printf(" net rpc trustdom establish \t establish relationship to trusted domain\n");
1779 d_printf(" net rpc trustdom revoke \t abandon relationship to trusted domain\n");
1780 d_printf(" net rpc trustdom list \t show current interdomain trust relationships\n");
1781 return -1;
1786 * Entrypoint for 'net rpc trustdom' code
1788 * @param argc standard argc
1789 * @param argv standard argv without initial components
1791 * @return Integer status (0 means success)
1794 static int rpc_trustdom(int argc, const char **argv)
1796 struct functable func[] = {
1797 {"add", rpc_trustdom_add},
1798 {"del", rpc_trustdom_del},
1799 {"establish", rpc_trustdom_establish},
1800 {"revoke", rpc_trustdom_revoke},
1801 {"help", rpc_trustdom_usage},
1802 {NULL, NULL}
1805 if (argc == 0) {
1806 rpc_trustdom_usage(argc, argv);
1807 return -1;
1810 return (net_run_function(argc, argv, func, rpc_user_usage));
1814 * Check if a server will take rpc commands
1815 * @param flags Type of server to connect to (PDC, DMB, localhost)
1816 * if the host is not explicitly specified
1817 * @return BOOL (true means rpc supported)
1819 BOOL net_rpc_check(unsigned flags)
1821 struct cli_state cli;
1822 BOOL ret = False;
1823 struct in_addr server_ip;
1824 char *server_name = NULL;
1826 /* flags (i.e. server type) may depend on command */
1827 if (!net_find_server(flags, &server_ip, &server_name))
1828 goto done;
1830 ZERO_STRUCT(cli);
1831 if (cli_initialise(&cli) == False)
1832 return False;
1834 if (!cli_connect(&cli, server_name, &server_ip))
1835 goto done;
1836 if (!attempt_netbios_session_request(&cli, global_myname,
1837 server_name, &server_ip))
1838 goto done;
1839 if (!cli_negprot(&cli))
1840 goto done;
1841 if (cli.protocol < PROTOCOL_NT1)
1842 goto done;
1844 ret = True;
1845 done:
1846 cli_shutdown(&cli);
1847 return ret;
1851 /****************************************************************************/
1854 /**
1855 * Basic usage function for 'net rpc'
1856 * @param argc Standard main() style argc
1857 * @param argv Standard main() style argv. Initial components are already
1858 * stripped
1861 int net_rpc_usage(int argc, const char **argv)
1863 d_printf(" net rpc info \t\t\tshow basic info about a domain \n");
1864 d_printf(" net rpc join \t\t\tto join a domain \n");
1865 d_printf(" net rpc user \t\t\tto add, delete and list users\n");
1866 d_printf(" net rpc group \t\tto list groups\n");
1867 d_printf(" net rpc share \t\tto add, delete, and list shares\n");
1868 d_printf(" net rpc file \t\t\tto list open files\n");
1869 d_printf(" net rpc changetrustpw \tto change the trust account password\n");
1870 d_printf(" net rpc trustdom \t\tto create trusting domain's account\n"
1871 "\t\t\t\t\tor establish trust\n");
1872 d_printf(" net rpc abortshutdown \tto abort the shutdown of a remote server\n");
1873 d_printf(" net rpc shutdown \t\tto shutdown a remote server\n");
1874 d_printf("\n");
1875 d_printf("'net rpc shutdown' also accepts the following miscellaneous options:\n"); /* misc options */
1876 d_printf("\t-r or --reboot\trequest remote server reboot on shutdown\n");
1877 d_printf("\t-f or --force\trequest the remote server force its shutdown\n");
1878 d_printf("\t-t or --timeout=<timeout>\tnumber of seconds before shutdown\n");
1879 d_printf("\t-c or --comment=<message>\ttext message to display on impending shutdown\n");
1880 return -1;
1885 * Help function for 'net rpc'. Calls command specific help if requested
1886 * or displays usage of net rpc
1887 * @param argc Standard main() style argc
1888 * @param argv Standard main() style argv. Initial components are already
1889 * stripped
1892 int net_rpc_help(int argc, const char **argv)
1894 struct functable func[] = {
1895 {"join", rpc_join_usage},
1896 {"user", rpc_user_usage},
1897 {"group", rpc_group_usage},
1898 {"share", rpc_share_usage},
1899 /*{"changetrustpw", rpc_changetrustpw_usage}, */
1900 {"trustdom", rpc_trustdom_usage},
1901 /*{"abortshutdown", rpc_shutdown_abort_usage},*/
1902 /*{"shutdown", rpc_shutdown_usage}, */
1903 {NULL, NULL}
1906 if (argc == 0) {
1907 net_rpc_usage(argc, argv);
1908 return -1;
1911 return (net_run_function(argc, argv, func, rpc_user_usage));
1915 /**
1916 * 'net rpc' entrypoint.
1917 * @param argc Standard main() style argc
1918 * @param argv Standard main() style argv. Initial components are already
1919 * stripped
1922 int net_rpc(int argc, const char **argv)
1924 struct functable func[] = {
1925 {"info", net_rpc_info},
1926 {"join", net_rpc_join},
1927 {"user", net_rpc_user},
1928 {"group", net_rpc_group},
1929 {"share", net_rpc_share},
1930 {"file", net_rpc_file},
1931 {"changetrustpw", rpc_changetrustpw},
1932 {"trustdom", rpc_trustdom},
1933 {"abortshutdown", rpc_shutdown_abort},
1934 {"shutdown", rpc_shutdown},
1935 {"help", net_rpc_help},
1936 {NULL, NULL}
1938 return net_run_function(argc, argv, func, net_rpc_usage);