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,("net_get_remote_domain_sid: malloc returned NULL!\n"));
66 if (!(mem_ctx
=talloc_init()))
68 DEBUG(0,("net_get_remote_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
);
240 * Machine names can be 15 characters, but the max length on
241 * a password is 14. --jerry
244 trust_passwd
[14] = '\0';
246 E_md4hash( (uchar
*)trust_passwd
, orig_trust_passwd_hash
);
248 return trust_pw_change_and_store_it(cli
, mem_ctx
, orig_trust_passwd_hash
);
252 * Join a domain, the old way.
254 * @param argc Standard main() style argc
255 * @param argc Standard main() style argv. Initial components are already
258 * @return A shell status integer (0 for success)
261 static int net_rpc_join_oldstyle(int argc
, const char **argv
)
263 return run_rpc_command(PIPE_NETLOGON
, NET_FLAGS_ANONYMOUS
| NET_FLAGS_PDC
, rpc_join_oldstyle_internals
,
268 * Basic usage function for 'net rpc join'
269 * @param argc Standard main() style argc
270 * @param argc Standard main() style argv. Initial components are already
274 static int rpc_join_usage(int argc
, const char **argv
)
276 d_printf("net rpc join -U <username>[%%password] [options]\n"\
277 "\t to join a domain with admin username & password\n"\
278 "\t\t password will be prompted if none is specified\n");
279 d_printf("net rpc join [options except -U]\n"\
280 "\t to join a domain created in server manager\n\n\n");
282 net_common_flags_usage(argc
, argv
);
287 * 'net rpc join' entrypoint.
288 * @param argc Standard main() style argc
289 * @param argc Standard main() style argv. Initial components are already
292 * Main 'net_rpc_join()' (where the admain username/password is used) is
294 * Assume if a -U is specified, it's the new style, otherwise it's the
298 int net_rpc_join(int argc
, const char **argv
)
300 if ((net_rpc_join_oldstyle(argc
, argv
) == 0))
303 return net_rpc_join_newstyle(argc
, argv
);
307 /****************************************************************************/
310 * Basic usage function for 'net rpc user'
311 * @param argc Standard main() style argc.
312 * @param argv Standard main() style argv. Initial components are already
316 static int rpc_user_usage(int argc
, const char **argv
)
318 return net_help_user(argc
, argv
);
322 * Add a new user to a remote RPC server
324 * All paramaters are provided by the run_rpc_command funcion, except for
325 * argc, argv which are passes through.
327 * @param domain_sid The domain sid acquired from the remote server
328 * @param cli A cli_state connected to the server.
329 * @param mem_ctx Talloc context, destoyed on completion of the function.
330 * @param argc Standard main() style argc
331 * @param argv Standard main() style argv. Initial components are already
334 * @return Normal NTSTATUS return.
337 static NTSTATUS
rpc_user_add_internals(const DOM_SID
*domain_sid
, struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
338 int argc
, const char **argv
) {
340 POLICY_HND connect_pol
, domain_pol
, user_pol
;
341 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
342 const char *acct_name
;
344 uint32 unknown
, user_rid
;
347 d_printf("User must be specified\n");
348 rpc_user_usage(argc
, argv
);
354 /* Get sam policy handle */
356 result
= cli_samr_connect(cli
, mem_ctx
, MAXIMUM_ALLOWED_ACCESS
,
358 if (!NT_STATUS_IS_OK(result
)) {
362 /* Get domain policy handle */
364 result
= cli_samr_open_domain(cli
, mem_ctx
, &connect_pol
,
365 MAXIMUM_ALLOWED_ACCESS
,
366 domain_sid
, &domain_pol
);
367 if (!NT_STATUS_IS_OK(result
)) {
371 /* Create domain user */
373 acb_info
= ACB_NORMAL
;
374 unknown
= 0xe005000b; /* No idea what this is - a permission mask? */
376 result
= cli_samr_create_dom_user(cli
, mem_ctx
, &domain_pol
,
377 acct_name
, acb_info
, unknown
,
378 &user_pol
, &user_rid
);
379 if (!NT_STATUS_IS_OK(result
)) {
384 if (!NT_STATUS_IS_OK(result
)) {
385 d_printf("Failed to add user %s - %s\n", acct_name
,
388 d_printf("Added user %s\n", acct_name
);
394 * Add a new user to a remote RPC server
396 * @param argc Standard main() style argc
397 * @param argv Standard main() style argv. Initial components are already
400 * @return A shell status integer (0 for success)
403 static int rpc_user_add(int argc
, const char **argv
)
405 return run_rpc_command(PIPE_SAMR
, 0, rpc_user_add_internals
,
410 * Delete a user from a remote RPC server
412 * All paramaters are provided by the run_rpc_command funcion, except for
413 * argc, argv which are passes through.
415 * @param domain_sid The domain sid acquired from the remote server
416 * @param cli A cli_state connected to the server.
417 * @param mem_ctx Talloc context, destoyed on completion of the function.
418 * @param argc Standard main() style argc
419 * @param argv Standard main() style argv. Initial components are already
422 * @return Normal NTSTATUS return.
425 static NTSTATUS
rpc_user_del_internals(const DOM_SID
*domain_sid
,
426 struct cli_state
*cli
,
428 int argc
, const char **argv
)
430 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
431 POLICY_HND connect_pol
, domain_pol
, user_pol
;
434 d_printf("User must be specified\n");
435 rpc_user_usage(argc
, argv
);
438 /* Get sam policy and domain handles */
440 result
= cli_samr_connect(cli
, mem_ctx
, MAXIMUM_ALLOWED_ACCESS
,
443 if (!NT_STATUS_IS_OK(result
)) {
447 result
= cli_samr_open_domain(cli
, mem_ctx
, &connect_pol
,
448 MAXIMUM_ALLOWED_ACCESS
,
449 domain_sid
, &domain_pol
);
451 if (!NT_STATUS_IS_OK(result
)) {
455 /* Get handle on user */
458 uint32
*user_rids
, num_rids
, *name_types
;
459 uint32 flags
= 0x000003e8; /* Unknown */
461 result
= cli_samr_lookup_names(cli
, mem_ctx
, &domain_pol
,
463 &num_rids
, &user_rids
,
466 if (!NT_STATUS_IS_OK(result
)) {
470 result
= cli_samr_open_user(cli
, mem_ctx
, &domain_pol
,
471 MAXIMUM_ALLOWED_ACCESS
,
472 user_rids
[0], &user_pol
);
474 if (!NT_STATUS_IS_OK(result
)) {
481 result
= cli_samr_delete_dom_user(cli
, mem_ctx
, &user_pol
);
483 if (!NT_STATUS_IS_OK(result
)) {
487 /* Display results */
495 * Delete a user from a remote RPC server
497 * @param argc Standard main() style argc
498 * @param argv Standard main() style argv. Initial components are already
501 * @return A shell status integer (0 for success)
504 static int rpc_user_delete(int argc
, const char **argv
)
506 return run_rpc_command(PIPE_SAMR
, 0, rpc_user_del_internals
,
511 * List user's groups on a remote RPC server
513 * All paramaters are provided by the run_rpc_command funcion, except for
514 * argc, argv which are passes through.
516 * @param domain_sid The domain sid acquired from the remote server
517 * @param cli A cli_state connected to the server.
518 * @param mem_ctx Talloc context, destoyed on completion of the function.
519 * @param argc Standard main() style argc
520 * @param argv Standard main() style argv. Initial components are already
523 * @return Normal NTSTATUS return.
527 rpc_user_info_internals(const DOM_SID
*domain_sid
, struct cli_state
*cli
,
528 TALLOC_CTX
*mem_ctx
, int argc
, const char **argv
)
530 POLICY_HND connect_pol
, domain_pol
, user_pol
;
531 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
532 uint32
*rids
, num_rids
, *name_types
, num_names
;
533 uint32 flags
= 0x000003e8; /* Unknown */
539 d_printf("User must be specified\n");
540 rpc_user_usage(argc
, argv
);
543 /* Get sam policy handle */
545 result
= cli_samr_connect(cli
, mem_ctx
, MAXIMUM_ALLOWED_ACCESS
,
547 if (!NT_STATUS_IS_OK(result
)) goto done
;
549 /* Get domain policy handle */
551 result
= cli_samr_open_domain(cli
, mem_ctx
, &connect_pol
,
552 MAXIMUM_ALLOWED_ACCESS
,
553 domain_sid
, &domain_pol
);
554 if (!NT_STATUS_IS_OK(result
)) goto done
;
556 /* Get handle on user */
558 result
= cli_samr_lookup_names(cli
, mem_ctx
, &domain_pol
,
560 &num_rids
, &rids
, &name_types
);
562 if (!NT_STATUS_IS_OK(result
)) goto done
;
564 result
= cli_samr_open_user(cli
, mem_ctx
, &domain_pol
,
565 MAXIMUM_ALLOWED_ACCESS
,
567 if (!NT_STATUS_IS_OK(result
)) goto done
;
569 result
= cli_samr_query_usergroups(cli
, mem_ctx
, &user_pol
,
570 &num_rids
, &user_gids
);
574 rids
= (uint32
*)talloc(mem_ctx
, sizeof(uint32
) * num_rids
);
576 for (i
= 0; i
< num_rids
; i
++)
577 rids
[i
] = user_gids
[i
].g_rid
;
579 result
= cli_samr_lookup_rids(cli
, mem_ctx
, &domain_pol
,
580 flags
, num_rids
, rids
,
581 &num_names
, &names
, &name_types
);
583 if (!NT_STATUS_IS_OK(result
)) {
587 /* Display results */
589 for (i
= 0; i
< num_names
; i
++)
590 printf("%s\n", names
[i
]);
597 * List a user's groups from a remote RPC server
599 * @param argc Standard main() style argc
600 * @param argv Standard main() style argv. Initial components are already
603 * @return A shell status integer (0 for success)
606 static int rpc_user_info(int argc
, const char **argv
)
608 return run_rpc_command(PIPE_SAMR
, 0, rpc_user_info_internals
,
613 * List users on a remote RPC server
615 * All paramaters are provided by the run_rpc_command funcion, except for
616 * argc, argv which are passes through.
618 * @param domain_sid The domain sid acquired from the remote server
619 * @param cli A cli_state connected to the server.
620 * @param mem_ctx Talloc context, destoyed on completion of the function.
621 * @param argc Standard main() style argc
622 * @param argv Standard main() style argv. Initial components are already
625 * @return Normal NTSTATUS return.
629 rpc_user_list_internals(const DOM_SID
*domain_sid
, struct cli_state
*cli
,
630 TALLOC_CTX
*mem_ctx
, int argc
, const char **argv
)
632 POLICY_HND connect_pol
, domain_pol
;
633 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
634 uint32 start_idx
=0, max_entries
=250, num_entries
, i
;
635 SAM_DISPINFO_CTR ctr
;
636 SAM_DISPINFO_1 info1
;
638 /* Get sam policy handle */
640 result
= cli_samr_connect(cli
, mem_ctx
, MAXIMUM_ALLOWED_ACCESS
,
642 if (!NT_STATUS_IS_OK(result
)) {
646 /* Get domain policy handle */
648 result
= cli_samr_open_domain(cli
, mem_ctx
, &connect_pol
,
649 MAXIMUM_ALLOWED_ACCESS
,
650 domain_sid
, &domain_pol
);
651 if (!NT_STATUS_IS_OK(result
)) {
655 /* Query domain users */
658 ctr
.sam
.info1
= &info1
;
659 if (opt_long_list_entries
)
660 d_printf("\nUser name Comment"\
661 "\n-----------------------------\n");
664 result
= cli_samr_query_dispinfo(cli
, mem_ctx
, &domain_pol
,
665 &start_idx
, 1, &num_entries
,
667 for (i
= 0; i
< num_entries
; i
++) {
668 unistr2_to_ascii(user
, &(&ctr
.sam
.info1
->str
[i
])->uni_acct_name
, sizeof(user
)-1);
669 if (opt_long_list_entries
)
670 unistr2_to_ascii(desc
, &(&ctr
.sam
.info1
->str
[i
])->uni_acct_desc
, sizeof(desc
)-1);
672 if (opt_long_list_entries
)
673 printf("%-21.21s %-50.50s\n", user
, desc
);
675 printf("%s\n", user
);
677 } while (!NT_STATUS_IS_OK(result
));
684 * 'net rpc user' entrypoint.
685 * @param argc Standard main() style argc
686 * @param argc Standard main() style argv. Initial components are already
690 int net_rpc_user(int argc
, const char **argv
)
692 struct functable func
[] = {
693 {"add", rpc_user_add
},
694 {"info", rpc_user_info
},
695 {"delete", rpc_user_delete
},
700 if (opt_long_list_entries
) {
703 return run_rpc_command(PIPE_SAMR
, 0,
704 rpc_user_list_internals
,
708 return net_run_function(argc
, argv
, func
, rpc_user_usage
);
712 /****************************************************************************/
715 * Basic usage function for 'net rpc group'
716 * @param argc Standard main() style argc.
717 * @param argv Standard main() style argv. Initial components are already
721 static int rpc_group_usage(int argc
, const char **argv
)
723 return net_help_group(argc
, argv
);
727 * List groups on a remote RPC server
729 * All paramaters are provided by the run_rpc_command funcion, except for
730 * argc, argv which are passes through.
732 * @param domain_sid The domain sid acquired from the remote server
733 * @param cli A cli_state connected to the server.
734 * @param mem_ctx Talloc context, destoyed on completion of the function.
735 * @param argc Standard main() style argc
736 * @param argv Standard main() style argv. Initial components are already
739 * @return Normal NTSTATUS return.
743 rpc_group_list_internals(const DOM_SID
*domain_sid
, struct cli_state
*cli
,
744 TALLOC_CTX
*mem_ctx
, int argc
, const char **argv
)
746 POLICY_HND connect_pol
, domain_pol
;
747 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
748 uint32 start_idx
=0, max_entries
=250, num_entries
, i
;
749 struct acct_info
*groups
;
750 DOM_SID global_sid_Builtin
;
752 string_to_sid(&global_sid_Builtin
, "S-1-5-32");
754 /* Get sam policy handle */
756 result
= cli_samr_connect(cli
, mem_ctx
, MAXIMUM_ALLOWED_ACCESS
,
758 if (!NT_STATUS_IS_OK(result
)) {
762 /* Get domain policy handle */
764 result
= cli_samr_open_domain(cli
, mem_ctx
, &connect_pol
,
765 MAXIMUM_ALLOWED_ACCESS
,
766 domain_sid
, &domain_pol
);
767 if (!NT_STATUS_IS_OK(result
)) {
771 /* Query domain groups */
772 if (opt_long_list_entries
)
773 d_printf("\nGroup name Comment"\
774 "\n-----------------------------\n");
776 result
= cli_samr_enum_dom_groups(cli
, mem_ctx
, &domain_pol
,
777 &start_idx
, max_entries
,
778 &groups
, &num_entries
);
780 for (i
= 0; i
< num_entries
; i
++) {
781 if (opt_long_list_entries
)
782 printf("%-21.21s %-50.50s\n",
784 groups
[i
].acct_desc
);
786 printf("%-21.21s\n", groups
[i
].acct_name
);
788 } while (!NT_STATUS_IS_OK(result
));
789 /* query domain aliases */
791 result
= cli_samr_enum_als_groups(cli
, mem_ctx
, &domain_pol
,
792 &start_idx
, max_entries
,
793 &groups
, &num_entries
);
795 for (i
= 0; i
< num_entries
; i
++) {
796 if (opt_long_list_entries
)
797 printf("%-21.21s %-50.50s\n",
799 groups
[i
].acct_desc
);
801 printf("%-21.21s\n", groups
[i
].acct_name
);
803 } while (!NT_STATUS_IS_OK(result
));
804 cli_samr_close(cli
, mem_ctx
, &domain_pol
);
805 /* Get builtin policy handle */
807 result
= cli_samr_open_domain(cli
, mem_ctx
, &connect_pol
,
808 MAXIMUM_ALLOWED_ACCESS
,
809 &global_sid_Builtin
, &domain_pol
);
810 if (!NT_STATUS_IS_OK(result
)) {
813 /* query builtin aliases */
815 result
= cli_samr_enum_als_groups(cli
, mem_ctx
, &domain_pol
,
816 &start_idx
, max_entries
,
817 &groups
, &num_entries
);
819 for (i
= 0; i
< num_entries
; i
++) {
820 if (opt_long_list_entries
)
821 printf("%-21.21s %-50.50s\n",
823 groups
[i
].acct_desc
);
825 printf("%s\n", groups
[i
].acct_name
);
827 } while (!NT_STATUS_IS_OK(result
));
834 * 'net rpc group' entrypoint.
835 * @param argc Standard main() style argc
836 * @param argc Standard main() style argv. Initial components are already
840 int net_rpc_group(int argc
, const char **argv
)
842 struct functable func
[] = {
844 {"add", rpc_group_add
},
845 {"delete", rpc_group_delete
},
851 if (opt_long_list_entries
) {
854 return run_rpc_command(PIPE_SAMR
, 0,
855 rpc_group_list_internals
,
859 return net_run_function(argc
, argv
, func
, rpc_group_usage
);
863 /****************************************************************************/
868 * ABORT the shutdown of a remote RPC Server
870 * All paramaters are provided by the run_rpc_command funcion, except for
871 * argc, argv which are passed through.
873 * @param domain_sid The domain sid aquired from the remote server
874 * @param cli A cli_state connected to the server.
875 * @param mem_ctx Talloc context, destoyed on compleation of the function.
876 * @param argc Standard main() style argc
877 * @param argc Standard main() style argv. Initial components are already
880 * @return Normal NTSTATUS return.
883 static NTSTATUS
rpc_shutdown_abort_internals(const DOM_SID
*domain_sid
, struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
884 int argc
, const char **argv
)
886 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
888 result
= cli_reg_abort_shutdown(cli
, mem_ctx
);
890 if (NT_STATUS_IS_OK(result
))
891 DEBUG(5,("cmd_reg_abort_shutdown: query succeeded\n"));
893 DEBUG(5,("cmd_reg_abort_shutdown: query failed\n"));
900 * ABORT the Shut down of a remote RPC server
902 * @param argc Standard main() style argc
903 * @param argc Standard main() style argv. Initial components are already
906 * @return A shell status integer (0 for success)
909 static int rpc_shutdown_abort(int argc
, const char **argv
)
911 return run_rpc_command(PIPE_WINREG
, 0, rpc_shutdown_abort_internals
,
916 * Shut down a remote RPC Server
918 * All paramaters are provided by the run_rpc_command funcion, except for
919 * argc, argv which are passes through.
921 * @param domain_sid The domain sid aquired from the remote server
922 * @param cli A cli_state connected to the server.
923 * @param mem_ctx Talloc context, destoyed on compleation of the function.
924 * @param argc Standard main() style argc
925 * @param argc Standard main() style argv. Initial components are already
928 * @return Normal NTSTATUS return.
931 static NTSTATUS
rpc_shutdown_internals(const DOM_SID
*domain_sid
, struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
932 int argc
, const char **argv
)
934 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
935 char *msg
= "This machine will be shutdown shortly";
938 BOOL reboot
= opt_reboot
;
939 BOOL force
= opt_force
;
944 struct poptOption long_options
[] = {
945 {"message", 'm', POPT_ARG_STRING
, &msg
},
946 {"timeout", 't', POPT_ARG_INT
, &timeout
},
947 {"reboot", 'r', POPT_ARG_NONE
, &reboot
},
948 {"force", 'f', POPT_ARG_NONE
, &force
},
952 pc
= poptGetContext(NULL
, argc
, (const char **) argv
, long_options
,
953 POPT_CONTEXT_KEEP_FIRST
);
955 rc
= poptGetNextOpt(pc
);
958 /* an error occurred during option processing */
959 DEBUG(0, ("%s: %s\n",
960 poptBadOption(pc
, POPT_BADOPTION_NOALIAS
),
962 return NT_STATUS_INVALID_PARAMETER
;
966 flgs
|= REG_REBOOT_ON_SHUTDOWN
;
969 flgs
|= REG_FORCE_SHUTDOWN
;
975 timeout
= opt_timeout
;
978 /* create an entry */
979 result
= cli_reg_shutdown(cli
, mem_ctx
, msg
, timeout
, flgs
);
981 if (NT_STATUS_IS_OK(result
))
982 DEBUG(5,("Shutdown of remote machine succeeded\n"));
984 DEBUG(0,("Shutdown of remote machine failed!\n"));
990 * Shut down a remote RPC server
992 * @param argc Standard main() style argc
993 * @param argc Standard main() style argv. Initial components are already
996 * @return A shell status integer (0 for success)
999 static int rpc_shutdown(int argc
, const char **argv
)
1001 return run_rpc_command(PIPE_WINREG
, 0, rpc_shutdown_internals
,
1005 /***************************************************************************
1006 NT Domain trusts code (i.e. 'net rpc trustdom' functionality)
1008 ***************************************************************************/
1011 * Add interdomain trust account to the RPC server.
1012 * All parameters (except for argc and argv) are passed by run_rpc_command
1015 * @param domain_sid The domain sid acquired from the server
1016 * @param cli A cli_state connected to the server.
1017 * @param mem_ctx Talloc context, destoyed on completion of the function.
1018 * @param argc Standard main() style argc
1019 * @param argc Standard main() style argv. Initial components are already
1022 * @return normal NTSTATUS return code
1025 static NTSTATUS
rpc_trustdom_add_internals(const DOM_SID
*domain_sid
, struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
1026 int argc
, const char **argv
) {
1028 POLICY_HND connect_pol
, domain_pol
, user_pol
;
1029 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
1032 uint32 unknown
, user_rid
;
1035 d_printf("Usage: net rpc trustdom add <domain_name>\n");
1036 return NT_STATUS_INVALID_PARAMETER
;
1040 * Make valid trusting domain account (ie. uppercased and with '$' appended)
1043 if (asprintf(&acct_name
, "%s$", argv
[0]) < 0) {
1044 return NT_STATUS_NO_MEMORY
;
1047 strupper(acct_name
);
1049 /* Get sam policy handle */
1051 result
= cli_samr_connect(cli
, mem_ctx
, MAXIMUM_ALLOWED_ACCESS
,
1053 if (!NT_STATUS_IS_OK(result
)) {
1057 /* Get domain policy handle */
1059 result
= cli_samr_open_domain(cli
, mem_ctx
, &connect_pol
,
1060 MAXIMUM_ALLOWED_ACCESS
,
1061 domain_sid
, &domain_pol
);
1062 if (!NT_STATUS_IS_OK(result
)) {
1066 /* Create trusting domain's account */
1068 acb_info
= ACB_DOMTRUST
;
1069 unknown
= 0xe005000b; /* No idea what this is - a permission mask?
1070 Is it needed for interdomain account also ? */
1072 result
= cli_samr_create_dom_user(cli
, mem_ctx
, &domain_pol
,
1073 acct_name
, acb_info
, unknown
,
1074 &user_pol
, &user_rid
);
1075 if (!NT_STATUS_IS_OK(result
)) {
1080 SAFE_FREE(acct_name
);
1085 * Create interdomain trust account for a remote domain.
1087 * @param argc standard argc
1088 * @param argv standard argv without initial components
1090 * @return Integer status (0 means success)
1093 static int rpc_trustdom_add(int argc
, const char **argv
)
1095 return run_rpc_command(PIPE_SAMR
, 0, rpc_trustdom_add_internals
,
1101 * Delete interdomain trust account for a remote domain.
1103 * @param argc standard argc
1104 * @param argv standard argv without initial components
1106 * @return Integer status (0 means success)
1109 static int rpc_trustdom_del(int argc
, const char **argv
)
1111 d_printf("Sorry, not yet implemented.\n");
1117 * Establish trust relationship to a trusting domain.
1118 * Interdomain account must already be created on remote PDC.
1120 * @param argc standard argc
1121 * @param argv standard argv without initial components
1123 * @return Integer status (0 means success)
1126 extern char *opt_user_name
;
1127 extern char *opt_password
;
1129 static int rpc_trustdom_establish(int argc
, const char **argv
) {
1131 struct cli_state
*cli
;
1132 struct in_addr server_ip
;
1133 POLICY_HND connect_hnd
;
1134 TALLOC_CTX
*mem_ctx
;
1137 WKS_INFO_100 wks_info
;
1144 * Connect to \\server\ipc$ as 'our domain' account with password
1148 d_printf("Usage: net rpc trustdom add <domain_name>\n");
1153 domain_name
= smb_xstrdup(argv
[0]);
1154 strupper(domain_name
);
1156 asprintf(&acct_name
, "%s$", lp_workgroup());
1157 strupper(acct_name
);
1159 opt_user_name
= (char*)malloc(strlen(acct_name
) + 1);
1160 safe_strcpy(opt_user_name
, acct_name
, strlen(acct_name
) + 1);
1162 /* find the domain controller */
1163 if (!net_find_dc(&server_ip
, pdc_name
, domain_name
)) {
1164 DEBUG(0, ("Coulnd find domain controller for domain %s\n", domain_name
));
1168 /* connect to ipc$ as username/password */
1169 nt_status
= connect_to_ipc(&cli
, &server_ip
, pdc_name
);
1170 if (!NT_STATUS_EQUAL(nt_status
, NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT
)) {
1172 /* Is it trusting domain account for sure ? */
1173 DEBUG(0, ("Couldn't verify trusting domain account. Error was %s\n",
1174 nt_errstr(nt_status
)));
1179 * Connect to \\server\ipc$ again (this time anonymously)
1182 nt_status
= connect_to_ipc_anonymous(&cli
, &server_ip
, (char*)pdc_name
);
1184 if (NT_STATUS_IS_ERR(nt_status
)) {
1185 DEBUG(0, ("Couldn't connect to domain %s controller. Error was %s.\n",
1186 domain_name
, nt_errstr(nt_status
)));
1190 * Use NetServerEnum2 to make sure we're talking to a proper server
1193 if (!cli_get_pdc_name(cli
, domain_name
, (char*)pdc_name
)) {
1194 DEBUG(0, ("NetServerEnum2 error: Couldn't find primary domain controller\
1195 for domain %s\n", domain_name
));
1199 * Call WksQueryInfo to check remote server's capabilities
1200 * FIXME:Is really necessary ? nt serv does this, but from samba's
1201 * point of view it doesn't seem to make the difference
1202 * IDEA: It may be used to get info about type of pdc we're talking to
1203 * (e.g. WinNT or Win2k)
1206 if (!cli_nt_session_open(cli
, PIPE_WKSSVC
)) {
1207 DEBUG(0, ("Couldn't not initialise wkssvc pipe\n"));
1211 /* TODO: convert this call from rpc_client/cli_wkssvc.c
1212 to cli_wks_query_info() in libsmb/cli_wkssvc.c
1213 UPDATE: already done :)
1216 if (!(mem_ctx
= talloc_init())) {
1217 DEBUG(0, ("talloc_init() failed\n"));
1222 nt_status
= cli_wks_query_info(cli
, mem_ctx
, &wks_info
);
1224 if (NT_STATUS_IS_ERR(nt_status
)) {
1225 DEBUG(0, ("WksQueryInfo call failed.\n"));
1229 if (cli
->nt_pipe_fnum
)
1230 cli_nt_session_close(cli
);
1234 * Call LsaOpenPolicy and LsaQueryInfo
1237 if (!(mem_ctx
= talloc_init())) {
1238 DEBUG(0, ("talloc_init() failed\n"));
1243 if (!cli_nt_session_open(cli
, PIPE_LSARPC
)) {
1244 DEBUG(0, ("Could not initialise lsa pipe\n"));
1247 nt_status
= cli_lsa_open_policy2(cli
, mem_ctx
, True
, SEC_RIGHTS_QUERY_VALUE
,
1249 if (NT_STATUS_IS_ERR(nt_status
)) {
1250 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
1251 nt_errstr(nt_status
)));
1255 /* Querying info level 5 */
1257 nt_status
= cli_lsa_query_info_policy(cli
, mem_ctx
, &connect_hnd
,
1258 5 /* info level */, domain_name
, &domain_sid
);
1259 if (NT_STATUS_IS_ERR(nt_status
)) {
1260 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
1261 nt_errstr(nt_status
)));
1266 /* There should be actually query info level 3 (following nt serv behaviour),
1267 but I still don't know if it's _really_ necessary */
1270 * Store the password in secrets db
1273 if (!secrets_store_trusted_domain_password(domain_name
, wks_info
.uni_lan_grp
.buffer
,
1274 wks_info
.uni_lan_grp
.uni_str_len
, opt_password
,
1276 DEBUG(0, ("Storing password for trusted domain failed.\n"));
1281 * Close the pipes and clean up
1284 nt_status
= cli_lsa_close(cli
, mem_ctx
, &connect_hnd
);
1285 if (NT_STATUS_IS_ERR(nt_status
)) {
1286 DEBUG(0, ("Couldn't close LSA pipe. Error was %s\n",
1287 nt_errstr(nt_status
)));
1291 if (cli
->nt_pipe_fnum
)
1292 cli_nt_session_close(cli
);
1294 talloc_destroy(mem_ctx
);
1296 DEBUG(0, ("Success!\n"));
1301 * Revoke trust relationship to the remote domain
1303 * @param argc standard argc
1304 * @param argv standard argv without initial components
1306 * @return Integer status (0 means success)
1309 static int rpc_trustdom_revoke(int argc
, const char **argv
) {
1313 if (argc
< 1) return -1;
1315 /* generate upper cased domain name */
1316 domain_name
= smb_xstrdup(argv
[0]);
1317 strupper(domain_name
);
1319 /* delete password of the trust */
1320 if (!trusted_domain_password_delete(domain_name
)) {
1321 DEBUG(0, ("Failed to revoke relationship to the trusted domain %s\n",
1330 * Usage for 'net rpc trustdom' command
1332 * @param argc standard argc
1333 * @param argv standard argv without inital components
1335 * @return Integer status returned to shell
1338 static int rpc_trustdom_usage(int argc
, const char **argv
) {
1339 d_printf(" net rpc trustdom add \t\t add trusting domain's account\n");
1340 d_printf(" net rpc trustdom del \t\t delete trusting domain's account\n");
1341 d_printf(" net rpc trustdom establish \t establish relationship to trusted domain\n");
1342 d_printf(" net rpc trustdom revoke \t abandon relationship to trusted domain\n");
1343 d_printf(" net rpc trustdom list \t show current interdomain trust relationships\n");
1349 * Entrypoint for 'net rpc trustdom' code
1351 * @param argc standard argc
1352 * @param argv standard argv without initial components
1354 * @return Integer status (0 means success)
1357 static int rpc_trustdom(int argc
, const char **argv
)
1359 struct functable func
[] = {
1360 {"add", rpc_trustdom_add
},
1361 {"del", rpc_trustdom_del
},
1362 {"establish", rpc_trustdom_establish
},
1363 {"revoke", rpc_trustdom_revoke
},
1364 {"help", rpc_trustdom_usage
},
1369 rpc_trustdom_usage(argc
, argv
);
1373 return (net_run_function(argc
, argv
, func
, rpc_user_usage
));
1377 * Check if a server will take rpc commands
1378 * @param flags Type of server to connect to (PDC, DMB, localhost)
1379 * if the host is not explicitly specified
1380 * @return BOOL (true means rpc supported)
1382 BOOL
net_rpc_check(unsigned flags
)
1384 struct cli_state cli
;
1386 struct in_addr server_ip
;
1387 char *server_name
= NULL
;
1389 /* flags (i.e. server type) may depend on command */
1390 if (!net_find_server(flags
, &server_ip
, &server_name
))
1394 if (cli_initialise(&cli
) == False
)
1397 if (!cli_connect(&cli
, server_name
, &server_ip
))
1399 if (!attempt_netbios_session_request(&cli
, global_myname
,
1400 server_name
, &server_ip
))
1402 if (!cli_negprot(&cli
))
1404 if (cli
.protocol
< PROTOCOL_NT1
)
1414 /****************************************************************************/
1418 * Basic usage function for 'net rpc'
1419 * @param argc Standard main() style argc
1420 * @param argv Standard main() style argv. Initial components are already
1424 int net_rpc_usage(int argc
, const char **argv
)
1426 d_printf(" net rpc join \t\t\tto join a domain \n");
1427 d_printf(" net rpc user \t\t\tto add, delete and list users\n");
1428 d_printf(" net rpc changetrustpw \tto change the trust account password\n");
1429 d_printf(" net rpc trustdom \t\tto create trusting domain's account or establish trust\n");
1430 d_printf(" net rpc abortshutdown \tto to abort the shutdown of a remote server\n");
1431 d_printf(" net rpc shutdown \t\tto to shutdown a remote server\n");
1433 d_printf("'net rpc shutdown' also accepts the following miscellaneous options:\n"); /* misc options */
1434 d_printf("\t-r or --reboot\trequest remote server reboot on shutdown\n");
1435 d_printf("\t-f or --force\trequest the remote server force its shutdown\n");
1436 d_printf("\t-t or --timeout=<timeout>\tnumber of seconds before shutdown\n");
1437 d_printf("\t-c or --comment=<message>\ttext message to display on impending shutdown\n");
1443 * Help function for 'net rpc'. Calls command specific help if requested
1444 * or displays usage of net rpc
1445 * @param argc Standard main() style argc
1446 * @param argv Standard main() style argv. Initial components are already
1450 int net_rpc_help(int argc
, const char **argv
)
1452 struct functable func
[] = {
1453 {"join", rpc_join_usage
},
1454 {"user", net_help_user
},
1455 /*{"changetrustpw", rpc_changetrustpw_usage}, */
1456 {"trustdom", rpc_trustdom_usage
},
1457 /*{"abortshutdown", rpc_shutdown_abort_usage},*/
1458 /*{"shutdown", rpc_shutdown_usage}, */
1463 net_rpc_usage(argc
, argv
);
1467 return (net_run_function(argc
, argv
, func
, rpc_user_usage
));
1472 * 'net rpc' entrypoint.
1473 * @param argc Standard main() style argc
1474 * @param argv Standard main() style argv. Initial components are already
1478 int net_rpc(int argc
, const char **argv
)
1480 struct functable func
[] = {
1481 {"join", net_rpc_join
},
1482 {"user", net_rpc_user
},
1483 {"group", net_rpc_group
},
1484 {"changetrustpw", rpc_changetrustpw
},
1485 {"trustdom", rpc_trustdom
},
1486 {"abortshutdown", rpc_shutdown_abort
},
1487 {"shutdown", rpc_shutdown
},
1488 {"help", net_rpc_help
},
1491 return net_run_function(argc
, argv
, func
, net_rpc_usage
);