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"
27 * @brief RPC based subcommands for the 'net' utility.
29 * This file should contain much of the functionality that used to
30 * be found in rpcclient, execpt that the commands should change
31 * less often, and the fucntionality should be sane (the user is not
32 * expected to know a rid/sid before they conduct an operation etc.)
34 * @todo Perhaps eventually these should be split out into a number
35 * of files, as this could get quite big.
39 /* A function of this type is passed to the 'run_rpc_command' wrapper */
40 typedef NTSTATUS (*rpc_command_fn)(const DOM_SID *, struct cli_state *, TALLOC_CTX *, int, const char **);
43 * Many of the RPC functions need the domain sid. This function gets
44 * it at the start of every run
46 * @param cli A cli_state already connected to the remote machine
48 * @return The Domain SID of the remote machine.
51 static DOM_SID *net_get_remote_domain_sid(struct cli_state *cli)
55 NTSTATUS result = NT_STATUS_OK;
56 uint32 info_class = 5;
60 if (!(domain_sid = malloc(sizeof(DOM_SID)))){
61 DEBUG(0,("net_get_remote_domain_sid: malloc returned NULL!\n"));
65 if (!(mem_ctx=talloc_init("net_get_remote_domain_sid")))
67 DEBUG(0,("net_get_remote_domain_sid: talloc_init returned NULL!\n"));
72 if (!cli_nt_session_open (cli, PI_LSARPC)) {
73 fprintf(stderr, "could not initialise lsa pipe\n");
77 result = cli_lsa_open_policy(cli, mem_ctx, False,
78 SEC_RIGHTS_MAXIMUM_ALLOWED,
80 if (!NT_STATUS_IS_OK(result)) {
84 result = cli_lsa_query_info_policy(cli, mem_ctx, &pol, info_class,
85 domain_name, domain_sid);
86 if (!NT_STATUS_IS_OK(result)) {
90 cli_lsa_close(cli, mem_ctx, &pol);
91 cli_nt_session_close(cli);
92 talloc_destroy(mem_ctx);
97 fprintf(stderr, "could not obtain sid for domain %s\n", cli->domain);
99 if (!NT_STATUS_IS_OK(result)) {
100 fprintf(stderr, "error: %s\n", nt_errstr(result));
107 * Run a single RPC command, from start to finish.
109 * @param pipe_name the pipe to connect to (usually a PIPE_ constant)
110 * @param conn_flag a NET_FLAG_ combination. Passed to
111 * net_make_ipc_connection.
112 * @param argc Standard main() style argc
113 * @param argc Standard main() style argv. Initial components are already
115 * @return A shell status integer (0 for success)
118 static int run_rpc_command(struct cli_state *cli_arg, const int pipe_idx, int conn_flags,
120 int argc, const char **argv)
122 struct cli_state *cli = NULL;
127 /* make use of cli_state handed over as an argument, if possible */
129 cli = net_make_ipc_connection(conn_flags);
137 domain_sid = net_get_remote_domain_sid(cli);
141 if (!(mem_ctx = talloc_init("run_rpc_command"))) {
142 DEBUG(0, ("talloc_init() failed\n"));
147 if (!cli_nt_session_open(cli, pipe_idx)) {
148 DEBUG(0, ("Could not initialise pipe\n"));
151 nt_status = fn(domain_sid, cli, mem_ctx, argc, argv);
153 if (!NT_STATUS_IS_OK(nt_status)) {
154 DEBUG(1, ("rpc command function failed! (%s)\n", nt_errstr(nt_status)));
156 DEBUG(5, ("rpc command function succedded\n"));
160 if (cli->nt_pipe_fnum)
161 cli_nt_session_close(cli);
163 /* close the connection only if it was opened here */
167 talloc_destroy(mem_ctx);
169 return (!NT_STATUS_IS_OK(nt_status));
173 /****************************************************************************/
177 * Force a change of the trust acccount password.
179 * All parameters are provided by the run_rpc_command function, except for
180 * argc, argv which are passes through.
182 * @param domain_sid The domain sid aquired from the remote server
183 * @param cli A cli_state connected to the server.
184 * @param mem_ctx Talloc context, destoyed on compleation of the function.
185 * @param argc Standard main() style argc
186 * @param argc Standard main() style argv. Initial components are already
189 * @return Normal NTSTATUS return.
192 static NTSTATUS rpc_changetrustpw_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx,
193 int argc, const char **argv) {
195 return trust_pw_find_change_and_store_it(cli, mem_ctx, opt_target_workgroup);
199 * Force a change of the trust acccount password.
201 * @param argc Standard main() style argc
202 * @param argc Standard main() style argv. Initial components are already
205 * @return A shell status integer (0 for success)
208 int net_rpc_changetrustpw(int argc, const char **argv)
210 return run_rpc_command(NULL, PI_NETLOGON, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, rpc_changetrustpw_internals,
215 /****************************************************************************/
219 * Join a domain, the old way.
221 * This uses 'machinename' as the inital password, and changes it.
223 * The password should be created with 'server manager' or equiv first.
225 * All parameters are provided by the run_rpc_command function, except for
226 * argc, argv which are passes through.
228 * @param domain_sid The domain sid aquired from the remote server
229 * @param cli A cli_state connected to the server.
230 * @param mem_ctx Talloc context, destoyed on compleation of the function.
231 * @param argc Standard main() style argc
232 * @param argc Standard main() style argv. Initial components are already
235 * @return Normal NTSTATUS return.
238 static NTSTATUS rpc_oldjoin_internals(const DOM_SID *domain_sid, struct cli_state *cli,
240 int argc, const char **argv) {
242 fstring trust_passwd;
243 unsigned char orig_trust_passwd_hash[16];
245 uint32 sec_channel_type;
248 check what type of join - if the user want's to join as
249 a BDC, the server must agree that we are a BDC.
252 sec_channel_type = get_sec_channel_type(argv[0]);
254 sec_channel_type = get_sec_channel_type(NULL);
257 fstrcpy(trust_passwd, global_myname());
258 strlower_m(trust_passwd);
261 * Machine names can be 15 characters, but the max length on
262 * a password is 14. --jerry
265 trust_passwd[14] = '\0';
267 E_md4hash(trust_passwd, orig_trust_passwd_hash);
269 result = trust_pw_change_and_store_it(cli, mem_ctx, opt_target_workgroup,
270 orig_trust_passwd_hash,
273 if (NT_STATUS_IS_OK(result))
274 printf("Joined domain %s.\n",opt_target_workgroup);
277 if (!secrets_store_domain_sid(opt_target_workgroup, domain_sid)) {
278 DEBUG(0, ("error storing domain sid for %s\n", opt_target_workgroup));
279 result = NT_STATUS_UNSUCCESSFUL;
286 * Join a domain, the old way.
288 * @param argc Standard main() style argc
289 * @param argc Standard main() style argv. Initial components are already
292 * @return A shell status integer (0 for success)
295 static int net_rpc_oldjoin(int argc, const char **argv)
297 return run_rpc_command(NULL, PI_NETLOGON,
298 NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC,
299 rpc_oldjoin_internals,
304 * Basic usage function for 'net rpc join'
305 * @param argc Standard main() style argc
306 * @param argc Standard main() style argv. Initial components are already
310 static int rpc_join_usage(int argc, const char **argv)
312 d_printf("net rpc join -U <username>[%%password] <type>[options]\n"\
313 "\t to join a domain with admin username & password\n"\
314 "\t\t password will be prompted if needed and none is specified\n"\
315 "\t <type> can be (default MEMBER)\n"\
316 "\t\t BDC - Join as a BDC\n"\
317 "\t\t PDC - Join as a PDC\n"\
318 "\t\t MEMBER - Join as a MEMBER server\n");
320 net_common_flags_usage(argc, argv);
325 * 'net rpc join' entrypoint.
326 * @param argc Standard main() style argc
327 * @param argc Standard main() style argv. Initial components are already
330 * Main 'net_rpc_join()' (where the admain username/password is used) is
332 * Try to just change the password, but if that doesn't work, use/prompt
333 * for a username/password.
336 int net_rpc_join(int argc, const char **argv)
338 if ((net_rpc_oldjoin(argc, argv) == 0))
341 return net_rpc_join_newstyle(argc, argv);
347 * display info about a rpc domain
349 * All parameters are provided by the run_rpc_command function, except for
350 * argc, argv which are passed through.
352 * @param domain_sid The domain sid acquired from the remote server
353 * @param cli A cli_state connected to the server.
354 * @param mem_ctx Talloc context, destoyed on completion of the function.
355 * @param argc Standard main() style argc
356 * @param argv Standard main() style argv. Initial components are already
359 * @return Normal NTSTATUS return.
363 rpc_info_internals(const DOM_SID *domain_sid, struct cli_state *cli,
364 TALLOC_CTX *mem_ctx, int argc, const char **argv)
366 POLICY_HND connect_pol, domain_pol;
367 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
371 sid_to_string(sid_str, domain_sid);
373 /* Get sam policy handle */
374 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
376 if (!NT_STATUS_IS_OK(result)) {
380 /* Get domain policy handle */
381 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
382 MAXIMUM_ALLOWED_ACCESS,
383 domain_sid, &domain_pol);
384 if (!NT_STATUS_IS_OK(result)) {
389 result = cli_samr_query_dom_info(cli, mem_ctx, &domain_pol,
391 if (NT_STATUS_IS_OK(result)) {
392 TALLOC_CTX *ctx = talloc_init("rpc_info_internals");
393 d_printf("Domain Name: %s\n", unistr2_tdup(ctx, &ctr.info.inf2.uni_domain));
394 d_printf("Domain SID: %s\n", sid_str);
395 d_printf("Sequence number: %u\n", ctr.info.inf2.seq_num);
396 d_printf("Num users: %u\n", ctr.info.inf2.num_domain_usrs);
397 d_printf("Num domain groups: %u\n", ctr.info.inf2.num_domain_grps);
398 d_printf("Num local groups: %u\n", ctr.info.inf2.num_local_grps);
408 * 'net rpc info' entrypoint.
409 * @param argc Standard main() style argc
410 * @param argc Standard main() style argv. Initial components are already
413 int net_rpc_info(int argc, const char **argv)
415 return run_rpc_command(NULL, PI_SAMR, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC,
422 * Fetch domain SID into the local secrets.tdb
424 * All parameters are provided by the run_rpc_command function, except for
425 * argc, argv which are passes through.
427 * @param domain_sid The domain sid acquired from the remote server
428 * @param cli A cli_state connected to the server.
429 * @param mem_ctx Talloc context, destoyed on completion of the function.
430 * @param argc Standard main() style argc
431 * @param argv Standard main() style argv. Initial components are already
434 * @return Normal NTSTATUS return.
438 rpc_getsid_internals(const DOM_SID *domain_sid, struct cli_state *cli,
439 TALLOC_CTX *mem_ctx, int argc, const char **argv)
443 sid_to_string(sid_str, domain_sid);
444 d_printf("Storing SID %s for Domain %s in secrets.tdb\n",
445 sid_str, lp_workgroup());
447 if (!secrets_store_domain_sid(global_myname(), domain_sid)) {
448 DEBUG(0,("Can't store domain SID\n"));
449 return NT_STATUS_UNSUCCESSFUL;
457 * 'net rpc getsid' entrypoint.
458 * @param argc Standard main() style argc
459 * @param argc Standard main() style argv. Initial components are already
462 int net_rpc_getsid(int argc, const char **argv)
464 return run_rpc_command(NULL, PI_SAMR, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC,
465 rpc_getsid_internals,
470 /****************************************************************************/
473 * Basic usage function for 'net rpc user'
474 * @param argc Standard main() style argc.
475 * @param argv Standard main() style argv. Initial components are already
479 static int rpc_user_usage(int argc, const char **argv)
481 return net_help_user(argc, argv);
485 * Add a new user to a remote RPC server
487 * All parameters are provided by the run_rpc_command function, 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
497 * @return Normal NTSTATUS return.
500 static NTSTATUS rpc_user_add_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx,
501 int argc, const char **argv) {
503 POLICY_HND connect_pol, domain_pol, user_pol;
504 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
505 const char *acct_name;
507 uint32 unknown, user_rid;
510 d_printf("User must be specified\n");
511 rpc_user_usage(argc, argv);
517 /* Get sam policy handle */
519 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
521 if (!NT_STATUS_IS_OK(result)) {
525 /* Get domain policy handle */
527 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
528 MAXIMUM_ALLOWED_ACCESS,
529 domain_sid, &domain_pol);
530 if (!NT_STATUS_IS_OK(result)) {
534 /* Create domain user */
536 acb_info = ACB_NORMAL;
537 unknown = 0xe005000b; /* No idea what this is - a permission mask? */
539 result = cli_samr_create_dom_user(cli, mem_ctx, &domain_pol,
540 acct_name, acb_info, unknown,
541 &user_pol, &user_rid);
542 if (!NT_STATUS_IS_OK(result)) {
547 if (!NT_STATUS_IS_OK(result)) {
548 d_printf("Failed to add user %s - %s\n", acct_name,
551 d_printf("Added user %s\n", acct_name);
557 * Add a new user to a remote RPC server
559 * @param argc Standard main() style argc
560 * @param argv Standard main() style argv. Initial components are already
563 * @return A shell status integer (0 for success)
566 static int rpc_user_add(int argc, const char **argv)
568 return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_add_internals,
573 * Delete a user from a remote RPC server
575 * All parameters are provided by the run_rpc_command function, except for
576 * argc, argv which are passes through.
578 * @param domain_sid The domain sid acquired from the remote server
579 * @param cli A cli_state connected to the server.
580 * @param mem_ctx Talloc context, destoyed on completion of the function.
581 * @param argc Standard main() style argc
582 * @param argv Standard main() style argv. Initial components are already
585 * @return Normal NTSTATUS return.
588 static NTSTATUS rpc_user_del_internals(const DOM_SID *domain_sid,
589 struct cli_state *cli,
591 int argc, const char **argv)
593 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
594 POLICY_HND connect_pol, domain_pol, user_pol;
597 d_printf("User must be specified\n");
598 rpc_user_usage(argc, argv);
601 /* Get sam policy and domain handles */
603 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
606 if (!NT_STATUS_IS_OK(result)) {
610 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
611 MAXIMUM_ALLOWED_ACCESS,
612 domain_sid, &domain_pol);
614 if (!NT_STATUS_IS_OK(result)) {
618 /* Get handle on user */
621 uint32 *user_rids, num_rids, *name_types;
622 uint32 flags = 0x000003e8; /* Unknown */
624 result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol,
626 &num_rids, &user_rids,
629 if (!NT_STATUS_IS_OK(result)) {
633 result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
634 MAXIMUM_ALLOWED_ACCESS,
635 user_rids[0], &user_pol);
637 if (!NT_STATUS_IS_OK(result)) {
644 result = cli_samr_delete_dom_user(cli, mem_ctx, &user_pol);
646 if (!NT_STATUS_IS_OK(result)) {
650 /* Display results */
658 * Delete a user from a remote RPC server
660 * @param argc Standard main() style argc
661 * @param argv Standard main() style argv. Initial components are already
664 * @return A shell status integer (0 for success)
667 static int rpc_user_delete(int argc, const char **argv)
669 return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_del_internals,
674 * List user's groups on a remote RPC server
676 * All parameters are provided by the run_rpc_command function, except for
677 * argc, argv which are passes through.
679 * @param domain_sid The domain sid acquired from the remote server
680 * @param cli A cli_state connected to the server.
681 * @param mem_ctx Talloc context, destoyed on completion of the function.
682 * @param argc Standard main() style argc
683 * @param argv Standard main() style argv. Initial components are already
686 * @return Normal NTSTATUS return.
690 rpc_user_info_internals(const DOM_SID *domain_sid, struct cli_state *cli,
691 TALLOC_CTX *mem_ctx, int argc, const char **argv)
693 POLICY_HND connect_pol, domain_pol, user_pol;
694 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
695 uint32 *rids, num_rids, *name_types, num_names;
696 uint32 flags = 0x000003e8; /* Unknown */
702 d_printf("User must be specified\n");
703 rpc_user_usage(argc, argv);
706 /* Get sam policy handle */
708 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
710 if (!NT_STATUS_IS_OK(result)) goto done;
712 /* Get domain policy handle */
714 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
715 MAXIMUM_ALLOWED_ACCESS,
716 domain_sid, &domain_pol);
717 if (!NT_STATUS_IS_OK(result)) goto done;
719 /* Get handle on user */
721 result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol,
723 &num_rids, &rids, &name_types);
725 if (!NT_STATUS_IS_OK(result)) goto done;
727 result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
728 MAXIMUM_ALLOWED_ACCESS,
730 if (!NT_STATUS_IS_OK(result)) goto done;
732 result = cli_samr_query_usergroups(cli, mem_ctx, &user_pol,
733 &num_rids, &user_gids);
737 rids = (uint32 *)talloc(mem_ctx, sizeof(uint32) * num_rids);
739 for (i = 0; i < num_rids; i++)
740 rids[i] = user_gids[i].g_rid;
742 result = cli_samr_lookup_rids(cli, mem_ctx, &domain_pol,
743 flags, num_rids, rids,
744 &num_names, &names, &name_types);
746 if (!NT_STATUS_IS_OK(result)) {
750 /* Display results */
752 for (i = 0; i < num_names; i++)
753 printf("%s\n", names[i]);
760 * List a user's groups from a remote RPC server
762 * @param argc Standard main() style argc
763 * @param argv Standard main() style argv. Initial components are already
766 * @return A shell status integer (0 for success)
769 static int rpc_user_info(int argc, const char **argv)
771 return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_info_internals,
776 * List users on a remote RPC server
778 * All parameters are provided by the run_rpc_command function, except for
779 * argc, argv which are passes through.
781 * @param domain_sid The domain sid acquired from the remote server
782 * @param cli A cli_state connected to the server.
783 * @param mem_ctx Talloc context, destoyed on completion of the function.
784 * @param argc Standard main() style argc
785 * @param argv Standard main() style argv. Initial components are already
788 * @return Normal NTSTATUS return.
792 rpc_user_list_internals(const DOM_SID *domain_sid, struct cli_state *cli,
793 TALLOC_CTX *mem_ctx, int argc, const char **argv)
795 POLICY_HND connect_pol, domain_pol;
796 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
797 uint32 start_idx=0, num_entries, i, loop_count = 0;
798 SAM_DISPINFO_CTR ctr;
799 SAM_DISPINFO_1 info1;
801 /* Get sam policy handle */
803 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
805 if (!NT_STATUS_IS_OK(result)) {
809 /* Get domain policy handle */
811 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
812 MAXIMUM_ALLOWED_ACCESS,
813 domain_sid, &domain_pol);
814 if (!NT_STATUS_IS_OK(result)) {
818 /* Query domain users */
821 ctr.sam.info1 = &info1;
822 if (opt_long_list_entries)
823 d_printf("\nUser name Comment"\
824 "\n-----------------------------\n");
827 uint32 max_entries, max_size;
829 get_query_dispinfo_params(
830 loop_count, &max_entries, &max_size);
832 result = cli_samr_query_dispinfo(cli, mem_ctx, &domain_pol,
833 &start_idx, 1, &num_entries,
834 max_entries, max_size, &ctr);
837 for (i = 0; i < num_entries; i++) {
838 unistr2_to_ascii(user, &(&ctr.sam.info1->str[i])->uni_acct_name, sizeof(user)-1);
839 if (opt_long_list_entries)
840 unistr2_to_ascii(desc, &(&ctr.sam.info1->str[i])->uni_acct_desc, sizeof(desc)-1);
842 if (opt_long_list_entries)
843 printf("%-21.21s %s\n", user, desc);
845 printf("%s\n", user);
847 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
854 * 'net rpc user' entrypoint.
855 * @param argc Standard main() style argc
856 * @param argc Standard main() style argv. Initial components are already
860 int net_rpc_user(int argc, const char **argv)
862 struct functable func[] = {
863 {"add", rpc_user_add},
864 {"info", rpc_user_info},
865 {"delete", rpc_user_delete},
870 if (opt_long_list_entries) {
873 return run_rpc_command(NULL,PI_SAMR, 0,
874 rpc_user_list_internals,
878 return net_run_function(argc, argv, func, rpc_user_usage);
882 /****************************************************************************/
885 * Basic usage function for 'net rpc group'
886 * @param argc Standard main() style argc.
887 * @param argv Standard main() style argv. Initial components are already
891 static int rpc_group_usage(int argc, const char **argv)
893 return net_help_group(argc, argv);
897 * List groups on a remote RPC server
899 * All parameters are provided by the run_rpc_command function, except for
900 * argc, argv which are passes through.
902 * @param domain_sid The domain sid acquired from the remote server
903 * @param cli A cli_state connected to the server.
904 * @param mem_ctx Talloc context, destoyed on completion of the function.
905 * @param argc Standard main() style argc
906 * @param argv Standard main() style argv. Initial components are already
909 * @return Normal NTSTATUS return.
913 rpc_group_list_internals(const DOM_SID *domain_sid, struct cli_state *cli,
914 TALLOC_CTX *mem_ctx, int argc, const char **argv)
916 POLICY_HND connect_pol, domain_pol;
917 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
918 uint32 start_idx=0, max_entries=250, num_entries, i, loop_count = 0;
919 struct acct_info *groups;
920 DOM_SID global_sid_Builtin;
922 string_to_sid(&global_sid_Builtin, "S-1-5-32");
924 /* Get sam policy handle */
926 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
928 if (!NT_STATUS_IS_OK(result)) {
932 /* Get domain policy handle */
934 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
935 MAXIMUM_ALLOWED_ACCESS,
936 domain_sid, &domain_pol);
937 if (!NT_STATUS_IS_OK(result)) {
941 /* Query domain groups */
942 if (opt_long_list_entries)
943 d_printf("\nGroup name Comment"\
944 "\n-----------------------------\n");
946 SAM_DISPINFO_CTR ctr;
947 SAM_DISPINFO_3 info3;
952 ctr.sam.info3 = &info3;
954 get_query_dispinfo_params(
955 loop_count, &max_entries, &max_size);
957 result = cli_samr_query_dispinfo(cli, mem_ctx, &domain_pol,
958 &start_idx, 3, &num_entries,
959 max_entries, max_size, &ctr);
961 for (i = 0; i < num_entries; i++) {
965 unistr2_to_ascii(group, &(&ctr.sam.info3->str[i])->uni_grp_name, sizeof(group)-1);
966 unistr2_to_ascii(desc, &(&ctr.sam.info3->str[i])->uni_grp_desc, sizeof(desc)-1);
968 if (opt_long_list_entries)
969 printf("%-21.21s %-50.50s\n",
972 printf("%-21.21s\n", group);
974 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
975 /* query domain aliases */
978 result = cli_samr_enum_als_groups(cli, mem_ctx, &domain_pol,
979 &start_idx, max_entries,
980 &groups, &num_entries);
982 for (i = 0; i < num_entries; i++) {
984 char *description = NULL;
986 if (opt_long_list_entries) {
988 POLICY_HND alias_pol;
991 if ((NT_STATUS_IS_OK(cli_samr_open_alias(cli, mem_ctx,
996 (NT_STATUS_IS_OK(cli_samr_query_alias_info(cli, mem_ctx,
999 (NT_STATUS_IS_OK(cli_samr_close(cli, mem_ctx,
1001 description = unistr2_tdup(mem_ctx,
1002 &ctr.alias.info3.uni_acct_desc);
1006 if (description != NULL) {
1007 printf("%-21.21s %-50.50s\n",
1008 groups[i].acct_name,
1011 printf("%-21.21s\n", groups[i].acct_name);
1014 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
1015 cli_samr_close(cli, mem_ctx, &domain_pol);
1016 /* Get builtin policy handle */
1018 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
1019 MAXIMUM_ALLOWED_ACCESS,
1020 &global_sid_Builtin, &domain_pol);
1021 if (!NT_STATUS_IS_OK(result)) {
1024 /* query builtin aliases */
1027 result = cli_samr_enum_als_groups(cli, mem_ctx, &domain_pol,
1028 &start_idx, max_entries,
1029 &groups, &num_entries);
1031 for (i = 0; i < num_entries; i++) {
1033 char *description = NULL;
1035 if (opt_long_list_entries) {
1037 POLICY_HND alias_pol;
1040 if ((NT_STATUS_IS_OK(cli_samr_open_alias(cli, mem_ctx,
1045 (NT_STATUS_IS_OK(cli_samr_query_alias_info(cli, mem_ctx,
1048 (NT_STATUS_IS_OK(cli_samr_close(cli, mem_ctx,
1050 description = unistr2_tdup(mem_ctx,
1051 &ctr.alias.info3.uni_acct_desc);
1055 if (description != NULL) {
1056 printf("%-21.21s %-50.50s\n",
1057 groups[i].acct_name,
1060 printf("%-21.21s\n", groups[i].acct_name);
1063 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
1070 * 'net rpc group' entrypoint.
1071 * @param argc Standard main() style argc
1072 * @param argc Standard main() style argv. Initial components are already
1076 int net_rpc_group(int argc, const char **argv)
1078 struct functable func[] = {
1080 {"add", rpc_group_add},
1081 {"delete", rpc_group_delete},
1087 if (opt_long_list_entries) {
1090 return run_rpc_command(NULL, PI_SAMR, 0,
1091 rpc_group_list_internals,
1095 return net_run_function(argc, argv, func, rpc_group_usage);
1098 /****************************************************************************/
1100 static int rpc_share_usage(int argc, const char **argv)
1102 return net_help_share(argc, argv);
1106 * Add a share on a remote RPC server
1108 * All parameters are provided by the run_rpc_command function, except for
1109 * argc, argv which are passes through.
1111 * @param domain_sid The domain sid acquired from the remote server
1112 * @param cli A cli_state connected to the server.
1113 * @param mem_ctx Talloc context, destoyed on completion of the function.
1114 * @param argc Standard main() style argc
1115 * @param argv Standard main() style argv. Initial components are already
1118 * @return Normal NTSTATUS return.
1121 rpc_share_add_internals(const DOM_SID *domain_sid, struct cli_state *cli,
1122 TALLOC_CTX *mem_ctx,int argc, const char **argv)
1125 char *sharename=talloc_strdup(mem_ctx, argv[0]);
1127 uint32 type=0; /* only allow disk shares to be added */
1128 uint32 num_users=0, perms=0;
1129 char *password=NULL; /* don't allow a share password */
1131 path = strchr(sharename, '=');
1133 return NT_STATUS_UNSUCCESSFUL;
1136 result = cli_srvsvc_net_share_add(cli, mem_ctx, sharename, type,
1137 opt_comment, perms, opt_maxusers,
1138 num_users, path, password);
1139 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1142 static int rpc_share_add(int argc, const char **argv)
1144 if ((argc < 1) || !strchr(argv[0], '=')) {
1145 DEBUG(1,("Sharename or path not specified on add\n"));
1146 return rpc_share_usage(argc, argv);
1148 return run_rpc_command(NULL, PI_SRVSVC, 0,
1149 rpc_share_add_internals,
1154 * Delete a share on a remote RPC server
1156 * All parameters are provided by the run_rpc_command function, except for
1157 * argc, argv which are passes through.
1159 * @param domain_sid The domain sid acquired from the remote server
1160 * @param cli A cli_state connected to the server.
1161 * @param mem_ctx Talloc context, destoyed on completion of the function.
1162 * @param argc Standard main() style argc
1163 * @param argv Standard main() style argv. Initial components are already
1166 * @return Normal NTSTATUS return.
1169 rpc_share_del_internals(const DOM_SID *domain_sid, struct cli_state *cli,
1170 TALLOC_CTX *mem_ctx,int argc, const char **argv)
1174 result = cli_srvsvc_net_share_del(cli, mem_ctx, argv[0]);
1175 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1179 * Delete a share on a remote RPC server
1181 * @param domain_sid The domain sid acquired from the remote server
1182 * @param argc Standard main() style argc
1183 * @param argv Standard main() style argv. Initial components are already
1186 * @return A shell status integer (0 for success)
1188 static int rpc_share_delete(int argc, const char **argv)
1191 DEBUG(1,("Sharename not specified on delete\n"));
1192 return rpc_share_usage(argc, argv);
1194 return run_rpc_command(NULL, PI_SRVSVC, 0,
1195 rpc_share_del_internals,
1200 * Formatted print of share info
1202 * @param info1 pointer to SRV_SHARE_INFO_1 to format
1205 static void display_share_info_1(SRV_SHARE_INFO_1 *info1)
1207 fstring netname = "", remark = "";
1209 rpcstr_pull_unistr2_fstring(netname, &info1->info_1_str.uni_netname);
1210 rpcstr_pull_unistr2_fstring(remark, &info1->info_1_str.uni_remark);
1212 if (opt_long_list_entries) {
1213 d_printf("%-12.12s %-8.8s %-50.50s\n",
1214 netname, share_type[info1->info_1.type], remark);
1216 d_printf("%-12.12s\n", netname);
1222 * List shares on a remote RPC server
1224 * All parameters are provided by the run_rpc_command function, except for
1225 * argc, argv which are passes through.
1227 * @param domain_sid The domain sid acquired from the remote server
1228 * @param cli A cli_state connected to the server.
1229 * @param mem_ctx Talloc context, destoyed on completion of the function.
1230 * @param argc Standard main() style argc
1231 * @param argv Standard main() style argv. Initial components are already
1234 * @return Normal NTSTATUS return.
1238 rpc_share_list_internals(const DOM_SID *domain_sid, struct cli_state *cli,
1239 TALLOC_CTX *mem_ctx, int argc, const char **argv)
1241 SRV_SHARE_INFO_CTR ctr;
1244 uint32 preferred_len = 0xffffffff, i;
1246 init_enum_hnd(&hnd, 0);
1248 result = cli_srvsvc_net_share_enum(
1249 cli, mem_ctx, 1, &ctr, preferred_len, &hnd);
1251 if (!W_ERROR_IS_OK(result))
1254 /* Display results */
1256 if (opt_long_list_entries) {
1258 "\nEnumerating shared resources (exports) on remote server:\n\n"\
1259 "\nShare name Type Description\n"\
1260 "---------- ---- -----------\n");
1262 for (i = 0; i < ctr.num_entries; i++)
1263 display_share_info_1(&ctr.share.info1[i]);
1265 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1269 * 'net rpc share' entrypoint.
1270 * @param argc Standard main() style argc
1271 * @param argv Standard main() style argv. Initial components are already
1275 int net_rpc_share(int argc, const char **argv)
1277 struct functable func[] = {
1278 {"add", rpc_share_add},
1279 {"delete", rpc_share_delete},
1284 return run_rpc_command(NULL, PI_SRVSVC, 0,
1285 rpc_share_list_internals,
1288 return net_run_function(argc, argv, func, rpc_share_usage);
1291 /****************************************************************************/
1293 static int rpc_file_usage(int argc, const char **argv)
1295 return net_help_file(argc, argv);
1299 * Close a file on a remote RPC server
1301 * All parameters are provided by the run_rpc_command function, except for
1302 * argc, argv which are passes through.
1304 * @param domain_sid The domain sid acquired from the remote server
1305 * @param cli A cli_state connected to the server.
1306 * @param mem_ctx Talloc context, destoyed on completion of the function.
1307 * @param argc Standard main() style argc
1308 * @param argv Standard main() style argv. Initial components are already
1311 * @return Normal NTSTATUS return.
1314 rpc_file_close_internals(const DOM_SID *domain_sid, struct cli_state *cli,
1315 TALLOC_CTX *mem_ctx, int argc, const char **argv)
1318 result = cli_srvsvc_net_file_close(cli, mem_ctx, atoi(argv[0]));
1319 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1323 * Close a file on a remote RPC server
1325 * @param argc Standard main() style argc
1326 * @param argv Standard main() style argv. Initial components are already
1329 * @return A shell status integer (0 for success)
1331 static int rpc_file_close(int argc, const char **argv)
1334 DEBUG(1, ("No fileid given on close\n"));
1335 return(rpc_file_usage(argc, argv));
1338 return run_rpc_command(NULL, PI_SRVSVC, 0,
1339 rpc_file_close_internals,
1344 * Formatted print of open file info
1346 * @param info3 FILE_INFO_3 contents
1347 * @param str3 strings for FILE_INFO_3
1350 static void display_file_info_3(FILE_INFO_3 *info3, FILE_INFO_3_STR *str3)
1352 fstring user = "", path = "";
1354 rpcstr_pull_unistr2_fstring(user, &str3->uni_user_name);
1355 rpcstr_pull_unistr2_fstring(path, &str3->uni_path_name);
1357 d_printf("%-7.1d %-20.20s 0x%-4.2x %-6.1d %s\n",
1358 info3->id, user, info3->perms, info3->num_locks, path);
1362 * List open files on a remote RPC server
1364 * All parameters are provided by the run_rpc_command function, except for
1365 * argc, argv which are passes through.
1367 * @param domain_sid The domain sid acquired from the remote server
1368 * @param cli A cli_state connected to the server.
1369 * @param mem_ctx Talloc context, destoyed on completion of the function.
1370 * @param argc Standard main() style argc
1371 * @param argv Standard main() style argv. Initial components are already
1374 * @return Normal NTSTATUS return.
1378 rpc_file_list_internals(const DOM_SID *domain_sid, struct cli_state *cli,
1379 TALLOC_CTX *mem_ctx, int argc, const char **argv)
1381 SRV_FILE_INFO_CTR ctr;
1384 uint32 preferred_len = 0xffffffff, i;
1385 const char *username=NULL;
1387 init_enum_hnd(&hnd, 0);
1389 /* if argc > 0, must be user command */
1391 username = smb_xstrdup(argv[0]);
1393 result = cli_srvsvc_net_file_enum(
1394 cli, mem_ctx, 3, username, &ctr, preferred_len, &hnd);
1396 if (!W_ERROR_IS_OK(result))
1399 /* Display results */
1402 "\nEnumerating open files on remote server:\n\n"\
1403 "\nFileId Opened by Perms Locks Path"\
1404 "\n------ --------- ----- ----- ---- \n");
1405 for (i = 0; i < ctr.num_entries; i++)
1406 display_file_info_3(&ctr.file.info3[i].info_3,
1407 &ctr.file.info3[i].info_3_str);
1409 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1414 * List files for a user on a remote RPC server
1416 * @param argc Standard main() style argc
1417 * @param argv Standard main() style argv. Initial components are already
1420 * @return A shell status integer (0 for success)
1422 static int rpc_file_user(int argc, const char **argv)
1425 DEBUG(1, ("No username given\n"));
1426 return(rpc_file_usage(argc, argv));
1429 return run_rpc_command(NULL, PI_SRVSVC, 0,
1430 rpc_file_list_internals,
1436 * 'net rpc file' entrypoint.
1437 * @param argc Standard main() style argc
1438 * @param argv Standard main() style argv. Initial components are already
1442 int net_rpc_file(int argc, const char **argv)
1444 struct functable func[] = {
1445 {"close", rpc_file_close},
1446 {"user", rpc_file_user},
1448 {"info", rpc_file_info},
1454 return run_rpc_command(NULL, PI_SRVSVC, 0,
1455 rpc_file_list_internals,
1458 return net_run_function(argc, argv, func, rpc_file_usage);
1461 /****************************************************************************/
1466 * ABORT the shutdown of a remote RPC Server
1468 * All parameters are provided by the run_rpc_command function, except for
1469 * argc, argv which are passed through.
1471 * @param domain_sid The domain sid aquired from the remote server
1472 * @param cli A cli_state connected to the server.
1473 * @param mem_ctx Talloc context, destoyed on compleation of the function.
1474 * @param argc Standard main() style argc
1475 * @param argv Standard main() style argv. Initial components are already
1478 * @return Normal NTSTATUS return.
1481 static NTSTATUS rpc_shutdown_abort_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx,
1482 int argc, const char **argv)
1484 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1486 result = cli_reg_abort_shutdown(cli, mem_ctx);
1488 if (NT_STATUS_IS_OK(result))
1489 DEBUG(5,("cmd_reg_abort_shutdown: query succeeded\n"));
1491 DEBUG(5,("cmd_reg_abort_shutdown: query failed\n"));
1498 * ABORT the Shut down of a remote RPC server
1500 * @param argc Standard main() style argc
1501 * @param argv Standard main() style argv. Initial components are already
1504 * @return A shell status integer (0 for success)
1507 static int rpc_shutdown_abort(int argc, const char **argv)
1509 return run_rpc_command(NULL, PI_WINREG, 0, rpc_shutdown_abort_internals,
1514 * Shut down a remote RPC Server
1516 * All parameters are provided by the run_rpc_command function, except for
1517 * argc, argv which are passes through.
1519 * @param domain_sid The domain sid aquired from the remote server
1520 * @param cli A cli_state connected to the server.
1521 * @param mem_ctx Talloc context, destoyed on compleation of the function.
1522 * @param argc Standard main() style argc
1523 * @param argc Standard main() style argv. Initial components are already
1526 * @return Normal NTSTATUS return.
1529 static NTSTATUS rpc_shutdown_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx,
1530 int argc, const char **argv)
1532 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1533 const char *msg = "This machine will be shutdown shortly";
1534 uint32 timeout = 20;
1539 struct poptOption long_options[] = {
1540 {"message", 'm', POPT_ARG_STRING, &msg},
1541 {"timeout", 't', POPT_ARG_INT, &timeout},
1542 {"reboot", 'r', POPT_ARG_NONE, &reboot},
1543 {"force", 'f', POPT_ARG_NONE, &force},
1547 pc = poptGetContext(NULL, argc, (const char **) argv, long_options,
1548 POPT_CONTEXT_KEEP_FIRST);
1550 rc = poptGetNextOpt(pc);
1553 /* an error occurred during option processing */
1554 DEBUG(0, ("%s: %s\n",
1555 poptBadOption(pc, POPT_BADOPTION_NOALIAS),
1557 return NT_STATUS_INVALID_PARAMETER;
1564 timeout = opt_timeout;
1567 /* create an entry */
1568 result = cli_reg_shutdown(cli, mem_ctx, msg, timeout, opt_reboot, opt_force);
1570 if (NT_STATUS_IS_OK(result))
1571 DEBUG(5,("Shutdown of remote machine succeeded\n"));
1573 DEBUG(0,("Shutdown of remote machine failed!\n"));
1579 * Shut down a remote RPC server
1581 * @param argc Standard main() style argc
1582 * @param argc Standard main() style argv. Initial components are already
1585 * @return A shell status integer (0 for success)
1588 static int rpc_shutdown(int argc, const char **argv)
1590 return run_rpc_command(NULL, PI_WINREG, 0, rpc_shutdown_internals,
1594 /***************************************************************************
1595 NT Domain trusts code (i.e. 'net rpc trustdom' functionality)
1597 ***************************************************************************/
1600 * Add interdomain trust account to the RPC server.
1601 * All parameters (except for argc and argv) are passed by run_rpc_command
1604 * @param domain_sid The domain sid acquired from the server
1605 * @param cli A cli_state connected to the server.
1606 * @param mem_ctx Talloc context, destoyed on completion of the function.
1607 * @param argc Standard main() style argc
1608 * @param argc Standard main() style argv. Initial components are already
1611 * @return normal NTSTATUS return code
1614 static NTSTATUS rpc_trustdom_add_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx,
1615 int argc, const char **argv) {
1617 POLICY_HND connect_pol, domain_pol, user_pol;
1618 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1621 uint32 unknown, user_rid;
1624 d_printf("Usage: net rpc trustdom add <domain_name> <pw>\n");
1625 return NT_STATUS_INVALID_PARAMETER;
1629 * Make valid trusting domain account (ie. uppercased and with '$' appended)
1632 if (asprintf(&acct_name, "%s$", argv[0]) < 0) {
1633 return NT_STATUS_NO_MEMORY;
1636 strupper_m(acct_name);
1638 /* Get samr policy handle */
1639 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1641 if (!NT_STATUS_IS_OK(result)) {
1645 /* Get domain policy handle */
1646 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
1647 MAXIMUM_ALLOWED_ACCESS,
1648 domain_sid, &domain_pol);
1649 if (!NT_STATUS_IS_OK(result)) {
1653 /* Create trusting domain's account */
1654 acb_info = ACB_DOMTRUST;
1655 unknown = 0xe00500b0; /* No idea what this is - a permission mask?
1656 mimir: yes, most probably it is */
1658 result = cli_samr_create_dom_user(cli, mem_ctx, &domain_pol,
1659 acct_name, acb_info, unknown,
1660 &user_pol, &user_rid);
1661 if (!NT_STATUS_IS_OK(result)) {
1666 SAM_USERINFO_CTR ctr;
1667 SAM_USER_INFO_24 p24;
1668 fstring ucs2_trust_password;
1672 ucs2_pw_len = push_ucs2(NULL, ucs2_trust_password, argv[1],
1673 sizeof(ucs2_trust_password), 0);
1675 encode_pw_buffer((char *)pwbuf, ucs2_trust_password,
1681 init_sam_user_info24(&p24, (char *)pwbuf, 24);
1683 ctr.switch_value = 24;
1684 ctr.info.id24 = &p24;
1686 result = cli_samr_set_userinfo(cli, mem_ctx, &user_pol, 24,
1687 cli->user_session_key, &ctr);
1689 if (!NT_STATUS_IS_OK(result)) {
1690 DEBUG(0,("Could not set trust account password: %s\n",
1691 nt_errstr(result)));
1697 SAFE_FREE(acct_name);
1702 * Create interdomain trust account for a remote domain.
1704 * @param argc standard argc
1705 * @param argv standard argv without initial components
1707 * @return Integer status (0 means success)
1710 static int rpc_trustdom_add(int argc, const char **argv)
1712 return run_rpc_command(NULL, PI_SAMR, 0, rpc_trustdom_add_internals,
1718 * Delete interdomain trust account for a remote domain.
1720 * @param argc standard argc
1721 * @param argv standard argv without initial components
1723 * @return Integer status (0 means success)
1726 static int rpc_trustdom_del(int argc, const char **argv)
1728 d_printf("Sorry, not yet implemented.\n");
1734 * Establish trust relationship to a trusting domain.
1735 * Interdomain account must already be created on remote PDC.
1737 * @param argc standard argc
1738 * @param argv standard argv without initial components
1740 * @return Integer status (0 means success)
1743 static int rpc_trustdom_establish(int argc, const char **argv)
1745 struct cli_state *cli;
1746 struct in_addr server_ip;
1747 POLICY_HND connect_hnd;
1748 TALLOC_CTX *mem_ctx;
1751 WKS_INFO_100 wks_info;
1758 * Connect to \\server\ipc$ as 'our domain' account with password
1762 d_printf("Usage: net rpc trustdom establish <domain_name>\n");
1766 domain_name = smb_xstrdup(argv[0]);
1767 strupper_m(domain_name);
1769 /* account name used at first is our domain's name with '$' */
1770 asprintf(&acct_name, "%s$", lp_workgroup());
1771 strupper_m(acct_name);
1774 * opt_workgroup will be used by connection functions further,
1775 * hence it should be set to remote domain name instead of ours
1777 if (opt_workgroup) {
1778 opt_workgroup = smb_xstrdup(domain_name);
1781 opt_user_name = acct_name;
1783 /* find the domain controller */
1784 if (!net_find_pdc(&server_ip, pdc_name, domain_name)) {
1785 DEBUG(0, ("Coulnd find domain controller for domain %s\n", domain_name));
1789 /* connect to ipc$ as username/password */
1790 nt_status = connect_to_ipc(&cli, &server_ip, pdc_name);
1791 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT)) {
1793 /* Is it trusting domain account for sure ? */
1794 DEBUG(0, ("Couldn't verify trusting domain account. Error was %s\n",
1795 nt_errstr(nt_status)));
1800 * Connect to \\server\ipc$ again (this time anonymously)
1803 nt_status = connect_to_ipc_anonymous(&cli, &server_ip, (char*)pdc_name);
1805 if (NT_STATUS_IS_ERR(nt_status)) {
1806 DEBUG(0, ("Couldn't connect to domain %s controller. Error was %s.\n",
1807 domain_name, nt_errstr(nt_status)));
1811 * Use NetServerEnum2 to make sure we're talking to a proper server
1814 if (!cli_get_pdc_name(cli, domain_name, (char*)pdc_name)) {
1815 DEBUG(0, ("NetServerEnum2 error: Couldn't find primary domain controller\
1816 for domain %s\n", domain_name));
1820 * Call WksQueryInfo to check remote server's capabilities
1821 * note: It is now used only to get unicode domain name
1824 if (!cli_nt_session_open(cli, PI_WKSSVC)) {
1825 DEBUG(0, ("Couldn't not initialise wkssvc pipe\n"));
1829 if (!(mem_ctx = talloc_init("establishing trust relationship to domain %s",
1831 DEBUG(0, ("talloc_init() failed\n"));
1836 nt_status = cli_wks_query_info(cli, mem_ctx, &wks_info);
1838 if (NT_STATUS_IS_ERR(nt_status)) {
1839 DEBUG(0, ("WksQueryInfo call failed.\n"));
1843 if (cli->nt_pipe_fnum)
1844 cli_nt_session_close(cli);
1848 * Call LsaOpenPolicy and LsaQueryInfo
1851 if (!(mem_ctx = talloc_init("rpc_trustdom_establish"))) {
1852 DEBUG(0, ("talloc_init() failed\n"));
1857 if (!cli_nt_session_open(cli, PI_LSARPC)) {
1858 DEBUG(0, ("Could not initialise lsa pipe\n"));
1863 nt_status = cli_lsa_open_policy2(cli, mem_ctx, True, SEC_RIGHTS_QUERY_VALUE,
1865 if (NT_STATUS_IS_ERR(nt_status)) {
1866 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
1867 nt_errstr(nt_status)));
1871 /* Querying info level 5 */
1873 nt_status = cli_lsa_query_info_policy(cli, mem_ctx, &connect_hnd,
1874 5 /* info level */, domain_name,
1876 if (NT_STATUS_IS_ERR(nt_status)) {
1877 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
1878 nt_errstr(nt_status)));
1885 /* There should be actually query info level 3 (following nt serv behaviour),
1886 but I still don't know if it's _really_ necessary */
1889 * Store the password in secrets db
1892 if (!secrets_store_trusted_domain_password(domain_name, wks_info.uni_lan_grp.buffer,
1893 wks_info.uni_lan_grp.uni_str_len, opt_password,
1895 DEBUG(0, ("Storing password for trusted domain failed.\n"));
1900 * Close the pipes and clean up
1903 nt_status = cli_lsa_close(cli, mem_ctx, &connect_hnd);
1904 if (NT_STATUS_IS_ERR(nt_status)) {
1905 DEBUG(0, ("Couldn't close LSA pipe. Error was %s\n",
1906 nt_errstr(nt_status)));
1910 if (cli->nt_pipe_fnum)
1911 cli_nt_session_close(cli);
1913 talloc_destroy(mem_ctx);
1915 DEBUG(0, ("Success!\n"));
1920 * Revoke trust relationship to the remote domain
1922 * @param argc standard argc
1923 * @param argv standard argv without initial components
1925 * @return Integer status (0 means success)
1928 static int rpc_trustdom_revoke(int argc, const char **argv)
1932 if (argc < 1) return -1;
1934 /* generate upper cased domain name */
1935 domain_name = smb_xstrdup(argv[0]);
1936 strupper_m(domain_name);
1938 /* delete password of the trust */
1939 if (!trusted_domain_password_delete(domain_name)) {
1940 DEBUG(0, ("Failed to revoke relationship to the trusted domain %s\n",
1949 * Usage for 'net rpc trustdom' command
1951 * @param argc standard argc
1952 * @param argv standard argv without inital components
1954 * @return Integer status returned to shell
1957 static int rpc_trustdom_usage(int argc, const char **argv)
1959 d_printf(" net rpc trustdom add \t\t add trusting domain's account\n");
1960 d_printf(" net rpc trustdom del \t\t delete trusting domain's account\n");
1961 d_printf(" net rpc trustdom establish \t establish relationship to trusted domain\n");
1962 d_printf(" net rpc trustdom revoke \t abandon relationship to trusted domain\n");
1963 d_printf(" net rpc trustdom list \t show current interdomain trust relationships\n");
1968 static NTSTATUS rpc_query_domain_sid(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx,
1969 int argc, const char **argv)
1972 sid_to_string(str_sid, domain_sid);
1973 d_printf("%s\n", str_sid);
1974 return NT_STATUS_OK;
1978 static int rpc_trustdom_list(int argc, const char **argv)
1980 /* common variables */
1981 TALLOC_CTX* mem_ctx;
1982 struct cli_state *cli, *remote_cli;
1984 const char *domain_name = NULL;
1985 DOM_SID queried_dom_sid;
1986 fstring ascii_sid, padding;
1987 int ascii_dom_name_len;
1988 POLICY_HND connect_hnd;
1990 /* trusted domains listing variables */
1992 int num_domains, i, pad_len, col_len = 20;
1993 DOM_SID *domain_sids;
1994 char **trusted_dom_names;
1995 fstring pdc_name, dummy;
1997 /* trusting domains listing variables */
1998 POLICY_HND domain_hnd;
1999 char **trusting_dom_names;
2000 uint32 *trusting_dom_rids;
2003 * Listing trusted domains (stored in secrets.tdb, if local)
2006 mem_ctx = talloc_init("trust relationships listing");
2009 * set domain and pdc name to local samba server (default)
2010 * or to remote one given in command line
2013 if (StrCaseCmp(opt_workgroup, lp_workgroup())) {
2014 domain_name = opt_workgroup;
2015 opt_target_workgroup = opt_workgroup;
2017 fstrcpy(pdc_name, global_myname());
2018 domain_name = talloc_strdup(mem_ctx, lp_workgroup());
2019 opt_target_workgroup = domain_name;
2022 /* open \PIPE\lsarpc and open policy handle */
2023 if (!(cli = net_make_ipc_connection(NET_FLAGS_PDC))) {
2024 DEBUG(0, ("Couldn't connect to domain controller\n"));
2028 if (!cli_nt_session_open(cli, PI_LSARPC)) {
2029 DEBUG(0, ("Could not initialise lsa pipe\n"));
2033 nt_status = cli_lsa_open_policy2(cli, mem_ctx, False, SEC_RIGHTS_QUERY_VALUE,
2035 if (NT_STATUS_IS_ERR(nt_status)) {
2036 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
2037 nt_errstr(nt_status)));
2041 /* query info level 5 to obtain sid of a domain being queried */
2042 nt_status = cli_lsa_query_info_policy(
2043 cli, mem_ctx, &connect_hnd, 5 /* info level */,
2044 dummy, &queried_dom_sid);
2046 if (NT_STATUS_IS_ERR(nt_status)) {
2047 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
2048 nt_errstr(nt_status)));
2053 * Keep calling LsaEnumTrustdom over opened pipe until
2054 * the end of enumeration is reached
2057 d_printf("Trusted domains list:\n\n");
2060 nt_status = cli_lsa_enum_trust_dom(cli, mem_ctx, &connect_hnd, &enum_ctx,
2062 &trusted_dom_names, &domain_sids);
2064 if (NT_STATUS_IS_ERR(nt_status)) {
2065 DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
2066 nt_errstr(nt_status)));
2070 for (i = 0; i < num_domains; i++) {
2071 /* convert sid into ascii string */
2072 sid_to_string(ascii_sid, &(domain_sids[i]));
2074 /* calculate padding space for d_printf to look nicer */
2075 pad_len = col_len - strlen(trusted_dom_names[i]);
2076 padding[pad_len] = 0;
2077 do padding[--pad_len] = ' '; while (pad_len);
2079 d_printf("%s%s%s\n", trusted_dom_names[i], padding, ascii_sid);
2083 * in case of no trusted domains say something rather
2084 * than just display blank line
2086 if (!num_domains) d_printf("none\n");
2088 } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
2090 /* close this connection before doing next one */
2091 nt_status = cli_lsa_close(cli, mem_ctx, &connect_hnd);
2092 if (NT_STATUS_IS_ERR(nt_status)) {
2093 DEBUG(0, ("Couldn't properly close lsa policy handle. Error was %s\n",
2094 nt_errstr(nt_status)));
2098 cli_nt_session_close(cli);
2101 * Listing trusting domains (stored in passdb backend, if local)
2104 d_printf("\nTrusting domains list:\n\n");
2107 * Open \PIPE\samr and get needed policy handles
2109 if (!cli_nt_session_open(cli, PI_SAMR)) {
2110 DEBUG(0, ("Could not initialise samr pipe\n"));
2115 nt_status = cli_samr_connect(cli, mem_ctx, SA_RIGHT_SAM_OPEN_DOMAIN,
2117 if (!NT_STATUS_IS_OK(nt_status)) {
2118 DEBUG(0, ("Couldn't open SAMR policy handle. Error was %s\n",
2119 nt_errstr(nt_status)));
2123 /* SamrOpenDomain - we have to open domain policy handle in order to be
2124 able to enumerate accounts*/
2125 nt_status = cli_samr_open_domain(cli, mem_ctx, &connect_hnd,
2126 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
2127 &queried_dom_sid, &domain_hnd);
2128 if (!NT_STATUS_IS_OK(nt_status)) {
2129 DEBUG(0, ("Couldn't open domain object. Error was %s\n",
2130 nt_errstr(nt_status)));
2135 * perform actual enumeration
2138 enum_ctx = 0; /* reset enumeration context from last enumeration */
2141 nt_status = cli_samr_enum_dom_users(cli, mem_ctx, &domain_hnd,
2142 &enum_ctx, ACB_DOMTRUST, 0xffff,
2143 &trusting_dom_names, &trusting_dom_rids,
2145 if (NT_STATUS_IS_ERR(nt_status)) {
2146 DEBUG(0, ("Couldn't enumerate accounts. Error was: %s\n",
2147 nt_errstr(nt_status)));
2151 for (i = 0; i < num_domains; i++) {
2154 * get each single domain's sid (do we _really_ need this ?):
2155 * 1) connect to domain's pdc
2156 * 2) query the pdc for domain's sid
2159 /* get rid of '$' tail */
2160 ascii_dom_name_len = strlen(trusting_dom_names[i]);
2161 if (ascii_dom_name_len && ascii_dom_name_len < FSTRING_LEN)
2162 trusting_dom_names[i][ascii_dom_name_len - 1] = '\0';
2164 /* calculate padding space for d_printf to look nicer */
2165 pad_len = col_len - strlen(trusting_dom_names[i]);
2166 padding[pad_len] = 0;
2167 do padding[--pad_len] = ' '; while (pad_len);
2169 /* set opt_* variables to remote domain */
2170 strupper_m(trusting_dom_names[i]);
2171 opt_workgroup = talloc_strdup(mem_ctx, trusting_dom_names[i]);
2172 opt_target_workgroup = opt_workgroup;
2174 d_printf("%s%s", trusting_dom_names[i], padding);
2176 /* connect to remote domain controller */
2177 remote_cli = net_make_ipc_connection(NET_FLAGS_PDC | NET_FLAGS_ANONYMOUS);
2179 /* query for domain's sid */
2180 if (run_rpc_command(remote_cli, PI_LSARPC, 0, rpc_query_domain_sid, argc, argv))
2181 d_printf("couldn't get domain's sid\n");
2183 cli_shutdown(remote_cli);
2186 d_printf("domain controller is not responding\n");
2190 if (!num_domains) d_printf("none\n");
2192 } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
2194 /* close opened samr and domain policy handles */
2195 nt_status = cli_samr_close(cli, mem_ctx, &domain_hnd);
2196 if (!NT_STATUS_IS_OK(nt_status)) {
2197 DEBUG(0, ("Couldn't properly close domain policy handle for domain %s\n", domain_name));
2200 nt_status = cli_samr_close(cli, mem_ctx, &connect_hnd);
2201 if (!NT_STATUS_IS_OK(nt_status)) {
2202 DEBUG(0, ("Couldn't properly close samr policy handle for domain %s\n", domain_name));
2205 /* close samr pipe and connection to IPC$ */
2206 cli_nt_session_close(cli);
2209 talloc_destroy(mem_ctx);
2214 * Entrypoint for 'net rpc trustdom' code
2216 * @param argc standard argc
2217 * @param argv standard argv without initial components
2219 * @return Integer status (0 means success)
2222 static int rpc_trustdom(int argc, const char **argv)
2224 struct functable func[] = {
2225 {"add", rpc_trustdom_add},
2226 {"del", rpc_trustdom_del},
2227 {"establish", rpc_trustdom_establish},
2228 {"revoke", rpc_trustdom_revoke},
2229 {"help", rpc_trustdom_usage},
2230 {"list", rpc_trustdom_list},
2235 rpc_trustdom_usage(argc, argv);
2239 return (net_run_function(argc, argv, func, rpc_user_usage));
2243 * Check if a server will take rpc commands
2244 * @param flags Type of server to connect to (PDC, DMB, localhost)
2245 * if the host is not explicitly specified
2246 * @return BOOL (true means rpc supported)
2248 BOOL net_rpc_check(unsigned flags)
2250 struct cli_state cli;
2252 struct in_addr server_ip;
2253 char *server_name = NULL;
2255 /* flags (i.e. server type) may depend on command */
2256 if (!net_find_server(flags, &server_ip, &server_name))
2260 if (cli_initialise(&cli) == False)
2263 if (!cli_connect(&cli, server_name, &server_ip))
2265 if (!attempt_netbios_session_request(&cli, global_myname(),
2266 server_name, &server_ip))
2268 if (!cli_negprot(&cli))
2270 if (cli.protocol < PROTOCOL_NT1)
2280 /****************************************************************************/
2284 * Basic usage function for 'net rpc'
2285 * @param argc Standard main() style argc
2286 * @param argv Standard main() style argv. Initial components are already
2290 int net_rpc_usage(int argc, const char **argv)
2292 d_printf(" net rpc info \t\t\tshow basic info about a domain \n");
2293 d_printf(" net rpc join \t\t\tto join a domain \n");
2294 d_printf(" net rpc oldjoin \t\t\tto join a domain created in server manager\n\n\n");
2295 d_printf(" net rpc testjoin \t\ttests that a join is valid\n");
2296 d_printf(" net rpc user \t\t\tto add, delete and list users\n");
2297 d_printf(" net rpc group \t\tto list groups\n");
2298 d_printf(" net rpc share \t\tto add, delete, and list shares\n");
2299 d_printf(" net rpc file \t\t\tto list open files\n");
2300 d_printf(" net rpc changetrustpw \tto change the trust account password\n");
2301 d_printf(" net rpc getsid \t\tfetch the domain sid into the local secrets.tdb\n");
2302 d_printf(" net rpc vampire \t\tsyncronise an NT PDC's users and groups into the local passdb\n");
2303 d_printf(" net rpc samdump \t\tdiplay an NT PDC's users, groups and other data\n");
2304 d_printf(" net rpc trustdom \t\tto create trusting domain's account\n"
2305 "\t\t\t\t\tor establish trust\n");
2306 d_printf(" net rpc abortshutdown \tto abort the shutdown of a remote server\n");
2307 d_printf(" net rpc shutdown \t\tto shutdown a remote server\n");
2309 d_printf("'net rpc shutdown' also accepts the following miscellaneous options:\n"); /* misc options */
2310 d_printf("\t-r or --reboot\trequest remote server reboot on shutdown\n");
2311 d_printf("\t-f or --force\trequest the remote server force its shutdown\n");
2312 d_printf("\t-t or --timeout=<timeout>\tnumber of seconds before shutdown\n");
2313 d_printf("\t-c or --comment=<message>\ttext message to display on impending shutdown\n");
2319 * Help function for 'net rpc'. Calls command specific help if requested
2320 * or displays usage of net rpc
2321 * @param argc Standard main() style argc
2322 * @param argv Standard main() style argv. Initial components are already
2326 int net_rpc_help(int argc, const char **argv)
2328 struct functable func[] = {
2329 {"join", rpc_join_usage},
2330 {"user", rpc_user_usage},
2331 {"group", rpc_group_usage},
2332 {"share", rpc_share_usage},
2333 /*{"changetrustpw", rpc_changetrustpw_usage}, */
2334 {"trustdom", rpc_trustdom_usage},
2335 /*{"abortshutdown", rpc_shutdown_abort_usage},*/
2336 /*{"shutdown", rpc_shutdown_usage}, */
2341 net_rpc_usage(argc, argv);
2345 return (net_run_function(argc, argv, func, rpc_user_usage));
2350 * 'net rpc' entrypoint.
2351 * @param argc Standard main() style argc
2352 * @param argv Standard main() style argv. Initial components are already
2356 int net_rpc(int argc, const char **argv)
2358 struct functable func[] = {
2359 {"info", net_rpc_info},
2360 {"join", net_rpc_join},
2361 {"oldjoin", net_rpc_oldjoin},
2362 {"testjoin", net_rpc_testjoin},
2363 {"user", net_rpc_user},
2364 {"group", net_rpc_group},
2365 {"share", net_rpc_share},
2366 {"file", net_rpc_file},
2367 {"changetrustpw", net_rpc_changetrustpw},
2368 {"trustdom", rpc_trustdom},
2369 {"abortshutdown", rpc_shutdown_abort},
2370 {"shutdown", rpc_shutdown},
2371 {"samdump", rpc_samdump},
2372 {"vampire", rpc_vampire},
2373 {"getsid", net_rpc_getsid},
2374 {"help", net_rpc_help},
2377 return net_run_function(argc, argv, func, net_rpc_usage);