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. */
22 #include "../utils/net.h"
24 extern pstring global_myname;
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.
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 **);
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.
53 static DOM_SID *net_get_remote_domain_sid(struct cli_state *cli)
57 NTSTATUS result = NT_STATUS_OK;
58 uint32 info_class = 5;
62 if (!(domain_sid = malloc(sizeof(DOM_SID)))){
63 DEBUG(0,("net_get_remote_domain_sid: malloc returned NULL!\n"));
67 if (!(mem_ctx=talloc_init()))
69 DEBUG(0,("net_get_remote_domain_sid: talloc_init returned NULL!\n"));
74 if (!cli_nt_session_open (cli, PIPE_LSARPC)) {
75 fprintf(stderr, "could not initialise lsa pipe\n");
79 result = cli_lsa_open_policy(cli, mem_ctx, True,
80 SEC_RIGHTS_MAXIMUM_ALLOWED,
82 if (!NT_STATUS_IS_OK(result)) {
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)) {
92 cli_lsa_close(cli, mem_ctx, &pol);
93 cli_nt_session_close(cli);
94 talloc_destroy(mem_ctx);
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));
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
117 * @return A shell status integer (0 for success)
120 static int run_rpc_command(struct cli_state *cli_arg, const char *pipe_name, int conn_flags,
122 int argc, const char **argv)
124 struct cli_state *cli = NULL;
129 /* make use of cli_state handed over as an argument, if possible */
131 cli = net_make_ipc_connection(conn_flags);
139 domain_sid = net_get_remote_domain_sid(cli);
143 if (!(mem_ctx = talloc_init())) {
144 DEBUG(0, ("talloc_init() failed\n"));
149 if (!cli_nt_session_open(cli, pipe_name)) {
150 DEBUG(0, ("Could not initialise %s pipe\n", pipe_name));
153 nt_status = fn(domain_sid, cli, mem_ctx, argc, argv);
155 if (!NT_STATUS_IS_OK(nt_status)) {
156 DEBUG(1, ("rpc command function failed! (%s)\n", nt_errstr(nt_status)));
158 DEBUG(5, ("rpc command function succedded\n"));
162 if (cli->nt_pipe_fnum)
163 cli_nt_session_close(cli);
165 /* close the connection only if it was opened here */
169 talloc_destroy(mem_ctx);
171 return (!NT_STATUS_IS_OK(nt_status));
175 /****************************************************************************/
179 * Force a change of the trust acccount password.
181 * All paramaters are provided by the run_rpc_command funcion, except for
182 * argc, argv which are passes through.
184 * @param domain_sid The domain sid aquired from the remote server
185 * @param cli A cli_state connected to the server.
186 * @param mem_ctx Talloc context, destoyed on compleation of the function.
187 * @param argc Standard main() style argc
188 * @param argc Standard main() style argv. Initial components are already
191 * @return Normal NTSTATUS return.
194 static NTSTATUS rpc_changetrustpw_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx,
195 int argc, const char **argv) {
197 return trust_pw_find_change_and_store_it(cli, mem_ctx, opt_target_workgroup);
201 * Force a change of the trust acccount password.
203 * @param argc Standard main() style argc
204 * @param argc Standard main() style argv. Initial components are already
207 * @return A shell status integer (0 for success)
210 static int rpc_changetrustpw(int argc, const char **argv)
212 return run_rpc_command(NULL, PIPE_NETLOGON, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, rpc_changetrustpw_internals,
217 /****************************************************************************/
221 * Join a domain, the old way.
223 * This uses 'machinename' as the inital password, and changes it.
225 * The password should be created with 'server manager' or eqiv first.
227 * All paramaters are provided by the run_rpc_command funcion, except for
228 * argc, argv which are passes through.
230 * @param domain_sid The domain sid aquired from the remote server
231 * @param cli A cli_state connected to the server.
232 * @param mem_ctx Talloc context, destoyed on compleation of the function.
233 * @param argc Standard main() style argc
234 * @param argc Standard main() style argv. Initial components are already
237 * @return Normal NTSTATUS return.
240 static NTSTATUS rpc_join_oldstyle_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx,
241 int argc, const char **argv) {
243 extern pstring global_myname;
244 fstring trust_passwd;
245 unsigned char orig_trust_passwd_hash[16];
247 fstrcpy(trust_passwd, global_myname);
248 strlower(trust_passwd);
251 * Machine names can be 15 characters, but the max length on
252 * a password is 14. --jerry
255 trust_passwd[14] = '\0';
257 E_md4hash(trust_passwd, orig_trust_passwd_hash);
259 return trust_pw_change_and_store_it(cli, mem_ctx, orig_trust_passwd_hash);
263 * Join a domain, the old way.
265 * @param argc Standard main() style argc
266 * @param argc Standard main() style argv. Initial components are already
269 * @return A shell status integer (0 for success)
272 static int net_rpc_join_oldstyle(int argc, const char **argv)
274 return run_rpc_command(NULL, PIPE_NETLOGON, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, rpc_join_oldstyle_internals,
279 * Basic usage function for 'net rpc join'
280 * @param argc Standard main() style argc
281 * @param argc Standard main() style argv. Initial components are already
285 static int rpc_join_usage(int argc, const char **argv)
287 d_printf("net rpc join -U <username>[%%password] [options]\n"\
288 "\t to join a domain with admin username & password\n"\
289 "\t\t password will be prompted if none is specified\n");
290 d_printf("net rpc join [options except -U]\n"\
291 "\t to join a domain created in server manager\n\n\n");
293 net_common_flags_usage(argc, argv);
298 * 'net rpc join' entrypoint.
299 * @param argc Standard main() style argc
300 * @param argc Standard main() style argv. Initial components are already
303 * Main 'net_rpc_join()' (where the admain username/password is used) is
305 * Assume if a -U is specified, it's the new style, otherwise it's the
309 int net_rpc_join(int argc, const char **argv)
311 if ((net_rpc_join_oldstyle(argc, argv) == 0))
314 return net_rpc_join_newstyle(argc, argv);
320 * display info about a rpc domain
322 * All paramaters are provided by the run_rpc_command function, except for
323 * argc, argv which are passes through.
325 * @param domain_sid The domain sid acquired from the remote server
326 * @param cli A cli_state connected to the server.
327 * @param mem_ctx Talloc context, destoyed on completion of the function.
328 * @param argc Standard main() style argc
329 * @param argv Standard main() style argv. Initial components are already
332 * @return Normal NTSTATUS return.
336 rpc_info_internals(const DOM_SID *domain_sid, struct cli_state *cli,
337 TALLOC_CTX *mem_ctx, int argc, const char **argv)
339 POLICY_HND connect_pol, domain_pol;
340 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
343 /* Get sam policy handle */
344 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
346 if (!NT_STATUS_IS_OK(result)) {
350 /* Get domain policy handle */
351 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
352 MAXIMUM_ALLOWED_ACCESS,
353 domain_sid, &domain_pol);
354 if (!NT_STATUS_IS_OK(result)) {
359 result = cli_samr_query_dom_info(cli, mem_ctx, &domain_pol,
361 if (NT_STATUS_IS_OK(result)) {
362 TALLOC_CTX *ctx = talloc_init();
363 d_printf("Domain Name: %s\n", unistr2_tdup(ctx, &ctr.info.inf2.uni_domain));
364 d_printf("Sequence number: %u\n", ctr.info.inf2.seq_num);
365 d_printf("Num users: %u\n", ctr.info.inf2.num_domain_usrs);
366 d_printf("Num domain groups: %u\n", ctr.info.inf2.num_domain_grps);
367 d_printf("Num local groups: %u\n", ctr.info.inf2.num_local_grps);
377 * 'net rpc info' entrypoint.
378 * @param argc Standard main() style argc
379 * @param argc Standard main() style argv. Initial components are already
382 int net_rpc_info(int argc, const char **argv)
384 return run_rpc_command(NULL, PIPE_SAMR, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC,
392 /****************************************************************************/
395 * Basic usage function for 'net rpc user'
396 * @param argc Standard main() style argc.
397 * @param argv Standard main() style argv. Initial components are already
401 static int rpc_user_usage(int argc, const char **argv)
403 return net_help_user(argc, argv);
407 * Add a new user to a remote RPC server
409 * All paramaters are provided by the run_rpc_command funcion, except for
410 * argc, argv which are passes through.
412 * @param domain_sid The domain sid acquired from the remote server
413 * @param cli A cli_state connected to the server.
414 * @param mem_ctx Talloc context, destoyed on completion of the function.
415 * @param argc Standard main() style argc
416 * @param argv Standard main() style argv. Initial components are already
419 * @return Normal NTSTATUS return.
422 static NTSTATUS rpc_user_add_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx,
423 int argc, const char **argv) {
425 POLICY_HND connect_pol, domain_pol, user_pol;
426 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
427 const char *acct_name;
429 uint32 unknown, user_rid;
432 d_printf("User must be specified\n");
433 rpc_user_usage(argc, argv);
439 /* Get sam policy handle */
441 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
443 if (!NT_STATUS_IS_OK(result)) {
447 /* Get domain policy handle */
449 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
450 MAXIMUM_ALLOWED_ACCESS,
451 domain_sid, &domain_pol);
452 if (!NT_STATUS_IS_OK(result)) {
456 /* Create domain user */
458 acb_info = ACB_NORMAL;
459 unknown = 0xe005000b; /* No idea what this is - a permission mask? */
461 result = cli_samr_create_dom_user(cli, mem_ctx, &domain_pol,
462 acct_name, acb_info, unknown,
463 &user_pol, &user_rid);
464 if (!NT_STATUS_IS_OK(result)) {
469 if (!NT_STATUS_IS_OK(result)) {
470 d_printf("Failed to add user %s - %s\n", acct_name,
473 d_printf("Added user %s\n", acct_name);
479 * Add a new user to a remote RPC server
481 * @param argc Standard main() style argc
482 * @param argv Standard main() style argv. Initial components are already
485 * @return A shell status integer (0 for success)
488 static int rpc_user_add(int argc, const char **argv)
490 return run_rpc_command(NULL, PIPE_SAMR, 0, rpc_user_add_internals,
495 * Delete a user from a remote RPC server
497 * All paramaters are provided by the run_rpc_command funcion, except for
498 * argc, argv which are passes through.
500 * @param domain_sid The domain sid acquired from the remote server
501 * @param cli A cli_state connected to the server.
502 * @param mem_ctx Talloc context, destoyed on completion of the function.
503 * @param argc Standard main() style argc
504 * @param argv Standard main() style argv. Initial components are already
507 * @return Normal NTSTATUS return.
510 static NTSTATUS rpc_user_del_internals(const DOM_SID *domain_sid,
511 struct cli_state *cli,
513 int argc, const char **argv)
515 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
516 POLICY_HND connect_pol, domain_pol, user_pol;
519 d_printf("User must be specified\n");
520 rpc_user_usage(argc, argv);
523 /* Get sam policy and domain handles */
525 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
528 if (!NT_STATUS_IS_OK(result)) {
532 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
533 MAXIMUM_ALLOWED_ACCESS,
534 domain_sid, &domain_pol);
536 if (!NT_STATUS_IS_OK(result)) {
540 /* Get handle on user */
543 uint32 *user_rids, num_rids, *name_types;
544 uint32 flags = 0x000003e8; /* Unknown */
546 result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol,
548 &num_rids, &user_rids,
551 if (!NT_STATUS_IS_OK(result)) {
555 result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
556 MAXIMUM_ALLOWED_ACCESS,
557 user_rids[0], &user_pol);
559 if (!NT_STATUS_IS_OK(result)) {
566 result = cli_samr_delete_dom_user(cli, mem_ctx, &user_pol);
568 if (!NT_STATUS_IS_OK(result)) {
572 /* Display results */
580 * Delete a user from a remote RPC server
582 * @param argc Standard main() style argc
583 * @param argv Standard main() style argv. Initial components are already
586 * @return A shell status integer (0 for success)
589 static int rpc_user_delete(int argc, const char **argv)
591 return run_rpc_command(NULL, PIPE_SAMR, 0, rpc_user_del_internals,
596 * List user's groups on a remote RPC server
598 * All paramaters are provided by the run_rpc_command funcion, except for
599 * argc, argv which are passes through.
601 * @param domain_sid The domain sid acquired from the remote server
602 * @param cli A cli_state connected to the server.
603 * @param mem_ctx Talloc context, destoyed on completion of the function.
604 * @param argc Standard main() style argc
605 * @param argv Standard main() style argv. Initial components are already
608 * @return Normal NTSTATUS return.
612 rpc_user_info_internals(const DOM_SID *domain_sid, struct cli_state *cli,
613 TALLOC_CTX *mem_ctx, int argc, const char **argv)
615 POLICY_HND connect_pol, domain_pol, user_pol;
616 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
617 uint32 *rids, num_rids, *name_types, num_names;
618 uint32 flags = 0x000003e8; /* Unknown */
624 d_printf("User must be specified\n");
625 rpc_user_usage(argc, argv);
628 /* Get sam policy handle */
630 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
632 if (!NT_STATUS_IS_OK(result)) goto done;
634 /* Get domain policy handle */
636 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
637 MAXIMUM_ALLOWED_ACCESS,
638 domain_sid, &domain_pol);
639 if (!NT_STATUS_IS_OK(result)) goto done;
641 /* Get handle on user */
643 result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol,
645 &num_rids, &rids, &name_types);
647 if (!NT_STATUS_IS_OK(result)) goto done;
649 result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
650 MAXIMUM_ALLOWED_ACCESS,
652 if (!NT_STATUS_IS_OK(result)) goto done;
654 result = cli_samr_query_usergroups(cli, mem_ctx, &user_pol,
655 &num_rids, &user_gids);
659 rids = (uint32 *)talloc(mem_ctx, sizeof(uint32) * num_rids);
661 for (i = 0; i < num_rids; i++)
662 rids[i] = user_gids[i].g_rid;
664 result = cli_samr_lookup_rids(cli, mem_ctx, &domain_pol,
665 flags, num_rids, rids,
666 &num_names, &names, &name_types);
668 if (!NT_STATUS_IS_OK(result)) {
672 /* Display results */
674 for (i = 0; i < num_names; i++)
675 printf("%s\n", names[i]);
682 * List a user's groups from a remote RPC server
684 * @param argc Standard main() style argc
685 * @param argv Standard main() style argv. Initial components are already
688 * @return A shell status integer (0 for success)
691 static int rpc_user_info(int argc, const char **argv)
693 return run_rpc_command(NULL, PIPE_SAMR, 0, rpc_user_info_internals,
698 * List users on a remote RPC server
700 * All paramaters are provided by the run_rpc_command function, except for
701 * argc, argv which are passes through.
703 * @param domain_sid The domain sid acquired from the remote server
704 * @param cli A cli_state connected to the server.
705 * @param mem_ctx Talloc context, destoyed on completion of the function.
706 * @param argc Standard main() style argc
707 * @param argv Standard main() style argv. Initial components are already
710 * @return Normal NTSTATUS return.
714 rpc_user_list_internals(const DOM_SID *domain_sid, struct cli_state *cli,
715 TALLOC_CTX *mem_ctx, int argc, const char **argv)
717 POLICY_HND connect_pol, domain_pol;
718 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
719 uint32 start_idx=0, max_entries=250, num_entries, i;
720 SAM_DISPINFO_CTR ctr;
721 SAM_DISPINFO_1 info1;
723 /* Get sam policy handle */
725 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
727 if (!NT_STATUS_IS_OK(result)) {
731 /* Get domain policy handle */
733 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
734 MAXIMUM_ALLOWED_ACCESS,
735 domain_sid, &domain_pol);
736 if (!NT_STATUS_IS_OK(result)) {
740 /* Query domain users */
743 ctr.sam.info1 = &info1;
744 if (opt_long_list_entries)
745 d_printf("\nUser name Comment"\
746 "\n-----------------------------\n");
749 result = cli_samr_query_dispinfo(cli, mem_ctx, &domain_pol,
750 &start_idx, 1, &num_entries,
752 for (i = 0; i < num_entries; i++) {
753 unistr2_to_ascii(user, &(&ctr.sam.info1->str[i])->uni_acct_name, sizeof(user)-1);
754 if (opt_long_list_entries)
755 unistr2_to_ascii(desc, &(&ctr.sam.info1->str[i])->uni_acct_desc, sizeof(desc)-1);
757 if (opt_long_list_entries)
758 printf("%-21.21s %-50.50s\n", user, desc);
760 printf("%s\n", user);
762 } while (!NT_STATUS_IS_OK(result));
769 * 'net rpc user' entrypoint.
770 * @param argc Standard main() style argc
771 * @param argc Standard main() style argv. Initial components are already
775 int net_rpc_user(int argc, const char **argv)
777 struct functable func[] = {
778 {"add", rpc_user_add},
779 {"info", rpc_user_info},
780 {"delete", rpc_user_delete},
785 if (opt_long_list_entries) {
788 return run_rpc_command(NULL,PIPE_SAMR, 0,
789 rpc_user_list_internals,
793 return net_run_function(argc, argv, func, rpc_user_usage);
797 /****************************************************************************/
800 * Basic usage function for 'net rpc group'
801 * @param argc Standard main() style argc.
802 * @param argv Standard main() style argv. Initial components are already
806 static int rpc_group_usage(int argc, const char **argv)
808 return net_help_group(argc, argv);
812 * List groups on a remote RPC server
814 * All paramaters are provided by the run_rpc_command funcion, except for
815 * argc, argv which are passes through.
817 * @param domain_sid The domain sid acquired from the remote server
818 * @param cli A cli_state connected to the server.
819 * @param mem_ctx Talloc context, destoyed on completion of the function.
820 * @param argc Standard main() style argc
821 * @param argv Standard main() style argv. Initial components are already
824 * @return Normal NTSTATUS return.
828 rpc_group_list_internals(const DOM_SID *domain_sid, struct cli_state *cli,
829 TALLOC_CTX *mem_ctx, int argc, const char **argv)
831 POLICY_HND connect_pol, domain_pol;
832 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
833 uint32 start_idx=0, max_entries=250, num_entries, i;
834 struct acct_info *groups;
835 DOM_SID global_sid_Builtin;
837 string_to_sid(&global_sid_Builtin, "S-1-5-32");
839 /* Get sam policy handle */
841 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
843 if (!NT_STATUS_IS_OK(result)) {
847 /* Get domain policy handle */
849 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
850 MAXIMUM_ALLOWED_ACCESS,
851 domain_sid, &domain_pol);
852 if (!NT_STATUS_IS_OK(result)) {
856 /* Query domain groups */
857 if (opt_long_list_entries)
858 d_printf("\nGroup name Comment"\
859 "\n-----------------------------\n");
861 result = cli_samr_enum_dom_groups(cli, mem_ctx, &domain_pol,
862 &start_idx, max_entries,
863 &groups, &num_entries);
865 for (i = 0; i < num_entries; i++) {
866 if (opt_long_list_entries)
867 printf("%-21.21s %-50.50s\n",
869 groups[i].acct_desc);
871 printf("%-21.21s\n", groups[i].acct_name);
873 } while (!NT_STATUS_IS_OK(result));
874 /* query domain aliases */
876 result = cli_samr_enum_als_groups(cli, mem_ctx, &domain_pol,
877 &start_idx, max_entries,
878 &groups, &num_entries);
880 for (i = 0; i < num_entries; i++) {
881 if (opt_long_list_entries)
882 printf("%-21.21s %-50.50s\n",
884 groups[i].acct_desc);
886 printf("%-21.21s\n", groups[i].acct_name);
888 } while (!NT_STATUS_IS_OK(result));
889 cli_samr_close(cli, mem_ctx, &domain_pol);
890 /* Get builtin policy handle */
892 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
893 MAXIMUM_ALLOWED_ACCESS,
894 &global_sid_Builtin, &domain_pol);
895 if (!NT_STATUS_IS_OK(result)) {
898 /* query builtin aliases */
900 result = cli_samr_enum_als_groups(cli, mem_ctx, &domain_pol,
901 &start_idx, max_entries,
902 &groups, &num_entries);
904 for (i = 0; i < num_entries; i++) {
905 if (opt_long_list_entries)
906 printf("%-21.21s %-50.50s\n",
908 groups[i].acct_desc);
910 printf("%s\n", groups[i].acct_name);
912 } while (!NT_STATUS_IS_OK(result));
919 * 'net rpc group' entrypoint.
920 * @param argc Standard main() style argc
921 * @param argc Standard main() style argv. Initial components are already
925 int net_rpc_group(int argc, const char **argv)
927 struct functable func[] = {
929 {"add", rpc_group_add},
930 {"delete", rpc_group_delete},
936 if (opt_long_list_entries) {
939 return run_rpc_command(NULL, PIPE_SAMR, 0,
940 rpc_group_list_internals,
944 return net_run_function(argc, argv, func, rpc_group_usage);
947 /****************************************************************************/
949 static int rpc_share_usage(int argc, const char **argv)
951 return net_help_share(argc, argv);
955 * Add a share on a remote RPC server
957 * All paramaters are provided by the run_rpc_command function, except for
958 * argc, argv which are passes through.
960 * @param domain_sid The domain sid acquired from the remote server
961 * @param cli A cli_state connected to the server.
962 * @param mem_ctx Talloc context, destoyed on completion of the function.
963 * @param argc Standard main() style argc
964 * @param argv Standard main() style argv. Initial components are already
967 * @return Normal NTSTATUS return.
970 rpc_share_add_internals(const DOM_SID *domain_sid, struct cli_state *cli,
971 TALLOC_CTX *mem_ctx,int argc, const char **argv)
974 char *sharename=talloc_strdup(mem_ctx, argv[0]);
976 uint32 type=0; /* only allow disk shares to be added */
977 uint32 num_users=0, perms=0;
978 char *password=NULL; /* don't allow a share password */
980 path = strchr(sharename, '=');
982 return NT_STATUS_UNSUCCESSFUL;
985 result = cli_srvsvc_net_share_add(cli, mem_ctx, sharename, type,
986 opt_comment, perms, opt_maxusers,
987 num_users, path, password);
988 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
991 static int rpc_share_add(int argc, const char **argv)
993 if ((argc < 1) || !strchr(argv[0], '=')) {
994 DEBUG(1,("Sharename or path not specified on add\n"));
995 return rpc_share_usage(argc, argv);
997 return run_rpc_command(NULL, PIPE_SRVSVC, 0,
998 rpc_share_add_internals,
1003 * Delete a share on a remote RPC server
1005 * All paramaters are provided by the run_rpc_command function, except for
1006 * argc, argv which are passes through.
1008 * @param domain_sid The domain sid acquired from the remote server
1009 * @param cli A cli_state connected to the server.
1010 * @param mem_ctx Talloc context, destoyed on completion of the function.
1011 * @param argc Standard main() style argc
1012 * @param argv Standard main() style argv. Initial components are already
1015 * @return Normal NTSTATUS return.
1018 rpc_share_del_internals(const DOM_SID *domain_sid, struct cli_state *cli,
1019 TALLOC_CTX *mem_ctx,int argc, const char **argv)
1023 result = cli_srvsvc_net_share_del(cli, mem_ctx, argv[0]);
1024 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1028 * Delete a share on a remote RPC server
1030 * @param domain_sid The domain sid acquired from the remote server
1031 * @param argc Standard main() style argc
1032 * @param argv Standard main() style argv. Initial components are already
1035 * @return A shell status integer (0 for success)
1037 static int rpc_share_delete(int argc, const char **argv)
1040 DEBUG(1,("Sharename not specified on delete\n"));
1041 return rpc_share_usage(argc, argv);
1043 return run_rpc_command(NULL, PIPE_SRVSVC, 0,
1044 rpc_share_del_internals,
1049 * Formatted print of share info
1051 * @param info1 pointer to SRV_SHARE_INFO_1 to format
1054 static void display_share_info_1(SRV_SHARE_INFO_1 *info1)
1056 fstring netname = "", remark = "";
1058 rpcstr_pull_unistr2_fstring(netname, &info1->info_1_str.uni_netname);
1059 rpcstr_pull_unistr2_fstring(remark, &info1->info_1_str.uni_remark);
1061 if (opt_long_list_entries) {
1062 d_printf("%-12.12s %-8.8s %-50.50s\n",
1063 netname, share_type[info1->info_1.type], remark);
1065 d_printf("%-12.12s\n", netname);
1071 * List shares on a remote RPC server
1073 * All paramaters are provided by the run_rpc_command function, except for
1074 * argc, argv which are passes through.
1076 * @param domain_sid The domain sid acquired from the remote server
1077 * @param cli A cli_state connected to the server.
1078 * @param mem_ctx Talloc context, destoyed on completion of the function.
1079 * @param argc Standard main() style argc
1080 * @param argv Standard main() style argv. Initial components are already
1083 * @return Normal NTSTATUS return.
1087 rpc_share_list_internals(const DOM_SID *domain_sid, struct cli_state *cli,
1088 TALLOC_CTX *mem_ctx, int argc, const char **argv)
1090 SRV_SHARE_INFO_CTR ctr;
1093 uint32 preferred_len = 0xffffffff, i;
1095 init_enum_hnd(&hnd, 0);
1097 result = cli_srvsvc_net_share_enum(
1098 cli, mem_ctx, 1, &ctr, preferred_len, &hnd);
1100 if (!W_ERROR_IS_OK(result))
1103 /* Display results */
1105 if (opt_long_list_entries) {
1107 "\nEnumerating shared resources (exports) on remote server:\n\n"\
1108 "\nShare name Type Description\n"\
1109 "---------- ---- -----------\n");
1111 for (i = 0; i < ctr.num_entries; i++)
1112 display_share_info_1(&ctr.share.info1[i]);
1114 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1118 * 'net rpc share' entrypoint.
1119 * @param argc Standard main() style argc
1120 * @param argv Standard main() style argv. Initial components are already
1124 int net_rpc_share(int argc, const char **argv)
1126 struct functable func[] = {
1127 {"add", rpc_share_add},
1128 {"delete", rpc_share_delete},
1133 return run_rpc_command(NULL, PIPE_SRVSVC, 0,
1134 rpc_share_list_internals,
1137 return net_run_function(argc, argv, func, rpc_share_usage);
1140 /****************************************************************************/
1142 static int rpc_file_usage(int argc, const char **argv)
1144 return net_help_file(argc, argv);
1148 * Close a file on a remote RPC server
1150 * All paramaters are provided by the run_rpc_command function, except for
1151 * argc, argv which are passes through.
1153 * @param domain_sid The domain sid acquired from the remote server
1154 * @param cli A cli_state connected to the server.
1155 * @param mem_ctx Talloc context, destoyed on completion of the function.
1156 * @param argc Standard main() style argc
1157 * @param argv Standard main() style argv. Initial components are already
1160 * @return Normal NTSTATUS return.
1163 rpc_file_close_internals(const DOM_SID *domain_sid, struct cli_state *cli,
1164 TALLOC_CTX *mem_ctx, int argc, const char **argv)
1167 result = cli_srvsvc_net_file_close(cli, mem_ctx, atoi(argv[0]));
1168 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1172 * Close a file on a remote RPC server
1174 * @param argc Standard main() style argc
1175 * @param argv Standard main() style argv. Initial components are already
1178 * @return A shell status integer (0 for success)
1180 static int rpc_file_close(int argc, const char **argv)
1183 DEBUG(1, ("No fileid given on close\n"));
1184 return(rpc_file_usage(argc, argv));
1187 return run_rpc_command(NULL, PIPE_SRVSVC, 0,
1188 rpc_file_close_internals,
1193 * Formatted print of open file info
1195 * @param info3 FILE_INFO_3 contents
1196 * @param str3 strings for FILE_INFO_3
1199 static void display_file_info_3(FILE_INFO_3 *info3, FILE_INFO_3_STR *str3)
1201 fstring user = "", path = "";
1203 rpcstr_pull_unistr2_fstring(user, &str3->uni_user_name);
1204 rpcstr_pull_unistr2_fstring(path, &str3->uni_path_name);
1206 d_printf("%-7.1d %-20.20s 0x%-4.2x %-6.1d %s\n",
1207 info3->id, user, info3->perms, info3->num_locks, path);
1211 * List open files on a remote RPC server
1213 * All paramaters are provided by the run_rpc_command funcion, except for
1214 * argc, argv which are passes through.
1216 * @param domain_sid The domain sid acquired from the remote server
1217 * @param cli A cli_state connected to the server.
1218 * @param mem_ctx Talloc context, destoyed on completion of the function.
1219 * @param argc Standard main() style argc
1220 * @param argv Standard main() style argv. Initial components are already
1223 * @return Normal NTSTATUS return.
1227 rpc_file_list_internals(const DOM_SID *domain_sid, struct cli_state *cli,
1228 TALLOC_CTX *mem_ctx, int argc, const char **argv)
1230 SRV_FILE_INFO_CTR ctr;
1233 uint32 preferred_len = 0xffffffff, i;
1234 const char *username=NULL;
1236 init_enum_hnd(&hnd, 0);
1238 /* if argc > 0, must be user command */
1240 username = smb_xstrdup(argv[0]);
1242 result = cli_srvsvc_net_file_enum(
1243 cli, mem_ctx, 3, username, &ctr, preferred_len, &hnd);
1245 if (!W_ERROR_IS_OK(result))
1248 /* Display results */
1251 "\nEnumerating open files on remote server:\n\n"\
1252 "\nFileId Opened by Perms Locks Path"\
1253 "\n------ --------- ----- ----- ---- \n");
1254 for (i = 0; i < ctr.num_entries; i++)
1255 display_file_info_3(&ctr.file.info3[i].info_3,
1256 &ctr.file.info3[i].info_3_str);
1258 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1263 * List files for a user on a remote RPC server
1265 * @param argc Standard main() style argc
1266 * @param argv Standard main() style argv. Initial components are already
1269 * @return A shell status integer (0 for success)
1271 static int rpc_file_user(int argc, const char **argv)
1274 DEBUG(1, ("No username given\n"));
1275 return(rpc_file_usage(argc, argv));
1278 return run_rpc_command(NULL, PIPE_SRVSVC, 0,
1279 rpc_file_list_internals,
1285 * 'net rpc file' entrypoint.
1286 * @param argc Standard main() style argc
1287 * @param argv Standard main() style argv. Initial components are already
1291 int net_rpc_file(int argc, const char **argv)
1293 struct functable func[] = {
1294 {"close", rpc_file_close},
1295 {"user", rpc_file_user},
1297 {"info", rpc_file_info},
1303 return run_rpc_command(NULL, PIPE_SRVSVC, 0,
1304 rpc_file_list_internals,
1307 return net_run_function(argc, argv, func, rpc_file_usage);
1310 /****************************************************************************/
1315 * ABORT the shutdown of a remote RPC Server
1317 * All paramaters are provided by the run_rpc_command function, except for
1318 * argc, argv which are passed through.
1320 * @param domain_sid The domain sid aquired from the remote server
1321 * @param cli A cli_state connected to the server.
1322 * @param mem_ctx Talloc context, destoyed on compleation of the function.
1323 * @param argc Standard main() style argc
1324 * @param argv Standard main() style argv. Initial components are already
1327 * @return Normal NTSTATUS return.
1330 static NTSTATUS rpc_shutdown_abort_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx,
1331 int argc, const char **argv)
1333 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1335 result = cli_reg_abort_shutdown(cli, mem_ctx);
1337 if (NT_STATUS_IS_OK(result))
1338 DEBUG(5,("cmd_reg_abort_shutdown: query succeeded\n"));
1340 DEBUG(5,("cmd_reg_abort_shutdown: query failed\n"));
1347 * ABORT the Shut down of a remote RPC server
1349 * @param argc Standard main() style argc
1350 * @param argv Standard main() style argv. Initial components are already
1353 * @return A shell status integer (0 for success)
1356 static int rpc_shutdown_abort(int argc, const char **argv)
1358 return run_rpc_command(NULL, PIPE_WINREG, 0, rpc_shutdown_abort_internals,
1363 * Shut down a remote RPC Server
1365 * All paramaters are provided by the run_rpc_command funcion, except for
1366 * argc, argv which are passes through.
1368 * @param domain_sid The domain sid aquired from the remote server
1369 * @param cli A cli_state connected to the server.
1370 * @param mem_ctx Talloc context, destoyed on compleation of the function.
1371 * @param argc Standard main() style argc
1372 * @param argc Standard main() style argv. Initial components are already
1375 * @return Normal NTSTATUS return.
1378 static NTSTATUS rpc_shutdown_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx,
1379 int argc, const char **argv)
1381 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1382 char *msg = "This machine will be shutdown shortly";
1383 uint32 timeout = 20;
1385 BOOL reboot = opt_reboot;
1386 BOOL force = opt_force;
1391 struct poptOption long_options[] = {
1392 {"message", 'm', POPT_ARG_STRING, &msg},
1393 {"timeout", 't', POPT_ARG_INT, &timeout},
1394 {"reboot", 'r', POPT_ARG_NONE, &reboot},
1395 {"force", 'f', POPT_ARG_NONE, &force},
1399 pc = poptGetContext(NULL, argc, (const char **) argv, long_options,
1400 POPT_CONTEXT_KEEP_FIRST);
1402 rc = poptGetNextOpt(pc);
1405 /* an error occurred during option processing */
1406 DEBUG(0, ("%s: %s\n",
1407 poptBadOption(pc, POPT_BADOPTION_NOALIAS),
1409 return NT_STATUS_INVALID_PARAMETER;
1413 flgs |= REG_REBOOT_ON_SHUTDOWN;
1416 flgs |= REG_FORCE_SHUTDOWN;
1422 timeout = opt_timeout;
1425 /* create an entry */
1426 result = cli_reg_shutdown(cli, mem_ctx, msg, timeout, flgs);
1428 if (NT_STATUS_IS_OK(result))
1429 DEBUG(5,("Shutdown of remote machine succeeded\n"));
1431 DEBUG(0,("Shutdown of remote machine failed!\n"));
1437 * Shut down a remote RPC server
1439 * @param argc Standard main() style argc
1440 * @param argc Standard main() style argv. Initial components are already
1443 * @return A shell status integer (0 for success)
1446 static int rpc_shutdown(int argc, const char **argv)
1448 return run_rpc_command(NULL, PIPE_WINREG, 0, rpc_shutdown_internals,
1452 /***************************************************************************
1453 NT Domain trusts code (i.e. 'net rpc trustdom' functionality)
1455 ***************************************************************************/
1458 * Add interdomain trust account to the RPC server.
1459 * All parameters (except for argc and argv) are passed by run_rpc_command
1462 * @param domain_sid The domain sid acquired from the server
1463 * @param cli A cli_state connected to the server.
1464 * @param mem_ctx Talloc context, destoyed on completion of the function.
1465 * @param argc Standard main() style argc
1466 * @param argc Standard main() style argv. Initial components are already
1469 * @return normal NTSTATUS return code
1472 static NTSTATUS rpc_trustdom_add_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx,
1473 int argc, const char **argv) {
1475 POLICY_HND connect_pol, domain_pol, user_pol;
1476 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1479 uint32 unknown, user_rid;
1482 d_printf("Usage: net rpc trustdom add <domain_name>\n");
1483 return NT_STATUS_INVALID_PARAMETER;
1487 * Make valid trusting domain account (ie. uppercased and with '$' appended)
1490 if (asprintf(&acct_name, "%s$", argv[0]) < 0) {
1491 return NT_STATUS_NO_MEMORY;
1494 strupper(acct_name);
1496 /* Get samr policy handle */
1497 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1499 if (!NT_STATUS_IS_OK(result)) {
1503 /* Get domain policy handle */
1504 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
1505 MAXIMUM_ALLOWED_ACCESS,
1506 domain_sid, &domain_pol);
1507 if (!NT_STATUS_IS_OK(result)) {
1511 /* Create trusting domain's account */
1512 acb_info = ACB_DOMTRUST;
1513 unknown = 0xe005000b; /* No idea what this is - a permission mask?
1514 mimir: yes, most probably it is */
1516 result = cli_samr_create_dom_user(cli, mem_ctx, &domain_pol,
1517 acct_name, acb_info, unknown,
1518 &user_pol, &user_rid);
1519 if (!NT_STATUS_IS_OK(result)) {
1524 SAFE_FREE(acct_name);
1529 * Create interdomain trust account for a remote domain.
1531 * @param argc standard argc
1532 * @param argv standard argv without initial components
1534 * @return Integer status (0 means success)
1537 static int rpc_trustdom_add(int argc, const char **argv)
1539 return run_rpc_command(NULL, PIPE_SAMR, 0, rpc_trustdom_add_internals,
1545 * Delete interdomain trust account for a remote domain.
1547 * @param argc standard argc
1548 * @param argv standard argv without initial components
1550 * @return Integer status (0 means success)
1553 static int rpc_trustdom_del(int argc, const char **argv)
1555 d_printf("Sorry, not yet implemented.\n");
1561 * Establish trust relationship to a trusting domain.
1562 * Interdomain account must already be created on remote PDC.
1564 * @param argc standard argc
1565 * @param argv standard argv without initial components
1567 * @return Integer status (0 means success)
1570 extern char *opt_user_name;
1571 extern char *opt_password;
1572 extern char *opt_workgroup;
1574 static int rpc_trustdom_establish(int argc, const char **argv)
1576 struct cli_state *cli;
1577 struct in_addr server_ip;
1578 POLICY_HND connect_hnd;
1579 TALLOC_CTX *mem_ctx;
1582 WKS_INFO_100 wks_info;
1589 * Connect to \\server\ipc$ as 'our domain' account with password
1593 d_printf("Usage: net rpc trustdom establish <domain_name>\n");
1597 domain_name = smb_xstrdup(argv[0]);
1598 strupper(domain_name);
1601 * opt_workgroup will be used by connection functions further,
1602 * hence it should be set to remote domain name instead of ours
1604 if (opt_workgroup) {
1605 SAFE_FREE(opt_workgroup);
1606 opt_workgroup = smb_xstrdup(domain_name);
1609 asprintf(&acct_name, "%s$", lp_workgroup());
1610 strupper(acct_name);
1612 opt_user_name = acct_name;
1614 /* find the domain controller */
1615 if (!net_find_dc(&server_ip, pdc_name, domain_name)) {
1616 DEBUG(0, ("Coulnd find domain controller for domain %s\n", domain_name));
1620 /* connect to ipc$ as username/password */
1621 nt_status = connect_to_ipc(&cli, &server_ip, pdc_name);
1622 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT)) {
1624 /* Is it trusting domain account for sure ? */
1625 DEBUG(0, ("Couldn't verify trusting domain account. Error was %s\n",
1626 nt_errstr(nt_status)));
1631 * Connect to \\server\ipc$ again (this time anonymously)
1634 nt_status = connect_to_ipc_anonymous(&cli, &server_ip, (char*)pdc_name);
1636 if (NT_STATUS_IS_ERR(nt_status)) {
1637 DEBUG(0, ("Couldn't connect to domain %s controller. Error was %s.\n",
1638 domain_name, nt_errstr(nt_status)));
1642 * Use NetServerEnum2 to make sure we're talking to a proper server
1645 if (!cli_get_pdc_name(cli, domain_name, (char*)pdc_name)) {
1646 DEBUG(0, ("NetServerEnum2 error: Couldn't find primary domain controller\
1647 for domain %s\n", domain_name));
1651 * Call WksQueryInfo to check remote server's capabilities
1652 * note: It is now used only to get unicode domain name
1655 if (!cli_nt_session_open(cli, PIPE_WKSSVC)) {
1656 DEBUG(0, ("Couldn't not initialise wkssvc pipe\n"));
1660 if (!(mem_ctx = talloc_init_named("establishing trust relationship to domain %s",
1662 DEBUG(0, ("talloc_init() failed\n"));
1667 nt_status = cli_wks_query_info(cli, mem_ctx, &wks_info);
1669 if (NT_STATUS_IS_ERR(nt_status)) {
1670 DEBUG(0, ("WksQueryInfo call failed.\n"));
1674 if (cli->nt_pipe_fnum)
1675 cli_nt_session_close(cli);
1679 * Call LsaOpenPolicy and LsaQueryInfo
1682 if (!(mem_ctx = talloc_init())) {
1683 DEBUG(0, ("talloc_init() failed\n"));
1688 if (!cli_nt_session_open(cli, PIPE_LSARPC)) {
1689 DEBUG(0, ("Could not initialise lsa pipe\n"));
1694 nt_status = cli_lsa_open_policy2(cli, mem_ctx, True, SEC_RIGHTS_QUERY_VALUE,
1696 if (NT_STATUS_IS_ERR(nt_status)) {
1697 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
1698 nt_errstr(nt_status)));
1702 /* Querying info level 5 */
1704 nt_status = cli_lsa_query_info_policy(cli, mem_ctx, &connect_hnd,
1705 5 /* info level */, domain_name,
1707 if (NT_STATUS_IS_ERR(nt_status)) {
1708 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
1709 nt_errstr(nt_status)));
1716 /* There should be actually query info level 3 (following nt serv behaviour),
1717 but I still don't know if it's _really_ necessary */
1720 * Store the password in secrets db
1723 if (!secrets_store_trusted_domain_password(domain_name, wks_info.uni_lan_grp.buffer,
1724 wks_info.uni_lan_grp.uni_str_len, opt_password,
1726 DEBUG(0, ("Storing password for trusted domain failed.\n"));
1731 * Close the pipes and clean up
1734 nt_status = cli_lsa_close(cli, mem_ctx, &connect_hnd);
1735 if (NT_STATUS_IS_ERR(nt_status)) {
1736 DEBUG(0, ("Couldn't close LSA pipe. Error was %s\n",
1737 nt_errstr(nt_status)));
1741 if (cli->nt_pipe_fnum)
1742 cli_nt_session_close(cli);
1744 talloc_destroy(mem_ctx);
1746 DEBUG(0, ("Success!\n"));
1751 * Revoke trust relationship to the remote domain
1753 * @param argc standard argc
1754 * @param argv standard argv without initial components
1756 * @return Integer status (0 means success)
1759 static int rpc_trustdom_revoke(int argc, const char **argv)
1763 if (argc < 1) return -1;
1765 /* generate upper cased domain name */
1766 domain_name = smb_xstrdup(argv[0]);
1767 strupper(domain_name);
1769 /* delete password of the trust */
1770 if (!trusted_domain_password_delete(domain_name)) {
1771 DEBUG(0, ("Failed to revoke relationship to the trusted domain %s\n",
1780 * Usage for 'net rpc trustdom' command
1782 * @param argc standard argc
1783 * @param argv standard argv without inital components
1785 * @return Integer status returned to shell
1788 static int rpc_trustdom_usage(int argc, const char **argv)
1790 d_printf(" net rpc trustdom add \t\t add trusting domain's account\n");
1791 d_printf(" net rpc trustdom del \t\t delete trusting domain's account\n");
1792 d_printf(" net rpc trustdom establish \t establish relationship to trusted domain\n");
1793 d_printf(" net rpc trustdom revoke \t abandon relationship to trusted domain\n");
1794 d_printf(" net rpc trustdom list \t show current interdomain trust relationships\n");
1799 static NTSTATUS rpc_query_domain_sid(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx,
1800 int argc, const char **argv)
1803 sid_to_string(str_sid, domain_sid);
1804 d_printf("%s\n", str_sid);
1805 return NT_STATUS_OK;
1809 extern char* opt_workgroup;
1810 extern char* opt_target_worgroup;
1811 extern char* opt_host;
1812 extern char* opt_password;
1814 static int rpc_trustdom_list(int argc, const char **argv)
1816 /* common variables */
1817 TALLOC_CTX* mem_ctx;
1818 struct cli_state *cli, *remote_cli;
1820 char *domain_name = NULL;
1821 DOM_SID queried_dom_sid;
1822 fstring ascii_sid, padding;
1823 int ascii_dom_name_len;
1824 POLICY_HND connect_hnd;
1826 /* trusted domains listing variables */
1827 int enum_ctx = 0, pref_num_domains = 5;
1828 int num_domains, i, pad_len, col_len = 20;
1829 DOM_SID *domain_sids;
1830 char **trusted_dom_names;
1833 /* trusting domains listing variables */
1834 POLICY_HND domain_hnd;
1835 char **trusting_dom_names;
1836 uint32 *trusting_dom_rids;
1839 * Listing trusted domains (stored in secrets.tdb, if local)
1842 mem_ctx = talloc_init_named("trust relationships listing");
1845 * set domain and pdc name to local samba server (default)
1846 * or to remote one given in command line
1848 strupper(opt_workgroup);
1849 if (strcmp(opt_workgroup, lp_workgroup())) {
1850 domain_name = opt_workgroup;
1851 if (opt_target_workgroup) SAFE_FREE(opt_target_workgroup);
1852 opt_target_workgroup = opt_workgroup;
1854 safe_strcpy(pdc_name, global_myname, FSTRING_LEN);
1855 domain_name = talloc_strdup(mem_ctx, lp_workgroup());
1856 if (opt_target_workgroup) SAFE_FREE(opt_target_workgroup);
1857 opt_target_workgroup = domain_name;
1860 /* open \PIPE\lsarpc and open policy handle */
1861 if (!(cli = net_make_ipc_connection(NET_FLAGS_PDC))) {
1862 DEBUG(0, ("Couldn't connect to domain controller\n"));
1866 if (!cli_nt_session_open(cli, PIPE_LSARPC)) {
1867 DEBUG(0, ("Could not initialise lsa pipe\n"));
1871 nt_status = cli_lsa_open_policy2(cli, mem_ctx, True, SEC_RIGHTS_QUERY_VALUE,
1873 if (NT_STATUS_IS_ERR(nt_status)) {
1874 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
1875 nt_errstr(nt_status)));
1879 /* query info level 5 to obtain sid of a domain being queried */
1880 nt_status = cli_lsa_query_info_policy(cli, mem_ctx, &connect_hnd,
1881 5 /* info level */, domain_name, &queried_dom_sid);
1882 if (NT_STATUS_IS_ERR(nt_status)) {
1883 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
1884 nt_errstr(nt_status)));
1889 * Keep calling LsaEnumTrustdom over opened pipe until
1890 * the end of enumeration is reached
1893 d_printf("Trusted domains list:\n\n");
1896 nt_status = cli_lsa_enum_trust_dom(cli, mem_ctx, &connect_hnd, &enum_ctx,
1897 &pref_num_domains, &num_domains,
1898 &trusted_dom_names, &domain_sids);
1900 if (NT_STATUS_IS_ERR(nt_status)) {
1901 DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
1902 nt_errstr(nt_status)));
1906 for (i = 0; i < num_domains; i++) {
1907 /* convert sid into ascii string */
1908 sid_to_string(ascii_sid, &(domain_sids[i]));
1910 /* calculate padding space for d_printf to look nicer */
1911 pad_len = col_len - strlen(trusted_dom_names[i]);
1912 padding[pad_len] = 0;
1913 do padding[--pad_len] = ' '; while (pad_len);
1915 d_printf("%s%s%s\n", trusted_dom_names[i], padding, ascii_sid);
1918 } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
1920 /* close this connection before doing next one */
1921 nt_status = cli_lsa_close(cli, mem_ctx, &connect_hnd);
1922 if (NT_STATUS_IS_ERR(nt_status)) {
1923 DEBUG(0, ("Couldn't properly close lsa policy handle. Error was %s\n",
1924 nt_errstr(nt_status)));
1928 cli_nt_session_close(cli);
1931 * Listing trusting domains (stored in passdb backend, if local)
1934 d_printf("\nTrusting domains list:\n\n");
1937 * Open \PIPE\samr and get needed policy handles
1939 if (!cli_nt_session_open(cli, PIPE_SAMR)) {
1940 DEBUG(0, ("Could not initialise samr pipe\n"));
1945 nt_status = cli_samr_connect(cli, mem_ctx, SAMR_ACCESS_OPEN_DOMAIN,
1947 if (!NT_STATUS_IS_OK(nt_status)) {
1948 DEBUG(0, ("Couldn't open SAMR policy handle. Error was %s\n",
1949 nt_errstr(nt_status)));
1953 /* SamrOpenDomain - we have to open domain policy handle in order to be
1954 able to enumerate accounts*/
1955 nt_status = cli_samr_open_domain(cli, mem_ctx, &connect_hnd,
1956 DOMAIN_ACCESS_ENUM_ACCOUNTS,
1957 &queried_dom_sid, &domain_hnd);
1958 if (!NT_STATUS_IS_OK(nt_status)) {
1959 DEBUG(0, ("Couldn't open domain object. Error was %s\n",
1960 nt_errstr(nt_status)));
1965 * perform actual enumeration
1968 enum_ctx = 0; /* reset enumeration context from last enumeration */
1971 nt_status = cli_samr_enum_dom_users(cli, mem_ctx, &domain_hnd,
1972 &enum_ctx, ACB_DOMTRUST, 0xffff,
1973 &trusting_dom_names, &trusting_dom_rids,
1975 if (NT_STATUS_IS_ERR(nt_status)) {
1976 DEBUG(0, ("Couldn't enumerate accounts. Error was: %s\n",
1977 nt_errstr(nt_status)));
1981 for (i = 0; i < num_domains; i++) {
1984 * get each single domain's sid (do we _really_ need this ?):
1985 * 1) connect to domain's pdc
1986 * 2) query the pdc for domain's sid
1989 /* get rid of '$' tail */
1990 ascii_dom_name_len = strlen(trusting_dom_names[i]);
1991 if (ascii_dom_name_len && ascii_dom_name_len < FSTRING_LEN)
1992 trusting_dom_names[i][ascii_dom_name_len - 1] = '\0';
1994 /* calculate padding space for d_printf to look nicer */
1995 pad_len = col_len - strlen(trusting_dom_names[i]);
1996 padding[pad_len] = 0;
1997 do padding[--pad_len] = ' '; while (pad_len);
1999 /* set opt_* variables to remote domain */
2000 strupper(trusting_dom_names[i]);
2001 opt_workgroup = talloc_strdup(mem_ctx, trusting_dom_names[i]);
2002 if (opt_target_workgroup) SAFE_FREE(opt_target_workgroup);
2003 opt_target_workgroup = opt_workgroup;
2005 d_printf("%s%s", trusting_dom_names[i], padding);
2007 /* connect to remote domain controller */
2008 remote_cli = net_make_ipc_connection(NET_FLAGS_PDC | NET_FLAGS_ANONYMOUS);
2010 /* query for domain's sid */
2011 if (run_rpc_command(remote_cli, PIPE_LSARPC, 0, rpc_query_domain_sid, argc, argv))
2012 d_printf("couldn't get domain's sid\n");
2014 cli_shutdown(remote_cli);
2017 d_printf("domain controller is not responding\n");
2021 } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
2023 /* close opened samr and domain policy handles */
2024 nt_status = cli_samr_close(cli, mem_ctx, &domain_hnd);
2025 if (!NT_STATUS_IS_OK(nt_status)) {
2026 DEBUG(0, ("Couldn't properly close domain policy handle for domain %s\n", domain_name));
2029 nt_status = cli_samr_close(cli, mem_ctx, &connect_hnd);
2030 if (!NT_STATUS_IS_OK(nt_status)) {
2031 DEBUG(0, ("Couldn't properly close samr policy handle for domain %s\n", domain_name));
2034 /* close samr pipe and connection to IPC$ */
2035 cli_nt_session_close(cli);
2038 talloc_destroy(mem_ctx);
2043 * Entrypoint for 'net rpc trustdom' code
2045 * @param argc standard argc
2046 * @param argv standard argv without initial components
2048 * @return Integer status (0 means success)
2051 static int rpc_trustdom(int argc, const char **argv)
2053 struct functable func[] = {
2054 {"add", rpc_trustdom_add},
2055 {"del", rpc_trustdom_del},
2056 {"establish", rpc_trustdom_establish},
2057 {"revoke", rpc_trustdom_revoke},
2058 {"help", rpc_trustdom_usage},
2059 {"list", rpc_trustdom_list},
2064 rpc_trustdom_usage(argc, argv);
2068 return (net_run_function(argc, argv, func, rpc_user_usage));
2072 * Check if a server will take rpc commands
2073 * @param flags Type of server to connect to (PDC, DMB, localhost)
2074 * if the host is not explicitly specified
2075 * @return BOOL (true means rpc supported)
2077 BOOL net_rpc_check(unsigned flags)
2079 struct cli_state cli;
2081 struct in_addr server_ip;
2082 char *server_name = NULL;
2084 /* flags (i.e. server type) may depend on command */
2085 if (!net_find_server(flags, &server_ip, &server_name))
2089 if (cli_initialise(&cli) == False)
2092 if (!cli_connect(&cli, server_name, &server_ip))
2094 if (!attempt_netbios_session_request(&cli, global_myname,
2095 server_name, &server_ip))
2097 if (!cli_negprot(&cli))
2099 if (cli.protocol < PROTOCOL_NT1)
2109 /****************************************************************************/
2113 * Basic usage function for 'net rpc'
2114 * @param argc Standard main() style argc
2115 * @param argv Standard main() style argv. Initial components are already
2119 int net_rpc_usage(int argc, const char **argv)
2121 d_printf(" net rpc info \t\t\tshow basic info about a domain \n");
2122 d_printf(" net rpc join \t\t\tto join a domain \n");
2123 d_printf(" net rpc user \t\t\tto add, delete and list users\n");
2124 d_printf(" net rpc group \t\tto list groups\n");
2125 d_printf(" net rpc share \t\tto add, delete, and list shares\n");
2126 d_printf(" net rpc file \t\t\tto list open files\n");
2127 d_printf(" net rpc changetrustpw \tto change the trust account password\n");
2128 d_printf(" net rpc trustdom \t\tto create trusting domain's account\n"
2129 "\t\t\t\t\tor establish trust\n");
2130 d_printf(" net rpc abortshutdown \tto abort the shutdown of a remote server\n");
2131 d_printf(" net rpc shutdown \t\tto shutdown a remote server\n");
2133 d_printf("'net rpc shutdown' also accepts the following miscellaneous options:\n"); /* misc options */
2134 d_printf("\t-r or --reboot\trequest remote server reboot on shutdown\n");
2135 d_printf("\t-f or --force\trequest the remote server force its shutdown\n");
2136 d_printf("\t-t or --timeout=<timeout>\tnumber of seconds before shutdown\n");
2137 d_printf("\t-c or --comment=<message>\ttext message to display on impending shutdown\n");
2143 * Help function for 'net rpc'. Calls command specific help if requested
2144 * or displays usage of net rpc
2145 * @param argc Standard main() style argc
2146 * @param argv Standard main() style argv. Initial components are already
2150 int net_rpc_help(int argc, const char **argv)
2152 struct functable func[] = {
2153 {"join", rpc_join_usage},
2154 {"user", rpc_user_usage},
2155 {"group", rpc_group_usage},
2156 {"share", rpc_share_usage},
2157 /*{"changetrustpw", rpc_changetrustpw_usage}, */
2158 {"trustdom", rpc_trustdom_usage},
2159 /*{"abortshutdown", rpc_shutdown_abort_usage},*/
2160 /*{"shutdown", rpc_shutdown_usage}, */
2165 net_rpc_usage(argc, argv);
2169 return (net_run_function(argc, argv, func, rpc_user_usage));
2174 * 'net rpc' entrypoint.
2175 * @param argc Standard main() style argc
2176 * @param argv Standard main() style argv. Initial components are already
2180 int net_rpc(int argc, const char **argv)
2182 struct functable func[] = {
2183 {"info", net_rpc_info},
2184 {"join", net_rpc_join},
2185 {"user", net_rpc_user},
2186 {"group", net_rpc_group},
2187 {"share", net_rpc_share},
2188 {"file", net_rpc_file},
2189 {"changetrustpw", rpc_changetrustpw},
2190 {"trustdom", rpc_trustdom},
2191 {"abortshutdown", rpc_shutdown_abort},
2192 {"shutdown", rpc_shutdown},
2193 {"help", net_rpc_help},
2196 return net_run_function(argc, argv, func, net_rpc_usage);