2 Samba Unix/Linux SMB client library
3 Distributed SMB/CIFS Server Management Utility
4 Copyright (C) 2001 Andrew Bartlett (abartlet@samba.org)
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
21 #include "../utils/net.h"
23 extern pstring global_myname;
28 * @brief RPC based subcommands for the 'net' utility.
30 * This file should contain much of the functionality that used to
31 * be found in rpcclient, execpt that the commands should change
32 * less often, and the fucntionality should be sane (the user is not
33 * expected to know a rid/sid before they conduct an operation etc.)
35 * @todo Perhaps eventually these should be split out into a number
36 * of files, as this could get quite big.
40 /* A function of this type is passed to the 'run_rpc_command' wrapper */
41 typedef NTSTATUS (*rpc_command_fn)(const DOM_SID *, struct cli_state *, TALLOC_CTX *, int, const char **);
44 * Many of the RPC functions need the domain sid. This function gets
45 * it at the start of every run
47 * @param cli A cli_state already connected to the remote machine
49 * @return The Domain SID of the remote machine.
52 static DOM_SID *net_get_remote_domain_sid(struct cli_state *cli)
56 NTSTATUS result = NT_STATUS_OK;
57 uint32 info_class = 5;
61 if (!(domain_sid = malloc(sizeof(DOM_SID)))){
62 DEBUG(0,("fetch_domain_sid: malloc returned NULL!\n"));
66 if (!(mem_ctx=talloc_init()))
68 DEBUG(0,("fetch_domain_sid: talloc_init returned NULL!\n"));
73 if (!cli_nt_session_open (cli, PIPE_LSARPC)) {
74 fprintf(stderr, "could not initialise lsa pipe\n");
78 result = cli_lsa_open_policy(cli, mem_ctx, True,
79 SEC_RIGHTS_MAXIMUM_ALLOWED,
81 if (!NT_STATUS_IS_OK(result)) {
85 result = cli_lsa_query_info_policy(cli, mem_ctx, &pol, info_class,
86 domain_name, domain_sid);
87 if (!NT_STATUS_IS_OK(result)) {
91 cli_lsa_close(cli, mem_ctx, &pol);
92 cli_nt_session_close(cli);
93 talloc_destroy(mem_ctx);
98 fprintf(stderr, "could not obtain sid for domain %s\n", cli->domain);
100 if (!NT_STATUS_IS_OK(result)) {
101 fprintf(stderr, "error: %s\n", nt_errstr(result));
108 * Run a single RPC command, from start to finish.
110 * @param pipe_name the pipe to connect to (usually a PIPE_ constant)
111 * @param conn_flag a NET_FLAG_ combination. Passed to
112 * net_make_ipc_connection.
113 * @param argc Standard main() style argc
114 * @param argc Standard main() style argv. Initial components are already
116 * @return A shell status integer (0 for success)
119 static int run_rpc_command(const char *pipe_name, int conn_flags,
121 int argc, const char **argv)
123 struct cli_state *cli = net_make_ipc_connection(conn_flags);
132 domain_sid = net_get_remote_domain_sid(cli);
136 if (!(mem_ctx = talloc_init())) {
137 DEBUG(0, ("talloc_init() failed\n"));
142 if (!cli_nt_session_open(cli, pipe_name)) {
143 DEBUG(0, ("Could not initialise samr pipe\n"));
146 nt_status = fn(domain_sid, cli, mem_ctx, argc, argv);
148 if (!NT_STATUS_IS_OK(nt_status)) {
149 DEBUG(0, ("rpc command function failed! (%s)\n", nt_errstr(nt_status)));
151 DEBUG(5, ("rpc command function succedded\n"));
155 if (cli->nt_pipe_fnum)
156 cli_nt_session_close(cli);
158 talloc_destroy(mem_ctx);
160 return (!NT_STATUS_IS_OK(nt_status));
164 /****************************************************************************/
168 * Force a change of the trust acccount password.
170 * All paramaters are provided by the run_rpc_command funcion, except for
171 * argc, argv which are passes through.
173 * @param domain_sid The domain sid aquired from the remote server
174 * @param cli A cli_state connected to the server.
175 * @param mem_ctx Talloc context, destoyed on compleation of the function.
176 * @param argc Standard main() style argc
177 * @param argc Standard main() style argv. Initial components are already
180 * @return Normal NTSTATUS return.
183 static NTSTATUS rpc_changetrustpw_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx,
184 int argc, const char **argv) {
186 return trust_pw_find_change_and_store_it(cli, mem_ctx, opt_target_workgroup);
190 * Force a change of the trust acccount password.
192 * @param argc Standard main() style argc
193 * @param argc Standard main() style argv. Initial components are already
196 * @return A shell status integer (0 for success)
199 static int rpc_changetrustpw(int argc, const char **argv)
201 return run_rpc_command(PIPE_NETLOGON, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, rpc_changetrustpw_internals,
206 /****************************************************************************/
210 * Join a domain, the old way.
212 * This uses 'machinename' as the inital password, and changes it.
214 * The password should be created with 'server manager' or eqiv first.
216 * All paramaters are provided by the run_rpc_command funcion, except for
217 * argc, argv which are passes through.
219 * @param domain_sid The domain sid aquired from the remote server
220 * @param cli A cli_state connected to the server.
221 * @param mem_ctx Talloc context, destoyed on compleation of the function.
222 * @param argc Standard main() style argc
223 * @param argc Standard main() style argv. Initial components are already
226 * @return Normal NTSTATUS return.
229 static NTSTATUS rpc_join_oldstyle_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx,
230 int argc, const char **argv) {
232 extern pstring global_myname;
233 fstring trust_passwd;
234 unsigned char orig_trust_passwd_hash[16];
236 fstrcpy(trust_passwd, global_myname);
237 strlower(trust_passwd);
238 E_md4hash( (uchar *)trust_passwd, orig_trust_passwd_hash);
240 return trust_pw_change_and_store_it(cli, mem_ctx, orig_trust_passwd_hash);
244 * Join a domain, the old way.
246 * @param argc Standard main() style argc
247 * @param argc Standard main() style argv. Initial components are already
250 * @return A shell status integer (0 for success)
253 static int net_rpc_join_oldstyle(int argc, const char **argv)
255 return run_rpc_command(PIPE_NETLOGON, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, rpc_join_oldstyle_internals,
260 * Basic usage function for 'net rpc join'
261 * @param argc Standard main() style argc
262 * @param argc Standard main() style argv. Initial components are already
266 static int rpc_join_usage(int argc, const char **argv)
268 d_printf("net rpc join -U <username>[%%password] [options]\n"\
269 "\t to join a domain with admin username & password\n"\
270 "\t\t password will be prompted if none is specified\n");
271 d_printf("net rpc join [options except -U]\n"\
272 "\t to join a domain created in server manager\n\n\n");
274 net_common_flags_usage(argc, argv);
279 * 'net rpc join' entrypoint.
280 * @param argc Standard main() style argc
281 * @param argc Standard main() style argv. Initial components are already
284 * Main 'net_rpc_join()' (where the admain username/password is used) is
286 * Assume if a -U is specified, it's the new style, otherwise it's the
290 int net_rpc_join(int argc, const char **argv)
292 if ((net_rpc_join_oldstyle(argc, argv) == 0))
295 return net_rpc_join_newstyle(argc, argv);
299 /****************************************************************************/
302 * Basic usage function for 'net rpc user'
303 * @param argc Standard main() style argc.
304 * @param argv Standard main() style argv. Initial components are already
308 static int rpc_user_usage(int argc, const char **argv)
310 return net_help_user(argc, argv);
314 * Add a new user to a remote RPC server
316 * All paramaters are provided by the run_rpc_command funcion, except for
317 * argc, argv which are passes through.
319 * @param domain_sid The domain sid acquired from the remote server
320 * @param cli A cli_state connected to the server.
321 * @param mem_ctx Talloc context, destoyed on completion of the function.
322 * @param argc Standard main() style argc
323 * @param argv Standard main() style argv. Initial components are already
326 * @return Normal NTSTATUS return.
329 static NTSTATUS rpc_user_add_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx,
330 int argc, const char **argv) {
332 POLICY_HND connect_pol, domain_pol, user_pol;
333 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
334 const char *acct_name;
336 uint32 unknown, user_rid;
339 d_printf("User must be specified\n");
340 rpc_user_usage(argc, argv);
346 /* Get sam policy handle */
348 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
350 if (!NT_STATUS_IS_OK(result)) {
354 /* Get domain policy handle */
356 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
357 MAXIMUM_ALLOWED_ACCESS,
358 domain_sid, &domain_pol);
359 if (!NT_STATUS_IS_OK(result)) {
363 /* Create domain user */
365 acb_info = ACB_NORMAL;
366 unknown = 0xe005000b; /* No idea what this is - a permission mask? */
368 result = cli_samr_create_dom_user(cli, mem_ctx, &domain_pol,
369 acct_name, acb_info, unknown,
370 &user_pol, &user_rid);
371 if (!NT_STATUS_IS_OK(result)) {
376 if (!NT_STATUS_IS_OK(result)) {
377 d_printf("Failed to add user %s - %s\n", acct_name,
380 d_printf("Added user %s\n", acct_name);
386 * Add a new user to a remote RPC server
388 * @param argc Standard main() style argc
389 * @param argv Standard main() style argv. Initial components are already
392 * @return A shell status integer (0 for success)
395 static int rpc_user_add(int argc, const char **argv)
397 return run_rpc_command(PIPE_SAMR, 0, rpc_user_add_internals,
402 * Delete a user from a remote RPC server
404 * All paramaters are provided by the run_rpc_command funcion, except for
405 * argc, argv which are passes through.
407 * @param domain_sid The domain sid acquired from the remote server
408 * @param cli A cli_state connected to the server.
409 * @param mem_ctx Talloc context, destoyed on completion of the function.
410 * @param argc Standard main() style argc
411 * @param argv Standard main() style argv. Initial components are already
414 * @return Normal NTSTATUS return.
417 static NTSTATUS rpc_user_del_internals(const DOM_SID *domain_sid,
418 struct cli_state *cli,
420 int argc, const char **argv)
422 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
423 POLICY_HND connect_pol, domain_pol, user_pol;
426 d_printf("User must be specified\n");
427 rpc_user_usage(argc, argv);
430 /* Get sam policy and domain handles */
432 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
435 if (!NT_STATUS_IS_OK(result)) {
439 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
440 MAXIMUM_ALLOWED_ACCESS,
441 domain_sid, &domain_pol);
443 if (!NT_STATUS_IS_OK(result)) {
447 /* Get handle on user */
450 uint32 *user_rids, num_rids, *name_types;
451 uint32 flags = 0x000003e8; /* Unknown */
453 result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol,
454 flags, 1, (char **) &argv[0],
455 &num_rids, &user_rids,
458 if (!NT_STATUS_IS_OK(result)) {
462 result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
463 MAXIMUM_ALLOWED_ACCESS,
464 user_rids[0], &user_pol);
466 if (!NT_STATUS_IS_OK(result)) {
473 result = cli_samr_delete_dom_user(cli, mem_ctx, &user_pol);
475 if (!NT_STATUS_IS_OK(result)) {
479 /* Display results */
487 * Delete a user from a remote RPC server
489 * @param argc Standard main() style argc
490 * @param argv Standard main() style argv. Initial components are already
493 * @return A shell status integer (0 for success)
496 static int rpc_user_delete(int argc, const char **argv)
498 return run_rpc_command(PIPE_SAMR, 0, rpc_user_del_internals,
503 * List user's groups on a remote RPC server
505 * All paramaters are provided by the run_rpc_command funcion, except for
506 * argc, argv which are passes through.
508 * @param domain_sid The domain sid acquired from the remote server
509 * @param cli A cli_state connected to the server.
510 * @param mem_ctx Talloc context, destoyed on completion of the function.
511 * @param argc Standard main() style argc
512 * @param argv Standard main() style argv. Initial components are already
515 * @return Normal NTSTATUS return.
519 rpc_user_info_internals(const DOM_SID *domain_sid, struct cli_state *cli,
520 TALLOC_CTX *mem_ctx, int argc, const char **argv)
522 POLICY_HND connect_pol, domain_pol, user_pol;
523 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
524 uint32 *rids, num_rids, *name_types, num_names;
525 uint32 flags = 0x000003e8; /* Unknown */
531 d_printf("User must be specified\n");
532 rpc_user_usage(argc, argv);
535 /* Get sam policy handle */
537 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
539 if (!NT_STATUS_IS_OK(result)) goto done;
541 /* Get domain policy handle */
543 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
544 MAXIMUM_ALLOWED_ACCESS,
545 domain_sid, &domain_pol);
546 if (!NT_STATUS_IS_OK(result)) goto done;
548 /* Get handle on user */
550 result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol,
551 flags, 1, (char **) &argv[0],
552 &num_rids, &rids, &name_types);
554 if (!NT_STATUS_IS_OK(result)) goto done;
556 result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
557 MAXIMUM_ALLOWED_ACCESS,
559 if (!NT_STATUS_IS_OK(result)) goto done;
561 result = cli_samr_query_usergroups(cli, mem_ctx, &user_pol,
562 &num_rids, &user_gids);
566 rids = (uint32 *)talloc(mem_ctx, sizeof(uint32) * num_rids);
568 for (i = 0; i < num_rids; i++)
569 rids[i] = user_gids[i].g_rid;
571 result = cli_samr_lookup_rids(cli, mem_ctx, &domain_pol,
572 flags, num_rids, rids,
573 &num_names, &names, &name_types);
575 if (!NT_STATUS_IS_OK(result)) {
579 /* Display results */
581 for (i = 0; i < num_names; i++)
582 printf("%s\n", names[i]);
589 * List a user's groups from a remote RPC server
591 * @param argc Standard main() style argc
592 * @param argv Standard main() style argv. Initial components are already
595 * @return A shell status integer (0 for success)
598 static int rpc_user_info(int argc, const char **argv)
600 return run_rpc_command(PIPE_SAMR, 0, rpc_user_info_internals,
605 * List users on a remote RPC server
607 * All paramaters are provided by the run_rpc_command funcion, except for
608 * argc, argv which are passes through.
610 * @param domain_sid The domain sid acquired from the remote server
611 * @param cli A cli_state connected to the server.
612 * @param mem_ctx Talloc context, destoyed on completion of the function.
613 * @param argc Standard main() style argc
614 * @param argv Standard main() style argv. Initial components are already
617 * @return Normal NTSTATUS return.
621 rpc_user_list_internals(const DOM_SID *domain_sid, struct cli_state *cli,
622 TALLOC_CTX *mem_ctx, int argc, const char **argv)
624 POLICY_HND connect_pol, domain_pol;
625 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
626 uint32 start_idx=0, max_entries=250, num_entries, i;
627 SAM_DISPINFO_CTR ctr;
628 SAM_DISPINFO_1 info1;
630 /* Get sam policy handle */
632 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
634 if (!NT_STATUS_IS_OK(result)) {
638 /* Get domain policy handle */
640 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
641 MAXIMUM_ALLOWED_ACCESS,
642 domain_sid, &domain_pol);
643 if (!NT_STATUS_IS_OK(result)) {
647 /* Query domain users */
650 ctr.sam.info1 = &info1;
651 if (opt_long_list_entries)
652 d_printf("\nUser name Comment"\
653 "\n-----------------------------\n");
656 result = cli_samr_query_dispinfo(cli, mem_ctx, &domain_pol,
657 &start_idx, 1, &num_entries,
659 for (i = 0; i < num_entries; i++) {
660 unistr2_to_ascii(user, &(&ctr.sam.info1->str[i])->uni_acct_name, sizeof(user)-1);
661 if (opt_long_list_entries)
662 unistr2_to_ascii(desc, &(&ctr.sam.info1->str[i])->uni_acct_desc, sizeof(desc)-1);
664 if (opt_long_list_entries)
665 printf("%-21.21s %-50.50s\n", user, desc);
667 printf("%-21.21s\n", user);
669 } while (!NT_STATUS_IS_OK(result));
676 * 'net rpc user' entrypoint.
677 * @param argc Standard main() style argc
678 * @param argc Standard main() style argv. Initial components are already
682 int net_rpc_user(int argc, const char **argv)
684 struct functable func[] = {
685 {"add", rpc_user_add},
686 {"info", rpc_user_info},
687 {"delete", rpc_user_delete},
692 if (opt_long_list_entries) {
695 return run_rpc_command(PIPE_SAMR, 0,
696 rpc_user_list_internals,
700 return net_run_function(argc, argv, func, rpc_user_usage);
704 /****************************************************************************/
709 * ABORT the shutdown of a remote RPC Server
711 * All paramaters are provided by the run_rpc_command funcion, except for
712 * argc, argv which are passed through.
714 * @param domain_sid The domain sid aquired from the remote server
715 * @param cli A cli_state connected to the server.
716 * @param mem_ctx Talloc context, destoyed on compleation of the function.
717 * @param argc Standard main() style argc
718 * @param argc Standard main() style argv. Initial components are already
721 * @return Normal NTSTATUS return.
724 static NTSTATUS rpc_shutdown_abort_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx,
725 int argc, const char **argv)
727 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
729 result = cli_reg_abort_shutdown(cli, mem_ctx);
731 if (NT_STATUS_IS_OK(result))
732 DEBUG(5,("cmd_reg_abort_shutdown: query succeeded\n"));
734 DEBUG(5,("cmd_reg_abort_shutdown: query failed\n"));
741 * ABORT the Shut down of a remote RPC server
743 * @param argc Standard main() style argc
744 * @param argc Standard main() style argv. Initial components are already
747 * @return A shell status integer (0 for success)
750 static int rpc_shutdown_abort(int argc, const char **argv)
752 return run_rpc_command(PIPE_WINREG, 0, rpc_shutdown_abort_internals,
757 * Shut down a remote RPC Server
759 * All paramaters are provided by the run_rpc_command funcion, except for
760 * argc, argv which are passes through.
762 * @param domain_sid The domain sid aquired from the remote server
763 * @param cli A cli_state connected to the server.
764 * @param mem_ctx Talloc context, destoyed on compleation of the function.
765 * @param argc Standard main() style argc
766 * @param argc Standard main() style argv. Initial components are already
769 * @return Normal NTSTATUS return.
772 static NTSTATUS rpc_shutdown_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx,
773 int argc, const char **argv)
775 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
776 char *msg = "This machine will be shutdown shortly";
779 BOOL reboot = opt_reboot;
780 BOOL force = opt_force;
785 struct poptOption long_options[] = {
786 {"message", 'm', POPT_ARG_STRING, &msg},
787 {"timeout", 't', POPT_ARG_INT, &timeout},
788 {"reboot", 'r', POPT_ARG_NONE, &reboot},
789 {"force", 'f', POPT_ARG_NONE, &force},
793 pc = poptGetContext(NULL, argc, (const char **) argv, long_options,
794 POPT_CONTEXT_KEEP_FIRST);
796 rc = poptGetNextOpt(pc);
799 /* an error occurred during option processing */
800 DEBUG(0, ("%s: %s\n",
801 poptBadOption(pc, POPT_BADOPTION_NOALIAS),
803 return NT_STATUS_INVALID_PARAMETER;
807 flgs |= REG_REBOOT_ON_SHUTDOWN;
810 flgs |= REG_FORCE_SHUTDOWN;
816 timeout = opt_timeout;
819 /* create an entry */
820 result = cli_reg_shutdown(cli, mem_ctx, msg, timeout, flgs);
822 if (NT_STATUS_IS_OK(result))
823 DEBUG(5,("Shutdown of remote machine succeeded\n"));
825 DEBUG(0,("Shutdown of remote machine failed!\n"));
831 * Shut down a remote RPC server
833 * @param argc Standard main() style argc
834 * @param argc Standard main() style argv. Initial components are already
837 * @return A shell status integer (0 for success)
840 static int rpc_shutdown(int argc, const char **argv)
842 return run_rpc_command(PIPE_WINREG, 0, rpc_shutdown_internals,
846 /***************************************************************************
847 NT Domain trusts code (i.e. 'net rpc trustdom' functionality)
849 ***************************************************************************/
852 * Add interdomain trust account to the RPC server.
853 * All parameters (except for argc and argv) are passed by run_rpc_command
856 * @param domain_sid The domain sid acquired from the server
857 * @param cli A cli_state connected to the server.
858 * @param mem_ctx Talloc context, destoyed on completion of the function.
859 * @param argc Standard main() style argc
860 * @param argc Standard main() style argv. Initial components are already
863 * @return normal NTSTATUS return code
866 static NTSTATUS rpc_trustdom_add_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx,
867 int argc, const char **argv) {
869 POLICY_HND connect_pol, domain_pol, user_pol;
870 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
873 uint32 unknown, user_rid;
876 d_printf("Usage: net rpc trustdom add <domain_name>\n");
881 * Make valid trusting domain account (ie. uppercased and with '$' appended)
884 if (asprintf(&acct_name, "%s$", argv[0]) < 0) {
885 return NT_STATUS_NO_MEMORY;
890 /* Get sam policy handle */
892 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
894 if (!NT_STATUS_IS_OK(result)) {
898 /* Get domain policy handle */
900 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
901 MAXIMUM_ALLOWED_ACCESS,
902 domain_sid, &domain_pol);
903 if (!NT_STATUS_IS_OK(result)) {
907 /* Create trusting domain's account */
909 acb_info = ACB_DOMTRUST;
910 unknown = 0xe005000b; /* No idea what this is - a permission mask?
911 Is it needed for interdomain account also ? */
913 result = cli_samr_create_dom_user(cli, mem_ctx, &domain_pol,
914 acct_name, acb_info, unknown,
915 &user_pol, &user_rid);
916 if (!NT_STATUS_IS_OK(result)) {
921 SAFE_FREE(acct_name);
926 * Create interdomain trust account for a remote domain.
928 * @param argc standard argc
929 * @param argv standard argv without initial components
931 * @return Integer status (0 means success)
934 static int rpc_trustdom_add(int argc, const char **argv)
936 return run_rpc_command(PIPE_SAMR, 0, rpc_trustdom_add_internals,
942 * Delete interdomain trust account for a remote domain.
944 * @param argc standard argc
945 * @param argv standard argv without initial components
947 * @return Integer status (0 means success)
950 static int rpc_trustdom_del(int argc, const char **argv)
952 d_printf("Sorry, not yet implemented.\n");
958 * Establish trust relationship to a trusting domain.
959 * Interdomain account must already be created on remote PDC.
961 * @param argc standard argc
962 * @param argv standard argv without initial components
964 * @return Integer status (0 means success)
967 extern char *opt_user_name;
968 extern char *opt_password;
970 static int rpc_trustdom_establish(int argc, const char **argv) {
972 struct cli_state *cli;
973 struct in_addr server_ip;
974 POLICY_HND connect_hnd;
978 WKS_INFO_100 wks_info;
985 * Connect to \\server\ipc$ as 'our domain' account with password
988 domain_name = smb_xstrdup(argv[0]);
989 strupper(domain_name);
991 asprintf(&acct_name, "%s$", lp_workgroup());
994 opt_user_name = (char*)malloc(strlen(acct_name) + 1);
995 safe_strcpy(opt_user_name, acct_name, strlen(acct_name) + 1);
997 /* find the domain controller */
998 if (!net_find_dc(&server_ip, pdc_name, domain_name)) {
999 DEBUG(0, ("Coulnd find domain controller for domain %s\n", domain_name));
1003 /* connect to ipc$ as username/password */
1004 nt_status = connect_to_ipc(&cli, &server_ip, pdc_name);
1005 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT)) {
1007 /* Is it trusting domain account for sure ? */
1008 DEBUG(0, ("Couldn't verify trusting domain account. Error was %s\n",
1009 nt_errstr(nt_status)));
1014 * Connect to \\server\ipc$ again (this time anonymously)
1017 nt_status = connect_to_ipc_anonymous(&cli, &server_ip, (char*)pdc_name);
1019 if (NT_STATUS_IS_ERR(nt_status)) {
1020 DEBUG(0, ("Couldn't connect to domain %s controller. Error was %s.\n",
1021 domain_name, nt_errstr(nt_status)));
1025 * Use NetServerEnum2 to make sure we're talking to a proper server
1028 if (!cli_get_pdc_name(cli, domain_name, (char*)pdc_name)) {
1029 DEBUG(0, ("NetServerEnum2 error: Couldn't find primary domain controller\
1030 for domain %s\n", domain_name));
1034 * Call WksQueryInfo to check remote server's capabilities
1035 * FIXME:Is really necessary ? nt serv does this, but from samba's
1036 * point of view it doesn't seem to make the difference
1037 * IDEA: It may be used to get info about type of pdc we're talking to
1038 * (e.g. WinNT or Win2k)
1041 if (!cli_nt_session_open(cli, PIPE_WKSSVC)) {
1042 DEBUG(0, ("Couldn't not initialise wkssvc pipe\n"));
1046 /* TODO: convert this call from rpc_client/cli_wkssvc.c
1047 to cli_wks_query_info() in libsmb/cli_wkssvc.c
1048 UPDATE: already done :)
1051 if (!(mem_ctx = talloc_init())) {
1052 DEBUG(0, ("talloc_init() failed\n"));
1057 nt_status = cli_wks_query_info(cli, mem_ctx, &wks_info);
1059 if (NT_STATUS_IS_ERR(nt_status)) {
1060 DEBUG(0, ("WksQueryInfo call failed.\n"));
1064 if (cli->nt_pipe_fnum) {
1065 cli_nt_session_close(cli);
1066 talloc_destroy(mem_ctx);
1071 * Call LsaOpenPolicy and LsaQueryInfo
1074 if (!(mem_ctx = talloc_init())) {
1075 DEBUG(0, ("talloc_init() failed\n"));
1080 if (!cli_nt_session_open(cli, PIPE_LSARPC)) {
1081 DEBUG(0, ("Could not initialise lsa pipe\n"));
1084 nt_status = cli_lsa_open_policy2(cli, mem_ctx, True, SEC_RIGHTS_QUERY_VALUE,
1086 if (NT_STATUS_IS_ERR(nt_status)) {
1087 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
1088 nt_errstr(nt_status)));
1092 /* Querying info level 5 */
1094 nt_status = cli_lsa_query_info_policy(cli, mem_ctx, &connect_hnd,
1095 5 /* info level */, domain_name, &domain_sid);
1096 if (NT_STATUS_IS_ERR(nt_status)) {
1097 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
1098 nt_errstr(nt_status)));
1103 /* There should be actually query info level 3 (following nt serv behaviour),
1104 but I still don't know if it's _really_ necessary */
1107 * Close the pipes and clean up
1110 nt_status = cli_lsa_close(cli, mem_ctx, &connect_hnd);
1111 if (NT_STATUS_IS_ERR(nt_status)) {
1112 DEBUG(0, ("Couldn't close LSA pipe. Error was %s\n",
1113 nt_errstr(nt_status)));
1117 if (cli->nt_pipe_fnum)
1118 cli_nt_session_close(cli);
1120 talloc_destroy(mem_ctx);
1124 * Store the password in secrets db
1127 if (!secrets_store_trusted_domain_password(domain_name, opt_password,
1129 DEBUG(0, ("Storing password for trusted domain failed.\n"));
1133 DEBUG(0, ("Success!\n"));
1138 * Revoke trust relationship to the remote domain
1140 * @param argc standard argc
1141 * @param argv standard argv without initial components
1143 * @return Integer status (0 means success)
1146 static int rpc_trustdom_revoke(int argc, const char **argv) {
1150 if (argc < 1) return -1;
1152 /* generate upper cased domain name */
1153 domain_name = smb_xstrdup(argv[0]);
1154 strupper(domain_name);
1156 /* delete password of the trust */
1157 if (!trusted_domain_password_delete(domain_name)) {
1158 DEBUG(0, ("Failed to revoke relationship to the trusted domain %s\n",
1167 * Usage for 'net rpc trustdom' command
1169 * @param argc standard argc
1170 * @param argv standard argv without inital components
1172 * @return Integer status returned to shell
1175 static int rpc_trustdom_usage(int argc, const char **argv) {
1176 d_printf(" net rpc trustdom add \t\t add trusting domain's account\n");
1177 d_printf(" net rpc trustdom del \t\t delete trusting domain's account\n");
1178 d_printf(" net rpc trustdom establish \t establish relationship to trusted domain\n");
1179 d_printf(" net rpc trustdom revoke \t abandon relationship to trusted domain\n");
1180 d_printf(" net rpc trustdom list \t show current interdomain trust relationships\n");
1186 * Entrypoint for 'net rpc trustdom' code
1188 * @param argc standard argc
1189 * @param argv standard argv without initial components
1191 * @return Integer status (0 means success)
1194 static int rpc_trustdom(int argc, const char **argv)
1196 struct functable func[] = {
1197 {"add", rpc_trustdom_add},
1198 {"del", rpc_trustdom_del},
1199 {"establish", rpc_trustdom_establish},
1200 {"revoke", rpc_trustdom_revoke},
1201 {"help", rpc_trustdom_usage},
1206 rpc_trustdom_usage(argc, argv);
1210 return (net_run_function(argc, argv, func, rpc_user_usage));
1214 * Check if a server will take rpc commands
1215 * @param flags Type of server to connect to (PDC, DMB, localhost)
1216 * if the host is not explicitly specified
1217 * @return BOOL (true means rpc supported)
1219 BOOL net_rpc_check(unsigned flags)
1221 struct cli_state cli;
1223 struct in_addr server_ip;
1224 char *server_name = NULL;
1226 /* flags (i.e. server type) may depend on command */
1227 if (!net_find_server(flags, &server_ip, &server_name))
1231 if (cli_initialise(&cli) == False)
1234 if (!cli_connect(&cli, server_name, &server_ip))
1236 if (!attempt_netbios_session_request(&cli, global_myname,
1237 server_name, &server_ip))
1239 if (!cli_negprot(&cli))
1241 if (cli.protocol < PROTOCOL_NT1)
1251 /****************************************************************************/
1255 * Basic usage function for 'net rpc'
1256 * @param argc Standard main() style argc
1257 * @param argv Standard main() style argv. Initial components are already
1261 int net_rpc_usage(int argc, const char **argv)
1263 d_printf(" net rpc join \t\t\tto join a domain \n");
1264 d_printf(" net rpc user \t\t\tto add, delete and list users\n");
1265 d_printf(" net rpc changetrustpw \tto change the trust account password\n");
1266 d_printf(" net rpc trustdom \t\tto create trusting domain's account or establish trust\n");
1267 d_printf(" net rpc abortshutdown \tto to abort the shutdown of a remote server\n");
1268 d_printf(" net rpc shutdown \t\tto to shutdown a remote server\n");
1270 d_printf("'net rpc shutdown' also accepts the following miscellaneous options:\n"); /* misc options */
1271 d_printf("\t-r or --reboot\trequest remote server reboot on shutdown\n");
1272 d_printf("\t-f or --force\trequest the remote server force its shutdown\n");
1273 d_printf("\t-t or --timeout=<timeout>\tnumber of seconds before shutdown\n");
1274 d_printf("\t-c or --comment=<message>\ttext message to display on impending shutdown\n");
1280 * Help function for 'net rpc'. Calls command specific help if requested
1281 * or displays usage of net rpc
1282 * @param argc Standard main() style argc
1283 * @param argv Standard main() style argv. Initial components are already
1287 int net_rpc_help(int argc, const char **argv)
1289 struct functable func[] = {
1290 {"join", rpc_join_usage},
1291 {"user", net_help_user},
1292 /*{"changetrustpw", rpc_changetrustpw_usage}, */
1293 {"trustdom", rpc_trustdom_usage},
1294 /*{"abortshutdown", rpc_shutdown_abort_usage},*/
1295 /*{"shutdown", rpc_shutdown_usage}, */
1300 net_rpc_usage(argc, argv);
1304 return (net_run_function(argc, argv, func, rpc_user_usage));
1309 * 'net rpc' entrypoint.
1310 * @param argc Standard main() style argc
1311 * @param argv Standard main() style argv. Initial components are already
1315 int net_rpc(int argc, const char **argv)
1317 struct functable func[] = {
1318 {"join", net_rpc_join},
1319 {"user", net_rpc_user},
1320 {"changetrustpw", rpc_changetrustpw},
1321 {"trustdom", rpc_trustdom},
1322 {"abortshutdown", rpc_shutdown_abort},
1323 {"shutdown", rpc_shutdown},
1324 {"help", net_rpc_help},
1327 return net_run_function(argc, argv, func, net_rpc_usage);