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)
6 Copyright (C) 2004 Guenther Deschner (gd@samba.org)
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
23 #include "utils/net.h"
25 static int net_mode_share;
30 * @brief RPC based subcommands for the 'net' utility.
32 * This file should contain much of the functionality that used to
33 * be found in rpcclient, execpt that the commands should change
34 * less often, and the fucntionality should be sane (the user is not
35 * expected to know a rid/sid before they conduct an operation etc.)
37 * @todo Perhaps eventually these should be split out into a number
38 * of files, as this could get quite big.
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, TALLOC_CTX *mem_ctx, char **domain_name)
55 NTSTATUS result = NT_STATUS_OK;
56 uint32 info_class = 5;
58 if (!cli_nt_session_open (cli, PI_LSARPC)) {
59 fprintf(stderr, "could not initialise lsa pipe\n");
63 result = cli_lsa_open_policy(cli, mem_ctx, False,
64 SEC_RIGHTS_MAXIMUM_ALLOWED,
66 if (!NT_STATUS_IS_OK(result)) {
70 result = cli_lsa_query_info_policy(cli, mem_ctx, &pol, info_class,
71 domain_name, &domain_sid);
72 if (!NT_STATUS_IS_OK(result)) {
74 fprintf(stderr, "could not obtain sid for domain %s\n", cli->domain);
76 if (!NT_STATUS_IS_OK(result)) {
77 fprintf(stderr, "error: %s\n", nt_errstr(result));
83 cli_lsa_close(cli, mem_ctx, &pol);
84 cli_nt_session_close(cli);
90 * Run a single RPC command, from start to finish.
92 * @param pipe_name the pipe to connect to (usually a PIPE_ constant)
93 * @param conn_flag a NET_FLAG_ combination. Passed to
94 * net_make_ipc_connection.
95 * @param argc Standard main() style argc
96 * @param argc Standard main() style argv. Initial components are already
98 * @return A shell status integer (0 for success)
101 int run_rpc_command(struct cli_state *cli_arg, const int pipe_idx, int conn_flags,
103 int argc, const char **argv)
105 struct cli_state *cli = NULL;
111 /* make use of cli_state handed over as an argument, if possible */
113 cli = net_make_ipc_connection(conn_flags);
123 if (!(mem_ctx = talloc_init("run_rpc_command"))) {
124 DEBUG(0, ("talloc_init() failed\n"));
129 domain_sid = net_get_remote_domain_sid(cli, mem_ctx, &domain_name);
131 if (!(conn_flags & NET_FLAGS_NO_PIPE)) {
132 if (!cli_nt_session_open(cli, pipe_idx)) {
133 DEBUG(0, ("Could not initialise pipe\n"));
139 nt_status = fn(domain_sid, domain_name, cli, mem_ctx, argc, argv);
141 if (!NT_STATUS_IS_OK(nt_status)) {
142 DEBUG(1, ("rpc command function failed! (%s)\n", nt_errstr(nt_status)));
144 DEBUG(5, ("rpc command function succedded\n"));
147 if (!(conn_flags & NET_FLAGS_NO_PIPE)) {
148 if (cli->pipes[cli->pipe_idx].fnum)
149 cli_nt_session_close(cli);
152 /* close the connection only if it was opened here */
156 talloc_destroy(mem_ctx);
158 return (!NT_STATUS_IS_OK(nt_status));
162 /****************************************************************************/
166 * Force a change of the trust acccount password.
168 * All parameters are provided by the run_rpc_command function, except for
169 * argc, argv which are passes through.
171 * @param domain_sid The domain sid aquired from the remote server
172 * @param cli A cli_state connected to the server.
173 * @param mem_ctx Talloc context, destoyed on compleation of the function.
174 * @param argc Standard main() style argc
175 * @param argc Standard main() style argv. Initial components are already
178 * @return Normal NTSTATUS return.
181 static NTSTATUS rpc_changetrustpw_internals(const DOM_SID *domain_sid, const char *domain_name,
182 struct cli_state *cli, TALLOC_CTX *mem_ctx,
183 int argc, const char **argv) {
185 return trust_pw_find_change_and_store_it(cli, mem_ctx, opt_target_workgroup);
189 * Force a change of the trust acccount password.
191 * @param argc Standard main() style argc
192 * @param argc Standard main() style argv. Initial components are already
195 * @return A shell status integer (0 for success)
198 int net_rpc_changetrustpw(int argc, const char **argv)
200 return run_rpc_command(NULL, PI_NETLOGON, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC,
201 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 equiv first.
216 * All parameters are provided by the run_rpc_command function, 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_oldjoin_internals(const DOM_SID *domain_sid, const char *domain_name,
230 struct cli_state *cli,
232 int argc, const char **argv) {
234 fstring trust_passwd;
235 unsigned char orig_trust_passwd_hash[16];
237 uint32 sec_channel_type;
240 check what type of join - if the user want's to join as
241 a BDC, the server must agree that we are a BDC.
244 sec_channel_type = get_sec_channel_type(argv[0]);
246 sec_channel_type = get_sec_channel_type(NULL);
249 fstrcpy(trust_passwd, global_myname());
250 strlower_m(trust_passwd);
253 * Machine names can be 15 characters, but the max length on
254 * a password is 14. --jerry
257 trust_passwd[14] = '\0';
259 E_md4hash(trust_passwd, orig_trust_passwd_hash);
261 result = trust_pw_change_and_store_it(cli, mem_ctx, opt_target_workgroup,
262 orig_trust_passwd_hash,
265 if (NT_STATUS_IS_OK(result))
266 printf("Joined domain %s.\n",opt_target_workgroup);
269 if (!secrets_store_domain_sid(opt_target_workgroup, domain_sid)) {
270 DEBUG(0, ("error storing domain sid for %s\n", opt_target_workgroup));
271 result = NT_STATUS_UNSUCCESSFUL;
278 * Join a domain, the old way.
280 * @param argc Standard main() style argc
281 * @param argc Standard main() style argv. Initial components are already
284 * @return A shell status integer (0 for success)
287 static int net_rpc_perform_oldjoin(int argc, const char **argv)
289 return run_rpc_command(NULL, PI_NETLOGON,
290 NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC,
291 rpc_oldjoin_internals,
296 * Join a domain, the old way. This function exists to allow
297 * the message to be displayed when oldjoin was explicitly
298 * requested, but not when it was implied by "net rpc join"
300 * @param argc Standard main() style argc
301 * @param argc Standard main() style argv. Initial components are already
304 * @return A shell status integer (0 for success)
307 static int net_rpc_oldjoin(int argc, const char **argv)
309 int rc = net_rpc_perform_oldjoin(argc, argv);
312 d_printf("Failed to join domain\n");
319 * Basic usage function for 'net rpc join'
320 * @param argc Standard main() style argc
321 * @param argc Standard main() style argv. Initial components are already
325 static int rpc_join_usage(int argc, const char **argv)
327 d_printf("net rpc join -U <username>[%%password] <type>[options]\n"\
328 "\t to join a domain with admin username & password\n"\
329 "\t\t password will be prompted if needed and none is specified\n"\
330 "\t <type> can be (default MEMBER)\n"\
331 "\t\t BDC - Join as a BDC\n"\
332 "\t\t PDC - Join as a PDC\n"\
333 "\t\t MEMBER - Join as a MEMBER server\n");
335 net_common_flags_usage(argc, argv);
340 * 'net rpc join' entrypoint.
341 * @param argc Standard main() style argc
342 * @param argc Standard main() style argv. Initial components are already
345 * Main 'net_rpc_join()' (where the admain username/password is used) is
347 * Try to just change the password, but if that doesn't work, use/prompt
348 * for a username/password.
351 int net_rpc_join(int argc, const char **argv)
353 if ((net_rpc_perform_oldjoin(argc, argv) == 0))
356 return net_rpc_join_newstyle(argc, argv);
362 * display info about a rpc domain
364 * All parameters are provided by the run_rpc_command function, except for
365 * argc, argv which are passed through.
367 * @param domain_sid The domain sid acquired from the remote server
368 * @param cli A cli_state connected to the server.
369 * @param mem_ctx Talloc context, destoyed on completion of the function.
370 * @param argc Standard main() style argc
371 * @param argv Standard main() style argv. Initial components are already
374 * @return Normal NTSTATUS return.
378 rpc_info_internals(const DOM_SID *domain_sid, const char *domain_name,
379 struct cli_state *cli,
380 TALLOC_CTX *mem_ctx, int argc, const char **argv)
382 POLICY_HND connect_pol, domain_pol;
383 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
387 sid_to_string(sid_str, domain_sid);
389 /* Get sam policy handle */
390 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
392 if (!NT_STATUS_IS_OK(result)) {
396 /* Get domain policy handle */
397 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
398 MAXIMUM_ALLOWED_ACCESS,
399 domain_sid, &domain_pol);
400 if (!NT_STATUS_IS_OK(result)) {
405 result = cli_samr_query_dom_info(cli, mem_ctx, &domain_pol,
407 if (NT_STATUS_IS_OK(result)) {
408 TALLOC_CTX *ctx = talloc_init("rpc_info_internals");
409 d_printf("Domain Name: %s\n", unistr2_tdup(ctx, &ctr.info.inf2.uni_domain));
410 d_printf("Domain SID: %s\n", sid_str);
411 d_printf("Sequence number: %u\n", ctr.info.inf2.seq_num.low);
412 d_printf("Num users: %u\n", ctr.info.inf2.num_domain_usrs);
413 d_printf("Num domain groups: %u\n", ctr.info.inf2.num_domain_grps);
414 d_printf("Num local groups: %u\n", ctr.info.inf2.num_local_grps);
424 * 'net rpc info' entrypoint.
425 * @param argc Standard main() style argc
426 * @param argc Standard main() style argv. Initial components are already
429 int net_rpc_info(int argc, const char **argv)
431 return run_rpc_command(NULL, PI_SAMR, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC,
438 * Fetch domain SID into the local secrets.tdb
440 * All parameters are provided by the run_rpc_command function, except for
441 * argc, argv which are passes through.
443 * @param domain_sid The domain sid acquired from the remote server
444 * @param cli A cli_state connected to the server.
445 * @param mem_ctx Talloc context, destoyed on completion of the function.
446 * @param argc Standard main() style argc
447 * @param argv Standard main() style argv. Initial components are already
450 * @return Normal NTSTATUS return.
454 rpc_getsid_internals(const DOM_SID *domain_sid, const char *domain_name,
455 struct cli_state *cli,
456 TALLOC_CTX *mem_ctx, int argc, const char **argv)
460 sid_to_string(sid_str, domain_sid);
461 d_printf("Storing SID %s for Domain %s in secrets.tdb\n",
462 sid_str, domain_name);
464 if (!secrets_store_domain_sid(domain_name, domain_sid)) {
465 DEBUG(0,("Can't store domain SID\n"));
466 return NT_STATUS_UNSUCCESSFUL;
474 * 'net rpc getsid' entrypoint.
475 * @param argc Standard main() style argc
476 * @param argc Standard main() style argv. Initial components are already
479 int net_rpc_getsid(int argc, const char **argv)
481 return run_rpc_command(NULL, PI_SAMR, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC,
482 rpc_getsid_internals,
487 /****************************************************************************/
490 * Basic usage function for 'net rpc user'
491 * @param argc Standard main() style argc.
492 * @param argv Standard main() style argv. Initial components are already
496 static int rpc_user_usage(int argc, const char **argv)
498 return net_help_user(argc, argv);
502 * Add a new user to a remote RPC server
504 * All parameters are provided by the run_rpc_command function, except for
505 * argc, argv which are passes through.
507 * @param domain_sid The domain sid acquired from the remote server
508 * @param cli A cli_state connected to the server.
509 * @param mem_ctx Talloc context, destoyed on completion of the function.
510 * @param argc Standard main() style argc
511 * @param argv Standard main() style argv. Initial components are already
514 * @return Normal NTSTATUS return.
517 static NTSTATUS rpc_user_add_internals(const DOM_SID *domain_sid, const char *domain_name,
518 struct cli_state *cli, TALLOC_CTX *mem_ctx,
519 int argc, const char **argv) {
521 POLICY_HND connect_pol, domain_pol, user_pol;
522 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
523 const char *acct_name;
525 uint32 unknown, user_rid;
528 d_printf("User must be specified\n");
529 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)) {
543 /* Get domain policy handle */
545 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
546 MAXIMUM_ALLOWED_ACCESS,
547 domain_sid, &domain_pol);
548 if (!NT_STATUS_IS_OK(result)) {
552 /* Create domain user */
554 acb_info = ACB_NORMAL;
555 unknown = 0xe005000b; /* No idea what this is - a permission mask? */
557 result = cli_samr_create_dom_user(cli, mem_ctx, &domain_pol,
558 acct_name, acb_info, unknown,
559 &user_pol, &user_rid);
560 if (!NT_STATUS_IS_OK(result)) {
565 if (!NT_STATUS_IS_OK(result)) {
566 d_printf("Failed to add user %s - %s\n", acct_name,
569 d_printf("Added user %s\n", acct_name);
575 * Add a new user to a remote RPC server
577 * @param argc Standard main() style argc
578 * @param argv Standard main() style argv. Initial components are already
581 * @return A shell status integer (0 for success)
584 static int rpc_user_add(int argc, const char **argv)
586 return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_add_internals,
591 * Delete a user from a remote RPC server
593 * All parameters are provided by the run_rpc_command function, except for
594 * argc, argv which are passes through.
596 * @param domain_sid The domain sid acquired from the remote server
597 * @param cli A cli_state connected to the server.
598 * @param mem_ctx Talloc context, destoyed on completion of the function.
599 * @param argc Standard main() style argc
600 * @param argv Standard main() style argv. Initial components are already
603 * @return Normal NTSTATUS return.
606 static NTSTATUS rpc_user_del_internals(const DOM_SID *domain_sid,
607 const char *domain_name,
608 struct cli_state *cli,
610 int argc, const char **argv)
612 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
613 POLICY_HND connect_pol, domain_pol, user_pol;
616 d_printf("User must be specified\n");
617 rpc_user_usage(argc, argv);
620 /* Get sam policy and domain handles */
622 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
625 if (!NT_STATUS_IS_OK(result)) {
629 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
630 MAXIMUM_ALLOWED_ACCESS,
631 domain_sid, &domain_pol);
633 if (!NT_STATUS_IS_OK(result)) {
637 /* Get handle on user */
640 uint32 *user_rids, num_rids, *name_types;
641 uint32 flags = 0x000003e8; /* Unknown */
643 result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol,
645 &num_rids, &user_rids,
648 if (!NT_STATUS_IS_OK(result)) {
652 result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
653 MAXIMUM_ALLOWED_ACCESS,
654 user_rids[0], &user_pol);
656 if (!NT_STATUS_IS_OK(result)) {
663 result = cli_samr_delete_dom_user(cli, mem_ctx, &user_pol);
665 if (!NT_STATUS_IS_OK(result)) {
669 /* Display results */
670 if (!NT_STATUS_IS_OK(result)) {
671 d_printf("Failed to delete user account - %s\n", nt_errstr(result));
673 d_printf("Deleted user account\n");
682 * Rename a user on a remote RPC server
684 * All parameters are provided by the run_rpc_command function, except for
685 * argc, argv which are passes through.
687 * @param domain_sid The domain sid acquired from the remote server
688 * @param cli A cli_state connected to the server.
689 * @param mem_ctx Talloc context, destoyed on completion of the function.
690 * @param argc Standard main() style argc
691 * @param argv Standard main() style argv. Initial components are already
694 * @return Normal NTSTATUS return.
697 static NTSTATUS rpc_user_rename_internals(const DOM_SID *domain_sid, const char *domain_name,
698 struct cli_state *cli, TALLOC_CTX *mem_ctx,
699 int argc, const char **argv) {
701 POLICY_HND connect_pol, domain_pol, user_pol;
702 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
703 uint32 info_level = 7;
704 const char *old_name, *new_name;
706 uint32 flags = 0x000003e8; /* Unknown */
707 uint32 num_rids, *name_types;
708 uint32 num_names = 1;
710 SAM_USERINFO_CTR *user_ctr;
711 SAM_USERINFO_CTR ctr;
712 SAM_USER_INFO_7 info7;
715 d_printf("Old and new username must be specified\n");
716 rpc_user_usage(argc, argv);
724 ZERO_STRUCT(user_ctr);
726 /* Get sam policy handle */
728 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
730 if (!NT_STATUS_IS_OK(result)) {
734 /* Get domain policy handle */
736 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
737 MAXIMUM_ALLOWED_ACCESS,
738 domain_sid, &domain_pol);
739 if (!NT_STATUS_IS_OK(result)) {
743 names = TALLOC_ARRAY(mem_ctx, const char *, num_names);
745 result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol,
746 flags, num_names, names,
747 &num_rids, &user_rid, &name_types);
748 if (!NT_STATUS_IS_OK(result)) {
752 /* Open domain user */
753 result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
754 MAXIMUM_ALLOWED_ACCESS, user_rid[0], &user_pol);
756 if (!NT_STATUS_IS_OK(result)) {
760 /* Query user info */
761 result = cli_samr_query_userinfo(cli, mem_ctx, &user_pol,
762 info_level, &user_ctr);
764 if (!NT_STATUS_IS_OK(result)) {
768 ctr.switch_value = info_level;
769 ctr.info.id7 = &info7;
771 init_sam_user_info7(&info7, new_name);
774 result = cli_samr_set_userinfo(cli, mem_ctx, &user_pol,
775 info_level, &cli->user_session_key, &ctr);
777 if (!NT_STATUS_IS_OK(result)) {
782 if (!NT_STATUS_IS_OK(result)) {
783 d_printf("Failed to rename user from %s to %s - %s\n", old_name, new_name,
786 d_printf("Renamed user from %s to %s\n", old_name, new_name);
793 * Rename a user on a remote RPC server
795 * @param argc Standard main() style argc
796 * @param argv Standard main() style argv. Initial components are already
799 * @return A shell status integer (0 for success)
802 static int rpc_user_rename(int argc, const char **argv)
804 return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_rename_internals,
809 * Delete a user from a remote RPC server
811 * @param argc Standard main() style argc
812 * @param argv Standard main() style argv. Initial components are already
815 * @return A shell status integer (0 for success)
818 static int rpc_user_delete(int argc, const char **argv)
820 return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_del_internals,
825 * Set a password for a user on a remote RPC server
827 * All parameters are provided by the run_rpc_command function, except for
828 * argc, argv which are passes through.
830 * @param domain_sid The domain sid acquired from the remote server
831 * @param cli A cli_state connected to the server.
832 * @param mem_ctx Talloc context, destoyed on completion of the function.
833 * @param argc Standard main() style argc
834 * @param argv Standard main() style argv. Initial components are already
837 * @return Normal NTSTATUS return.
840 static NTSTATUS rpc_user_password_internals(const DOM_SID *domain_sid,
841 const char *domain_name,
842 struct cli_state *cli,
844 int argc, const char **argv)
846 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
847 POLICY_HND connect_pol, domain_pol, user_pol;
848 SAM_USERINFO_CTR ctr;
849 SAM_USER_INFO_24 p24;
852 const char *new_password;
856 d_printf("User must be specified\n");
857 rpc_user_usage(argc, argv);
864 new_password = argv[1];
866 asprintf(&prompt, "Enter new password for %s:", user);
867 new_password = getpass(prompt);
871 /* Get sam policy and domain handles */
873 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
876 if (!NT_STATUS_IS_OK(result)) {
880 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
881 MAXIMUM_ALLOWED_ACCESS,
882 domain_sid, &domain_pol);
884 if (!NT_STATUS_IS_OK(result)) {
888 /* Get handle on user */
891 uint32 *user_rids, num_rids, *name_types;
892 uint32 flags = 0x000003e8; /* Unknown */
894 result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol,
896 &num_rids, &user_rids,
899 if (!NT_STATUS_IS_OK(result)) {
903 result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
904 MAXIMUM_ALLOWED_ACCESS,
905 user_rids[0], &user_pol);
907 if (!NT_STATUS_IS_OK(result)) {
912 /* Set password on account */
917 encode_pw_buffer(pwbuf, new_password, STR_UNICODE);
919 init_sam_user_info24(&p24, (char *)pwbuf,24);
921 ctr.switch_value = 24;
922 ctr.info.id24 = &p24;
924 result = cli_samr_set_userinfo(cli, mem_ctx, &user_pol, 24,
925 &cli->user_session_key, &ctr);
927 if (!NT_STATUS_IS_OK(result)) {
931 /* Display results */
939 * Set a user's password on a remote RPC server
941 * @param argc Standard main() style argc
942 * @param argv Standard main() style argv. Initial components are already
945 * @return A shell status integer (0 for success)
948 static int rpc_user_password(int argc, const char **argv)
950 return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_password_internals,
955 * List user's groups on a remote RPC server
957 * All parameters are provided by the run_rpc_command function, except for
958 * argc, argv which are passes through.
960 * @param domain_sid The domain sid acquired from the remote server
961 * @param cli A cli_state connected to the server.
962 * @param mem_ctx Talloc context, destoyed on completion of the function.
963 * @param argc Standard main() style argc
964 * @param argv Standard main() style argv. Initial components are already
967 * @return Normal NTSTATUS return.
971 rpc_user_info_internals(const DOM_SID *domain_sid, const char *domain_name,
972 struct cli_state *cli,
973 TALLOC_CTX *mem_ctx, int argc, const char **argv)
975 POLICY_HND connect_pol, domain_pol, user_pol;
976 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
977 uint32 *rids, num_rids, *name_types, num_names;
978 uint32 flags = 0x000003e8; /* Unknown */
984 d_printf("User must be specified\n");
985 rpc_user_usage(argc, argv);
988 /* Get sam policy handle */
990 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
992 if (!NT_STATUS_IS_OK(result)) goto done;
994 /* Get domain policy handle */
996 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
997 MAXIMUM_ALLOWED_ACCESS,
998 domain_sid, &domain_pol);
999 if (!NT_STATUS_IS_OK(result)) goto done;
1001 /* Get handle on user */
1003 result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol,
1005 &num_rids, &rids, &name_types);
1007 if (!NT_STATUS_IS_OK(result)) goto done;
1009 result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
1010 MAXIMUM_ALLOWED_ACCESS,
1011 rids[0], &user_pol);
1012 if (!NT_STATUS_IS_OK(result)) goto done;
1014 result = cli_samr_query_usergroups(cli, mem_ctx, &user_pol,
1015 &num_rids, &user_gids);
1017 if (!NT_STATUS_IS_OK(result)) goto done;
1022 rids = TALLOC_ARRAY(mem_ctx, uint32, num_rids);
1024 for (i = 0; i < num_rids; i++)
1025 rids[i] = user_gids[i].g_rid;
1027 result = cli_samr_lookup_rids(cli, mem_ctx, &domain_pol,
1029 &num_names, &names, &name_types);
1031 if (!NT_STATUS_IS_OK(result)) {
1035 /* Display results */
1037 for (i = 0; i < num_names; i++)
1038 printf("%s\n", names[i]);
1045 * List a user's groups from a remote RPC server
1047 * @param argc Standard main() style argc
1048 * @param argv Standard main() style argv. Initial components are already
1051 * @return A shell status integer (0 for success)
1054 static int rpc_user_info(int argc, const char **argv)
1056 return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_info_internals,
1061 * List users on a remote RPC server
1063 * All parameters are provided by the run_rpc_command function, except for
1064 * argc, argv which are passes through.
1066 * @param domain_sid The domain sid acquired from the remote server
1067 * @param cli A cli_state connected to the server.
1068 * @param mem_ctx Talloc context, destoyed on completion of the function.
1069 * @param argc Standard main() style argc
1070 * @param argv Standard main() style argv. Initial components are already
1073 * @return Normal NTSTATUS return.
1077 rpc_user_list_internals(const DOM_SID *domain_sid, const char *domain_name,
1078 struct cli_state *cli,
1079 TALLOC_CTX *mem_ctx, int argc, const char **argv)
1081 POLICY_HND connect_pol, domain_pol;
1082 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1083 uint32 start_idx=0, num_entries, i, loop_count = 0;
1084 SAM_DISPINFO_CTR ctr;
1085 SAM_DISPINFO_1 info1;
1087 /* Get sam policy handle */
1089 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1091 if (!NT_STATUS_IS_OK(result)) {
1095 /* Get domain policy handle */
1097 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
1098 MAXIMUM_ALLOWED_ACCESS,
1099 domain_sid, &domain_pol);
1100 if (!NT_STATUS_IS_OK(result)) {
1104 /* Query domain users */
1107 ctr.sam.info1 = &info1;
1108 if (opt_long_list_entries)
1109 d_printf("\nUser name Comment"\
1110 "\n-----------------------------\n");
1113 uint32 max_entries, max_size;
1115 get_query_dispinfo_params(
1116 loop_count, &max_entries, &max_size);
1118 result = cli_samr_query_dispinfo(cli, mem_ctx, &domain_pol,
1119 &start_idx, 1, &num_entries,
1120 max_entries, max_size, &ctr);
1123 for (i = 0; i < num_entries; i++) {
1124 unistr2_to_ascii(user, &(&ctr.sam.info1->str[i])->uni_acct_name, sizeof(user)-1);
1125 if (opt_long_list_entries)
1126 unistr2_to_ascii(desc, &(&ctr.sam.info1->str[i])->uni_acct_desc, sizeof(desc)-1);
1128 if (opt_long_list_entries)
1129 printf("%-21.21s %s\n", user, desc);
1131 printf("%s\n", user);
1133 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
1140 * 'net rpc user' entrypoint.
1141 * @param argc Standard main() style argc
1142 * @param argc Standard main() style argv. Initial components are already
1146 int net_rpc_user(int argc, const char **argv)
1148 struct functable func[] = {
1149 {"add", rpc_user_add},
1150 {"info", rpc_user_info},
1151 {"delete", rpc_user_delete},
1152 {"password", rpc_user_password},
1153 {"rename", rpc_user_rename},
1158 return run_rpc_command(NULL,PI_SAMR, 0,
1159 rpc_user_list_internals,
1163 return net_run_function(argc, argv, func, rpc_user_usage);
1167 /****************************************************************************/
1170 * Basic usage function for 'net rpc group'
1171 * @param argc Standard main() style argc.
1172 * @param argv Standard main() style argv. Initial components are already
1176 static int rpc_group_usage(int argc, const char **argv)
1178 return net_help_group(argc, argv);
1182 * Delete group on a remote RPC server
1184 * All parameters are provided by the run_rpc_command function, except for
1185 * argc, argv which are passes through.
1187 * @param domain_sid The domain sid acquired from the remote server
1188 * @param cli A cli_state connected to the server.
1189 * @param mem_ctx Talloc context, destoyed on completion of the function.
1190 * @param argc Standard main() style argc
1191 * @param argv Standard main() style argv. Initial components are already
1194 * @return Normal NTSTATUS return.
1197 static NTSTATUS rpc_group_delete_internals(const DOM_SID *domain_sid,
1198 const char *domain_name,
1199 struct cli_state *cli,
1200 TALLOC_CTX *mem_ctx,
1201 int argc, const char **argv)
1203 POLICY_HND connect_pol, domain_pol, group_pol, user_pol;
1204 BOOL group_is_primary = False;
1205 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1207 uint32 *group_rids, num_rids, *name_types, num_members,
1208 *group_attrs, group_rid;
1209 uint32 flags = 0x000003e8; /* Unknown */
1212 /* DOM_GID *user_gids; */
1213 SAM_USERINFO_CTR *user_ctr;
1217 d_printf("specify group\n");
1218 rpc_group_usage(argc,argv);
1219 return NT_STATUS_OK; /* ok? */
1222 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1225 if (!NT_STATUS_IS_OK(result)) {
1226 d_printf("Request samr_connect failed\n");
1230 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
1231 MAXIMUM_ALLOWED_ACCESS,
1232 domain_sid, &domain_pol);
1234 if (!NT_STATUS_IS_OK(result)) {
1235 d_printf("Request open_domain failed\n");
1239 result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol,
1241 &num_rids, &group_rids,
1244 if (!NT_STATUS_IS_OK(result)) {
1245 d_printf("Lookup of '%s' failed\n",argv[0]);
1249 switch (name_types[0])
1251 case SID_NAME_DOM_GRP:
1252 result = cli_samr_open_group(cli, mem_ctx, &domain_pol,
1253 MAXIMUM_ALLOWED_ACCESS,
1254 group_rids[0], &group_pol);
1255 if (!NT_STATUS_IS_OK(result)) {
1256 d_printf("Request open_group failed");
1260 group_rid = group_rids[0];
1262 result = cli_samr_query_groupmem(cli, mem_ctx, &group_pol,
1263 &num_members, &group_rids,
1266 if (!NT_STATUS_IS_OK(result)) {
1267 d_printf("Unable to query group members of %s",argv[0]);
1272 d_printf("Domain Group %s (rid: %d) has %d members\n",
1273 argv[0],group_rid,num_members);
1276 /* Check if group is anyone's primary group */
1277 for (i = 0; i < num_members; i++)
1279 result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
1280 MAXIMUM_ALLOWED_ACCESS,
1281 group_rids[i], &user_pol);
1283 if (!NT_STATUS_IS_OK(result)) {
1284 d_printf("Unable to open group member %d\n",group_rids[i]);
1288 ZERO_STRUCT(user_ctr);
1290 result = cli_samr_query_userinfo(cli, mem_ctx, &user_pol,
1293 if (!NT_STATUS_IS_OK(result)) {
1294 d_printf("Unable to lookup userinfo for group member %d\n",group_rids[i]);
1298 if (user_ctr->info.id21->group_rid == group_rid) {
1299 unistr2_to_ascii(temp, &(user_ctr->info.id21)->uni_user_name,
1302 d_printf("Group is primary group of %s\n",temp);
1303 group_is_primary = True;
1306 cli_samr_close(cli, mem_ctx, &user_pol);
1309 if (group_is_primary) {
1310 d_printf("Unable to delete group because some of it's "
1311 "members have it as primary group\n");
1312 result = NT_STATUS_MEMBERS_PRIMARY_GROUP;
1316 /* remove all group members */
1317 for (i = 0; i < num_members; i++)
1320 d_printf("Remove group member %d...",group_rids[i]);
1321 result = cli_samr_del_groupmem(cli, mem_ctx, &group_pol, group_rids[i]);
1323 if (NT_STATUS_IS_OK(result)) {
1328 d_printf("failed\n");
1333 result = cli_samr_delete_dom_group(cli, mem_ctx, &group_pol);
1336 /* removing a local group is easier... */
1337 case SID_NAME_ALIAS:
1338 result = cli_samr_open_alias(cli, mem_ctx, &domain_pol,
1339 MAXIMUM_ALLOWED_ACCESS,
1340 group_rids[0], &group_pol);
1342 if (!NT_STATUS_IS_OK(result)) {
1343 d_printf("Request open_alias failed\n");
1347 result = cli_samr_delete_dom_alias(cli, mem_ctx, &group_pol);
1350 d_printf("%s is of type %s. This command is only for deleting local or global groups\n",
1351 argv[0],sid_type_lookup(name_types[0]));
1352 result = NT_STATUS_UNSUCCESSFUL;
1357 if (NT_STATUS_IS_OK(result)) {
1359 d_printf("Deleted %s '%s'\n",sid_type_lookup(name_types[0]),argv[0]);
1361 d_printf("Deleting of %s failed: %s\n",argv[0],
1362 get_friendly_nt_error_msg(result));
1370 static int rpc_group_delete(int argc, const char **argv)
1372 return run_rpc_command(NULL, PI_SAMR, 0, rpc_group_delete_internals,
1377 rpc_group_add_internals(const DOM_SID *domain_sid, const char *domain_name,
1378 struct cli_state *cli,
1379 TALLOC_CTX *mem_ctx, int argc, const char **argv)
1381 POLICY_HND connect_pol, domain_pol, group_pol;
1382 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1383 GROUP_INFO_CTR group_info;
1386 d_printf("Group name must be specified\n");
1387 rpc_group_usage(argc, argv);
1388 return NT_STATUS_OK;
1391 /* Get sam policy handle */
1393 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1395 if (!NT_STATUS_IS_OK(result)) goto done;
1397 /* Get domain policy handle */
1399 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
1400 MAXIMUM_ALLOWED_ACCESS,
1401 domain_sid, &domain_pol);
1402 if (!NT_STATUS_IS_OK(result)) goto done;
1404 /* Create the group */
1406 result = cli_samr_create_dom_group(cli, mem_ctx, &domain_pol,
1407 argv[0], MAXIMUM_ALLOWED_ACCESS,
1409 if (!NT_STATUS_IS_OK(result)) goto done;
1411 if (strlen(opt_comment) == 0) goto done;
1413 /* We've got a comment to set */
1415 group_info.switch_value1 = 4;
1416 init_samr_group_info4(&group_info.group.info4, opt_comment);
1418 result = cli_samr_set_groupinfo(cli, mem_ctx, &group_pol, &group_info);
1419 if (!NT_STATUS_IS_OK(result)) goto done;
1422 if (NT_STATUS_IS_OK(result))
1423 DEBUG(5, ("add group succeeded\n"));
1425 d_printf("add group failed: %s\n", nt_errstr(result));
1431 rpc_alias_add_internals(const DOM_SID *domain_sid, const char *domain_name,
1432 struct cli_state *cli,
1433 TALLOC_CTX *mem_ctx, int argc, const char **argv)
1435 POLICY_HND connect_pol, domain_pol, alias_pol;
1436 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1437 ALIAS_INFO_CTR alias_info;
1440 d_printf("Alias name must be specified\n");
1441 rpc_group_usage(argc, argv);
1442 return NT_STATUS_OK;
1445 /* Get sam policy handle */
1447 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1449 if (!NT_STATUS_IS_OK(result)) goto done;
1451 /* Get domain policy handle */
1453 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
1454 MAXIMUM_ALLOWED_ACCESS,
1455 domain_sid, &domain_pol);
1456 if (!NT_STATUS_IS_OK(result)) goto done;
1458 /* Create the group */
1460 result = cli_samr_create_dom_alias(cli, mem_ctx, &domain_pol,
1461 argv[0], &alias_pol);
1462 if (!NT_STATUS_IS_OK(result)) goto done;
1464 if (strlen(opt_comment) == 0) goto done;
1466 /* We've got a comment to set */
1468 alias_info.level = 3;
1469 init_samr_alias_info3(&alias_info.alias.info3, opt_comment);
1471 result = cli_samr_set_aliasinfo(cli, mem_ctx, &alias_pol, &alias_info);
1472 if (!NT_STATUS_IS_OK(result)) goto done;
1475 if (NT_STATUS_IS_OK(result))
1476 DEBUG(5, ("add alias succeeded\n"));
1478 d_printf("add alias failed: %s\n", nt_errstr(result));
1483 static int rpc_group_add(int argc, const char **argv)
1486 return run_rpc_command(NULL, PI_SAMR, 0,
1487 rpc_alias_add_internals,
1490 return run_rpc_command(NULL, PI_SAMR, 0,
1491 rpc_group_add_internals,
1496 get_sid_from_name(struct cli_state *cli, TALLOC_CTX *mem_ctx, const char *name,
1497 DOM_SID *sid, enum SID_NAME_USE *type)
1499 int current_pipe = cli->pipe_idx;
1501 DOM_SID *sids = NULL;
1502 uint32 *types = NULL;
1504 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1506 if (current_pipe != PI_LSARPC) {
1508 if (current_pipe != -1)
1509 cli_nt_session_close(cli);
1511 if (!cli_nt_session_open(cli, PI_LSARPC))
1515 result = cli_lsa_open_policy(cli, mem_ctx, False,
1516 SEC_RIGHTS_MAXIMUM_ALLOWED, &lsa_pol);
1518 if (!NT_STATUS_IS_OK(result))
1521 result = cli_lsa_lookup_names(cli, mem_ctx, &lsa_pol, 1,
1522 &name, &sids, &types);
1524 if (NT_STATUS_IS_OK(result)) {
1525 sid_copy(sid, &sids[0]);
1529 cli_lsa_close(cli, mem_ctx, &lsa_pol);
1532 if (current_pipe != PI_LSARPC) {
1533 cli_nt_session_close(cli);
1534 if (current_pipe != -1)
1535 cli_nt_session_open(cli, current_pipe);
1538 if (!NT_STATUS_IS_OK(result) && (StrnCaseCmp(name, "S-", 2) == 0)) {
1540 /* Try as S-1-5-whatever */
1544 if (string_to_sid(&tmp_sid, name)) {
1545 sid_copy(sid, &tmp_sid);
1546 *type = SID_NAME_UNKNOWN;
1547 result = NT_STATUS_OK;
1555 rpc_add_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1556 const DOM_SID *group_sid, const char *member)
1558 POLICY_HND connect_pol, domain_pol;
1561 POLICY_HND group_pol;
1564 uint32 *rids = NULL;
1565 uint32 *rid_types = NULL;
1569 sid_copy(&sid, group_sid);
1571 if (!sid_split_rid(&sid, &group_rid))
1572 return NT_STATUS_UNSUCCESSFUL;
1574 /* Get sam policy handle */
1575 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1577 if (!NT_STATUS_IS_OK(result))
1580 /* Get domain policy handle */
1581 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
1582 MAXIMUM_ALLOWED_ACCESS,
1584 if (!NT_STATUS_IS_OK(result))
1587 result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol, 1000,
1589 &num_rids, &rids, &rid_types);
1591 if (!NT_STATUS_IS_OK(result)) {
1592 d_printf("Could not lookup up group member %s\n", member);
1596 result = cli_samr_open_group(cli, mem_ctx, &domain_pol,
1597 MAXIMUM_ALLOWED_ACCESS,
1598 group_rid, &group_pol);
1600 if (!NT_STATUS_IS_OK(result))
1603 result = cli_samr_add_groupmem(cli, mem_ctx, &group_pol, rids[0]);
1606 cli_samr_close(cli, mem_ctx, &connect_pol);
1611 rpc_add_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1612 const DOM_SID *alias_sid, const char *member)
1614 POLICY_HND connect_pol, domain_pol;
1617 POLICY_HND alias_pol;
1620 enum SID_NAME_USE member_type;
1624 sid_copy(&sid, alias_sid);
1626 if (!sid_split_rid(&sid, &alias_rid))
1627 return NT_STATUS_UNSUCCESSFUL;
1629 result = get_sid_from_name(cli, mem_ctx, member,
1630 &member_sid, &member_type);
1632 if (!NT_STATUS_IS_OK(result)) {
1633 d_printf("Could not lookup up group member %s\n", member);
1637 /* Get sam policy handle */
1638 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1640 if (!NT_STATUS_IS_OK(result)) {
1644 /* Get domain policy handle */
1645 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
1646 MAXIMUM_ALLOWED_ACCESS,
1648 if (!NT_STATUS_IS_OK(result)) {
1652 result = cli_samr_open_alias(cli, mem_ctx, &domain_pol,
1653 MAXIMUM_ALLOWED_ACCESS,
1654 alias_rid, &alias_pol);
1656 if (!NT_STATUS_IS_OK(result))
1659 result = cli_samr_add_aliasmem(cli, mem_ctx, &alias_pol, &member_sid);
1661 if (!NT_STATUS_IS_OK(result))
1665 cli_samr_close(cli, mem_ctx, &connect_pol);
1670 rpc_group_addmem_internals(const DOM_SID *domain_sid, const char *domain_name,
1671 struct cli_state *cli,
1672 TALLOC_CTX *mem_ctx, int argc, const char **argv)
1675 enum SID_NAME_USE group_type;
1678 d_printf("Usage: 'net rpc group addmem <group> <member>\n");
1679 return NT_STATUS_UNSUCCESSFUL;
1682 if (!NT_STATUS_IS_OK(get_sid_from_name(cli, mem_ctx, argv[0],
1683 &group_sid, &group_type))) {
1684 d_printf("Could not lookup group name %s\n", argv[0]);
1685 return NT_STATUS_UNSUCCESSFUL;
1688 if (group_type == SID_NAME_DOM_GRP) {
1689 NTSTATUS result = rpc_add_groupmem(cli, mem_ctx,
1690 &group_sid, argv[1]);
1692 if (!NT_STATUS_IS_OK(result)) {
1693 d_printf("Could not add %s to %s: %s\n",
1694 argv[1], argv[0], nt_errstr(result));
1699 if (group_type == SID_NAME_ALIAS) {
1700 NTSTATUS result = rpc_add_aliasmem(cli, mem_ctx,
1701 &group_sid, argv[1]);
1703 if (!NT_STATUS_IS_OK(result)) {
1704 d_printf("Could not add %s to %s: %s\n",
1705 argv[1], argv[0], nt_errstr(result));
1710 d_printf("Can only add members to global or local groups which "
1711 "%s is not\n", argv[0]);
1713 return NT_STATUS_UNSUCCESSFUL;
1716 static int rpc_group_addmem(int argc, const char **argv)
1718 return run_rpc_command(NULL, PI_SAMR, 0,
1719 rpc_group_addmem_internals,
1724 rpc_del_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1725 const DOM_SID *group_sid, const char *member)
1727 POLICY_HND connect_pol, domain_pol;
1730 POLICY_HND group_pol;
1733 uint32 *rids = NULL;
1734 uint32 *rid_types = NULL;
1738 sid_copy(&sid, group_sid);
1740 if (!sid_split_rid(&sid, &group_rid))
1741 return NT_STATUS_UNSUCCESSFUL;
1743 /* Get sam policy handle */
1744 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1746 if (!NT_STATUS_IS_OK(result))
1749 /* Get domain policy handle */
1750 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
1751 MAXIMUM_ALLOWED_ACCESS,
1753 if (!NT_STATUS_IS_OK(result))
1756 result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol, 1000,
1758 &num_rids, &rids, &rid_types);
1760 if (!NT_STATUS_IS_OK(result)) {
1761 d_printf("Could not lookup up group member %s\n", member);
1765 result = cli_samr_open_group(cli, mem_ctx, &domain_pol,
1766 MAXIMUM_ALLOWED_ACCESS,
1767 group_rid, &group_pol);
1769 if (!NT_STATUS_IS_OK(result))
1772 result = cli_samr_del_groupmem(cli, mem_ctx, &group_pol, rids[0]);
1775 cli_samr_close(cli, mem_ctx, &connect_pol);
1780 rpc_del_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1781 const DOM_SID *alias_sid, const char *member)
1783 POLICY_HND connect_pol, domain_pol;
1786 POLICY_HND alias_pol;
1789 enum SID_NAME_USE member_type;
1793 sid_copy(&sid, alias_sid);
1795 if (!sid_split_rid(&sid, &alias_rid))
1796 return NT_STATUS_UNSUCCESSFUL;
1798 result = get_sid_from_name(cli, mem_ctx, member,
1799 &member_sid, &member_type);
1801 if (!NT_STATUS_IS_OK(result)) {
1802 d_printf("Could not lookup up group member %s\n", member);
1806 /* Get sam policy handle */
1807 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1809 if (!NT_STATUS_IS_OK(result)) {
1813 /* Get domain policy handle */
1814 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
1815 MAXIMUM_ALLOWED_ACCESS,
1817 if (!NT_STATUS_IS_OK(result)) {
1821 result = cli_samr_open_alias(cli, mem_ctx, &domain_pol,
1822 MAXIMUM_ALLOWED_ACCESS,
1823 alias_rid, &alias_pol);
1825 if (!NT_STATUS_IS_OK(result))
1828 result = cli_samr_del_aliasmem(cli, mem_ctx, &alias_pol, &member_sid);
1830 if (!NT_STATUS_IS_OK(result))
1834 cli_samr_close(cli, mem_ctx, &connect_pol);
1839 rpc_group_delmem_internals(const DOM_SID *domain_sid, const char *domain_name,
1840 struct cli_state *cli,
1841 TALLOC_CTX *mem_ctx, int argc, const char **argv)
1844 enum SID_NAME_USE group_type;
1847 d_printf("Usage: 'net rpc group delmem <group> <member>\n");
1848 return NT_STATUS_UNSUCCESSFUL;
1851 if (!NT_STATUS_IS_OK(get_sid_from_name(cli, mem_ctx, argv[0],
1852 &group_sid, &group_type))) {
1853 d_printf("Could not lookup group name %s\n", argv[0]);
1854 return NT_STATUS_UNSUCCESSFUL;
1857 if (group_type == SID_NAME_DOM_GRP) {
1858 NTSTATUS result = rpc_del_groupmem(cli, mem_ctx,
1859 &group_sid, argv[1]);
1861 if (!NT_STATUS_IS_OK(result)) {
1862 d_printf("Could not del %s from %s: %s\n",
1863 argv[1], argv[0], nt_errstr(result));
1868 if (group_type == SID_NAME_ALIAS) {
1869 NTSTATUS result = rpc_del_aliasmem(cli, mem_ctx,
1870 &group_sid, argv[1]);
1872 if (!NT_STATUS_IS_OK(result)) {
1873 d_printf("Could not del %s from %s: %s\n",
1874 argv[1], argv[0], nt_errstr(result));
1879 d_printf("Can only delete members from global or local groups which "
1880 "%s is not\n", argv[0]);
1882 return NT_STATUS_UNSUCCESSFUL;
1885 static int rpc_group_delmem(int argc, const char **argv)
1887 return run_rpc_command(NULL, PI_SAMR, 0,
1888 rpc_group_delmem_internals,
1893 * List groups on a remote RPC server
1895 * All parameters are provided by the run_rpc_command function, except for
1896 * argc, argv which are passes through.
1898 * @param domain_sid The domain sid acquired from the remote server
1899 * @param cli A cli_state connected to the server.
1900 * @param mem_ctx Talloc context, destoyed on completion of the function.
1901 * @param argc Standard main() style argc
1902 * @param argv Standard main() style argv. Initial components are already
1905 * @return Normal NTSTATUS return.
1909 rpc_group_list_internals(const DOM_SID *domain_sid, const char *domain_name,
1910 struct cli_state *cli,
1911 TALLOC_CTX *mem_ctx, int argc, const char **argv)
1913 POLICY_HND connect_pol, domain_pol;
1914 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1915 uint32 start_idx=0, max_entries=250, num_entries, i, loop_count = 0;
1916 struct acct_info *groups;
1917 BOOL global = False;
1919 BOOL builtin = False;
1927 for (i=0; i<argc; i++) {
1928 if (strequal(argv[i], "global"))
1931 if (strequal(argv[i], "local"))
1934 if (strequal(argv[i], "builtin"))
1938 /* Get sam policy handle */
1940 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1942 if (!NT_STATUS_IS_OK(result)) {
1946 /* Get domain policy handle */
1948 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
1949 MAXIMUM_ALLOWED_ACCESS,
1950 domain_sid, &domain_pol);
1951 if (!NT_STATUS_IS_OK(result)) {
1955 /* Query domain groups */
1956 if (opt_long_list_entries)
1957 d_printf("\nGroup name Comment"\
1958 "\n-----------------------------\n");
1960 SAM_DISPINFO_CTR ctr;
1961 SAM_DISPINFO_3 info3;
1966 ctr.sam.info3 = &info3;
1970 get_query_dispinfo_params(
1971 loop_count, &max_entries, &max_size);
1973 result = cli_samr_query_dispinfo(cli, mem_ctx, &domain_pol,
1974 &start_idx, 3, &num_entries,
1975 max_entries, max_size, &ctr);
1977 if (!NT_STATUS_IS_OK(result) &&
1978 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
1981 for (i = 0; i < num_entries; i++) {
1983 fstring group, desc;
1985 unistr2_to_ascii(group, &(&ctr.sam.info3->str[i])->uni_grp_name, sizeof(group)-1);
1986 unistr2_to_ascii(desc, &(&ctr.sam.info3->str[i])->uni_grp_desc, sizeof(desc)-1);
1988 if (opt_long_list_entries)
1989 printf("%-21.21s %-50.50s\n",
1992 printf("%s\n", group);
1994 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
1995 /* query domain aliases */
2000 /* The max_size field in cli_samr_enum_als_groups is more like
2001 * an account_control field with indiviual bits what to
2002 * retrieve. Set this to 0xffff as NT4 usrmgr.exe does to get
2003 * everything. I'm too lazy (sorry) to get this through to
2004 * rpc_parse/ etc. Volker */
2006 result = cli_samr_enum_als_groups(cli, mem_ctx, &domain_pol,
2008 &groups, &num_entries);
2010 if (!NT_STATUS_IS_OK(result) &&
2011 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
2014 for (i = 0; i < num_entries; i++) {
2016 char *description = NULL;
2018 if (opt_long_list_entries) {
2020 POLICY_HND alias_pol;
2023 if ((NT_STATUS_IS_OK(cli_samr_open_alias(cli, mem_ctx,
2028 (NT_STATUS_IS_OK(cli_samr_query_alias_info(cli, mem_ctx,
2031 (NT_STATUS_IS_OK(cli_samr_close(cli, mem_ctx,
2033 description = unistr2_tdup(mem_ctx,
2034 ctr.alias.info3.description.string);
2038 if (description != NULL) {
2039 printf("%-21.21s %-50.50s\n",
2040 groups[i].acct_name,
2043 printf("%s\n", groups[i].acct_name);
2046 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
2047 cli_samr_close(cli, mem_ctx, &domain_pol);
2048 /* Get builtin policy handle */
2050 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
2051 MAXIMUM_ALLOWED_ACCESS,
2052 &global_sid_Builtin, &domain_pol);
2053 if (!NT_STATUS_IS_OK(result)) {
2056 /* query builtin aliases */
2059 if (!builtin) break;
2061 result = cli_samr_enum_als_groups(cli, mem_ctx, &domain_pol,
2062 &start_idx, max_entries,
2063 &groups, &num_entries);
2065 if (!NT_STATUS_IS_OK(result) &&
2066 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
2069 for (i = 0; i < num_entries; i++) {
2071 char *description = NULL;
2073 if (opt_long_list_entries) {
2075 POLICY_HND alias_pol;
2078 if ((NT_STATUS_IS_OK(cli_samr_open_alias(cli, mem_ctx,
2083 (NT_STATUS_IS_OK(cli_samr_query_alias_info(cli, mem_ctx,
2086 (NT_STATUS_IS_OK(cli_samr_close(cli, mem_ctx,
2088 description = unistr2_tdup(mem_ctx,
2089 ctr.alias.info3.description.string);
2093 if (description != NULL) {
2094 printf("%-21.21s %-50.50s\n",
2095 groups[i].acct_name,
2098 printf("%s\n", groups[i].acct_name);
2101 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
2107 static int rpc_group_list(int argc, const char **argv)
2109 return run_rpc_command(NULL, PI_SAMR, 0,
2110 rpc_group_list_internals,
2115 rpc_list_group_members(struct cli_state *cli, TALLOC_CTX *mem_ctx,
2116 const char *domain_name, const DOM_SID *domain_sid,
2117 POLICY_HND *domain_pol, uint32 rid)
2120 POLICY_HND group_pol;
2121 uint32 num_members, *group_rids, *group_attrs;
2128 sid_to_string(sid_str, domain_sid);
2130 result = cli_samr_open_group(cli, mem_ctx, domain_pol,
2131 MAXIMUM_ALLOWED_ACCESS,
2134 if (!NT_STATUS_IS_OK(result))
2137 result = cli_samr_query_groupmem(cli, mem_ctx, &group_pol,
2138 &num_members, &group_rids,
2141 if (!NT_STATUS_IS_OK(result))
2144 while (num_members > 0) {
2145 int this_time = 512;
2147 if (num_members < this_time)
2148 this_time = num_members;
2150 result = cli_samr_lookup_rids(cli, mem_ctx, domain_pol,
2151 this_time, group_rids,
2152 &num_names, &names, &name_types);
2154 if (!NT_STATUS_IS_OK(result))
2157 /* We only have users as members, but make the output
2158 the same as the output of alias members */
2160 for (i = 0; i < this_time; i++) {
2162 if (opt_long_list_entries) {
2163 printf("%s-%d %s\\%s %d\n", sid_str,
2164 group_rids[i], domain_name, names[i],
2167 printf("%s\\%s\n", domain_name, names[i]);
2171 num_members -= this_time;
2175 return NT_STATUS_OK;
2179 rpc_list_alias_members(struct cli_state *cli, TALLOC_CTX *mem_ctx,
2180 POLICY_HND *domain_pol, uint32 rid)
2183 POLICY_HND alias_pol, lsa_pol;
2185 DOM_SID *alias_sids;
2191 result = cli_samr_open_alias(cli, mem_ctx, domain_pol,
2192 MAXIMUM_ALLOWED_ACCESS, rid, &alias_pol);
2194 if (!NT_STATUS_IS_OK(result))
2197 result = cli_samr_query_aliasmem(cli, mem_ctx, &alias_pol,
2198 &num_members, &alias_sids);
2200 if (!NT_STATUS_IS_OK(result)) {
2201 d_printf("Couldn't list alias members\n");
2205 if (num_members == 0) {
2206 return NT_STATUS_OK;
2209 cli_nt_session_close(cli);
2211 if (!cli_nt_session_open(cli, PI_LSARPC)) {
2212 d_printf("Couldn't open LSA pipe\n");
2216 result = cli_lsa_open_policy(cli, mem_ctx, True,
2217 SEC_RIGHTS_MAXIMUM_ALLOWED, &lsa_pol);
2219 if (!NT_STATUS_IS_OK(result)) {
2220 d_printf("Couldn't open LSA policy handle\n");
2224 result = cli_lsa_lookup_sids(cli, mem_ctx, &lsa_pol, num_members,
2226 &domains, &names, &types);
2228 if (!NT_STATUS_IS_OK(result) &&
2229 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
2230 d_printf("Couldn't lookup SIDs\n");
2234 for (i = 0; i < num_members; i++) {
2236 sid_to_string(sid_str, &alias_sids[i]);
2238 if (opt_long_list_entries) {
2239 printf("%s %s\\%s %d\n", sid_str,
2240 domains[i] ? domains[i] : "*unknown*",
2241 names[i] ? names[i] : "*unknown*", types[i]);
2244 printf("%s\\%s\n", domains[i], names[i]);
2246 printf("%s\n", sid_str);
2250 return NT_STATUS_OK;
2254 rpc_group_members_internals(const DOM_SID *domain_sid,
2255 const char *domain_name,
2256 struct cli_state *cli,
2257 TALLOC_CTX *mem_ctx, int argc, const char **argv)
2260 POLICY_HND connect_pol, domain_pol;
2261 uint32 num_rids, *rids, *rid_types;
2263 /* Get sam policy handle */
2265 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
2268 if (!NT_STATUS_IS_OK(result))
2271 /* Get domain policy handle */
2273 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
2274 MAXIMUM_ALLOWED_ACCESS,
2275 domain_sid, &domain_pol);
2277 if (!NT_STATUS_IS_OK(result))
2280 result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol, 1000,
2281 1, argv, &num_rids, &rids, &rid_types);
2283 if (!NT_STATUS_IS_OK(result)) {
2285 /* Ok, did not find it in the global sam, try with builtin */
2287 DOM_SID sid_Builtin;
2289 cli_samr_close(cli, mem_ctx, &domain_pol);
2291 string_to_sid(&sid_Builtin, "S-1-5-32");
2293 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
2294 MAXIMUM_ALLOWED_ACCESS,
2295 &sid_Builtin, &domain_pol);
2297 if (!NT_STATUS_IS_OK(result)) {
2298 d_printf("Couldn't find group %s\n", argv[0]);
2302 result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol, 1000,
2306 if (!NT_STATUS_IS_OK(result)) {
2307 d_printf("Couldn't find group %s\n", argv[0]);
2312 if (num_rids != 1) {
2313 d_printf("Couldn't find group %s\n", argv[0]);
2317 if (rid_types[0] == SID_NAME_DOM_GRP) {
2318 return rpc_list_group_members(cli, mem_ctx, domain_name,
2319 domain_sid, &domain_pol,
2323 if (rid_types[0] == SID_NAME_ALIAS) {
2324 return rpc_list_alias_members(cli, mem_ctx, &domain_pol,
2328 return NT_STATUS_NO_SUCH_GROUP;
2331 static int rpc_group_members(int argc, const char **argv)
2334 return rpc_group_usage(argc, argv);
2337 return run_rpc_command(NULL, PI_SAMR, 0,
2338 rpc_group_members_internals,
2343 rpc_group_rename_internals(const DOM_SID *domain_sid,
2344 const char *domain_name,
2345 struct cli_state *cli,
2346 TALLOC_CTX *mem_ctx, int argc, const char **argv)
2349 POLICY_HND connect_pol, domain_pol, group_pol;
2350 uint32 num_rids, *rids, *rid_types;
2354 d_printf("Usage: 'net rpc group rename group newname'\n");
2355 return NT_STATUS_UNSUCCESSFUL;
2358 /* Get sam policy handle */
2360 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
2363 if (!NT_STATUS_IS_OK(result))
2366 /* Get domain policy handle */
2368 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
2369 MAXIMUM_ALLOWED_ACCESS,
2370 domain_sid, &domain_pol);
2372 if (!NT_STATUS_IS_OK(result))
2375 result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol, 1000,
2376 1, argv, &num_rids, &rids, &rid_types);
2378 if (num_rids != 1) {
2379 d_printf("Couldn't find group %s\n", argv[0]);
2383 if (rid_types[0] != SID_NAME_DOM_GRP) {
2384 d_printf("Can only rename domain groups\n");
2385 return NT_STATUS_UNSUCCESSFUL;
2388 result = cli_samr_open_group(cli, mem_ctx, &domain_pol,
2389 MAXIMUM_ALLOWED_ACCESS,
2390 rids[0], &group_pol);
2392 if (!NT_STATUS_IS_OK(result))
2397 ctr.switch_value1 = 2;
2398 init_samr_group_info2(&ctr.group.info2, argv[1]);
2400 result = cli_samr_set_groupinfo(cli, mem_ctx, &group_pol, &ctr);
2402 if (!NT_STATUS_IS_OK(result))
2405 return NT_STATUS_NO_SUCH_GROUP;
2408 static int rpc_group_rename(int argc, const char **argv)
2411 return rpc_group_usage(argc, argv);
2414 return run_rpc_command(NULL, PI_SAMR, 0,
2415 rpc_group_rename_internals,
2420 * 'net rpc group' entrypoint.
2421 * @param argc Standard main() style argc
2422 * @param argc Standard main() style argv. Initial components are already
2426 int net_rpc_group(int argc, const char **argv)
2428 struct functable func[] = {
2429 {"add", rpc_group_add},
2430 {"delete", rpc_group_delete},
2431 {"addmem", rpc_group_addmem},
2432 {"delmem", rpc_group_delmem},
2433 {"list", rpc_group_list},
2434 {"members", rpc_group_members},
2435 {"rename", rpc_group_rename},
2440 return run_rpc_command(NULL, PI_SAMR, 0,
2441 rpc_group_list_internals,
2445 return net_run_function(argc, argv, func, rpc_group_usage);
2448 /****************************************************************************/
2450 static int rpc_share_usage(int argc, const char **argv)
2452 return net_help_share(argc, argv);
2456 * Add a share on a remote RPC server
2458 * All parameters are provided by the run_rpc_command function, except for
2459 * argc, argv which are passes through.
2461 * @param domain_sid The domain sid acquired from the remote server
2462 * @param cli A cli_state connected to the server.
2463 * @param mem_ctx Talloc context, destoyed on completion of the function.
2464 * @param argc Standard main() style argc
2465 * @param argv Standard main() style argv. Initial components are already
2468 * @return Normal NTSTATUS return.
2471 rpc_share_add_internals(const DOM_SID *domain_sid, const char *domain_name,
2472 struct cli_state *cli,
2473 TALLOC_CTX *mem_ctx,int argc, const char **argv)
2476 char *sharename=talloc_strdup(mem_ctx, argv[0]);
2478 uint32 type = STYPE_DISKTREE; /* only allow disk shares to be added */
2479 uint32 num_users=0, perms=0;
2480 char *password=NULL; /* don't allow a share password */
2483 path = strchr(sharename, '=');
2485 return NT_STATUS_UNSUCCESSFUL;
2488 result = cli_srvsvc_net_share_add(cli, mem_ctx, sharename, type,
2489 opt_comment, perms, opt_maxusers,
2490 num_users, path, password,
2492 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
2495 static int rpc_share_add(int argc, const char **argv)
2497 if ((argc < 1) || !strchr(argv[0], '=')) {
2498 DEBUG(1,("Sharename or path not specified on add\n"));
2499 return rpc_share_usage(argc, argv);
2501 return run_rpc_command(NULL, PI_SRVSVC, 0,
2502 rpc_share_add_internals,
2507 * Delete a share on a remote RPC server
2509 * All parameters are provided by the run_rpc_command function, except for
2510 * argc, argv which are passes through.
2512 * @param domain_sid The domain sid acquired from the remote server
2513 * @param cli A cli_state connected to the server.
2514 * @param mem_ctx Talloc context, destoyed on completion of the function.
2515 * @param argc Standard main() style argc
2516 * @param argv Standard main() style argv. Initial components are already
2519 * @return Normal NTSTATUS return.
2522 rpc_share_del_internals(const DOM_SID *domain_sid, const char *domain_name,
2523 struct cli_state *cli,
2524 TALLOC_CTX *mem_ctx,int argc, const char **argv)
2528 result = cli_srvsvc_net_share_del(cli, mem_ctx, argv[0]);
2529 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
2533 * Delete a share on a remote RPC server
2535 * @param domain_sid The domain sid acquired from the remote server
2536 * @param argc Standard main() style argc
2537 * @param argv Standard main() style argv. Initial components are already
2540 * @return A shell status integer (0 for success)
2542 static int rpc_share_delete(int argc, const char **argv)
2545 DEBUG(1,("Sharename not specified on delete\n"));
2546 return rpc_share_usage(argc, argv);
2548 return run_rpc_command(NULL, PI_SRVSVC, 0,
2549 rpc_share_del_internals,
2554 * Formatted print of share info
2556 * @param info1 pointer to SRV_SHARE_INFO_1 to format
2559 static void display_share_info_1(SRV_SHARE_INFO_1 *info1)
2561 fstring netname = "", remark = "";
2563 rpcstr_pull_unistr2_fstring(netname, &info1->info_1_str.uni_netname);
2564 rpcstr_pull_unistr2_fstring(remark, &info1->info_1_str.uni_remark);
2566 if (opt_long_list_entries) {
2567 d_printf("%-12s %-8.8s %-50s\n",
2568 netname, share_type[info1->info_1.type], remark);
2570 d_printf("%s\n", netname);
2576 static WERROR get_share_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
2577 uint32 level, int argc, const char **argv,
2578 SRV_SHARE_INFO_CTR *ctr)
2581 SRV_SHARE_INFO info;
2583 /* no specific share requested, enumerate all */
2587 uint32 preferred_len = 0xffffffff;
2589 init_enum_hnd(&hnd, 0);
2591 return cli_srvsvc_net_share_enum(cli, mem_ctx, level, ctr,
2592 preferred_len, &hnd);
2595 /* request just one share */
2596 result = cli_srvsvc_net_share_get_info(cli, mem_ctx, argv[0], level, &info);
2598 if (!W_ERROR_IS_OK(result))
2604 ctr->info_level = ctr->switch_value = level;
2605 ctr->ptr_share_info = ctr->ptr_entries = 1;
2606 ctr->num_entries = ctr->num_entries2 = 1;
2612 SRV_SHARE_INFO_1 *info1;
2614 ctr->share.info1 = TALLOC_ARRAY(mem_ctx, SRV_SHARE_INFO_1, 1);
2615 info1 = ctr->share.info1;
2617 memset(ctr->share.info1, 0, sizeof(SRV_SHARE_INFO_1));
2619 /* Copy pointer crap */
2621 memcpy(&info1->info_1, &info.share.info1.info_1, sizeof(SH_INFO_1));
2623 /* Duplicate strings */
2625 s = unistr2_tdup(mem_ctx, &info.share.info1.info_1_str.uni_netname);
2627 init_unistr2(&info1->info_1_str.uni_netname, s, UNI_STR_TERMINATE);
2629 s = unistr2_tdup(mem_ctx, &info.share.info1.info_1_str.uni_remark);
2631 init_unistr2(&info1->info_1_str.uni_remark, s, UNI_STR_TERMINATE);
2636 SRV_SHARE_INFO_2 *info2;
2638 ctr->share.info2 = TALLOC_ARRAY(mem_ctx, SRV_SHARE_INFO_2, 1);
2639 info2 = ctr->share.info2;
2641 memset(ctr->share.info2, 0, sizeof(SRV_SHARE_INFO_2));
2643 /* Copy pointer crap */
2645 memcpy(&info2->info_2, &info.share.info2.info_2, sizeof(SH_INFO_2));
2647 /* Duplicate strings */
2649 s = unistr2_tdup(mem_ctx, &info.share.info2.info_2_str.uni_netname);
2651 init_unistr2(&info2->info_2_str.uni_netname, s, UNI_STR_TERMINATE);
2653 s = unistr2_tdup(mem_ctx, &info.share.info2.info_2_str.uni_remark);
2655 init_unistr2(&info2->info_2_str.uni_remark, s, UNI_STR_TERMINATE);
2657 s = unistr2_tdup(mem_ctx, &info.share.info2.info_2_str.uni_path);
2659 init_unistr2(&info2->info_2_str.uni_path, s, UNI_STR_TERMINATE);
2661 s = unistr2_tdup(mem_ctx, &info.share.info2.info_2_str.uni_passwd);
2663 init_unistr2(&info2->info_2_str.uni_passwd, s, UNI_STR_TERMINATE);
2668 SRV_SHARE_INFO_502 *info502;
2670 ctr->share.info502 = TALLOC_ARRAY(mem_ctx, SRV_SHARE_INFO_502, 1);
2671 info502 = ctr->share.info502;
2673 memset(ctr->share.info502, 0, sizeof(SRV_SHARE_INFO_502));
2675 /* Copy pointer crap */
2677 memcpy(&info502->info_502, &info.share.info502.info_502, sizeof(SH_INFO_502));
2679 /* Duplicate strings */
2681 s = unistr2_tdup(mem_ctx, &info.share.info502.info_502_str.uni_netname);
2683 init_unistr2(&info502->info_502_str.uni_netname, s, UNI_STR_TERMINATE);
2685 s = unistr2_tdup(mem_ctx, &info.share.info502.info_502_str.uni_remark);
2687 init_unistr2(&info502->info_502_str.uni_remark, s, UNI_STR_TERMINATE);
2689 s = unistr2_tdup(mem_ctx, &info.share.info502.info_502_str.uni_path);
2691 init_unistr2(&info502->info_502_str.uni_path, s, UNI_STR_TERMINATE);
2693 s = unistr2_tdup(mem_ctx, &info.share.info502.info_502_str.uni_passwd);
2695 init_unistr2(&info502->info_502_str.uni_passwd, s, UNI_STR_TERMINATE);
2697 info502->info_502_str.sd = dup_sec_desc(mem_ctx, info.share.info502.info_502_str.sd);
2708 * List shares on a remote RPC server
2710 * All parameters are provided by the run_rpc_command function, except for
2711 * argc, argv which are passes through.
2713 * @param domain_sid The domain sid acquired from the remote server
2714 * @param cli A cli_state connected to the server.
2715 * @param mem_ctx Talloc context, destoyed on completion of the function.
2716 * @param argc Standard main() style argc
2717 * @param argv Standard main() style argv. Initial components are already
2720 * @return Normal NTSTATUS return.
2724 rpc_share_list_internals(const DOM_SID *domain_sid, const char *domain_name,
2725 struct cli_state *cli,
2726 TALLOC_CTX *mem_ctx, int argc, const char **argv)
2728 SRV_SHARE_INFO_CTR ctr;
2730 uint32 i, level = 1;
2732 result = get_share_info(cli, mem_ctx, level, argc, argv, &ctr);
2733 if (!W_ERROR_IS_OK(result))
2736 /* Display results */
2738 if (opt_long_list_entries) {
2740 "\nEnumerating shared resources (exports) on remote server:\n\n"\
2741 "\nShare name Type Description\n"\
2742 "---------- ---- -----------\n");
2744 for (i = 0; i < ctr.num_entries; i++)
2745 display_share_info_1(&ctr.share.info1[i]);
2747 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
2751 * 'net rpc share list' entrypoint.
2752 * @param argc Standard main() style argc
2753 * @param argv Standard main() style argv. Initial components are already
2756 static int rpc_share_list(int argc, const char **argv)
2758 return run_rpc_command(NULL, PI_SRVSVC, 0, rpc_share_list_internals, argc, argv);
2761 static BOOL check_share_availability(struct cli_state *cli, const char *netname)
2763 if (!cli_send_tconX(cli, netname, "A:", "", 0)) {
2764 d_printf("skipping [%s]: not a file share.\n", netname);
2774 static BOOL check_share_sanity(struct cli_state *cli, fstring netname, uint32 type)
2776 /* only support disk shares */
2777 if (! ( type == STYPE_DISKTREE || type == (STYPE_DISKTREE | STYPE_HIDDEN)) ) {
2778 printf("share [%s] is not a diskshare (type: %x)\n", netname, type);
2782 /* skip builtin shares */
2783 /* FIXME: should print$ be added too ? */
2784 if (strequal(netname,"IPC$") || strequal(netname,"ADMIN$") ||
2785 strequal(netname,"global"))
2788 if (opt_exclude && in_list(netname, opt_exclude, False)) {
2789 printf("excluding [%s]\n", netname);
2793 return check_share_availability(cli, netname);
2797 * Migrate shares from a remote RPC server to the local RPC srever
2799 * All parameters are provided by the run_rpc_command function, except for
2800 * argc, argv which are passes through.
2802 * @param domain_sid The domain sid acquired from the remote server
2803 * @param cli A cli_state connected to the server.
2804 * @param mem_ctx Talloc context, destoyed on completion of the function.
2805 * @param argc Standard main() style argc
2806 * @param argv Standard main() style argv. Initial components are already
2809 * @return Normal NTSTATUS return.
2812 rpc_share_migrate_shares_internals(const DOM_SID *domain_sid, const char *domain_name,
2813 struct cli_state *cli, TALLOC_CTX *mem_ctx,
2814 int argc, const char **argv)
2817 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
2818 SRV_SHARE_INFO_CTR ctr_src;
2819 uint32 type = STYPE_DISKTREE; /* only allow disk shares to be added */
2820 char *password = NULL; /* don't allow a share password */
2822 BOOL got_dst_srvsvc_pipe = False;
2823 struct cli_state *cli_dst = NULL;
2824 uint32 level = 502; /* includes secdesc */
2826 result = get_share_info(cli, mem_ctx, level, argc, argv, &ctr_src);
2827 if (!W_ERROR_IS_OK(result))
2830 /* connect destination PI_SRVSVC */
2831 nt_status = connect_dst_pipe(&cli_dst, PI_SRVSVC, &got_dst_srvsvc_pipe);
2832 if (!NT_STATUS_IS_OK(nt_status))
2836 for (i = 0; i < ctr_src.num_entries; i++) {
2838 fstring netname = "", remark = "", path = "";
2839 /* reset error-code */
2840 nt_status = NT_STATUS_UNSUCCESSFUL;
2842 rpcstr_pull_unistr2_fstring(
2843 netname, &ctr_src.share.info502[i].info_502_str.uni_netname);
2844 rpcstr_pull_unistr2_fstring(
2845 remark, &ctr_src.share.info502[i].info_502_str.uni_remark);
2846 rpcstr_pull_unistr2_fstring(
2847 path, &ctr_src.share.info502[i].info_502_str.uni_path);
2849 if (!check_share_sanity(cli, netname, ctr_src.share.info502[i].info_502.type))
2852 /* finally add the share on the dst server */
2854 printf("migrating: [%s], path: %s, comment: %s, without share-ACLs\n",
2855 netname, path, remark);
2857 result = cli_srvsvc_net_share_add(cli_dst, mem_ctx, netname, type, remark,
2858 ctr_src.share.info502[i].info_502.perms,
2859 ctr_src.share.info502[i].info_502.max_uses,
2860 ctr_src.share.info502[i].info_502.num_uses,
2861 path, password, level,
2864 if (W_ERROR_V(result) == W_ERROR_V(WERR_ALREADY_EXISTS)) {
2865 printf(" [%s] does already exist\n", netname);
2869 if (!W_ERROR_IS_OK(result)) {
2870 printf("cannot add share: %s\n", dos_errstr(result));
2876 nt_status = NT_STATUS_OK;
2879 if (got_dst_srvsvc_pipe) {
2880 cli_nt_session_close(cli_dst);
2881 cli_shutdown(cli_dst);
2889 * Migrate shares from a rpc-server to another
2891 * @param argc Standard main() style argc
2892 * @param argv Standard main() style argv. Initial components are already
2895 * @return A shell status integer (0 for success)
2897 static int rpc_share_migrate_shares(int argc, const char **argv)
2901 printf("no server to migrate\n");
2905 return run_rpc_command(NULL, PI_SRVSVC, 0,
2906 rpc_share_migrate_shares_internals,
2913 * @param f file_info
2914 * @param mask current search mask
2915 * @param state arg-pointer
2918 static void copy_fn(const char *mnt, file_info *f, const char *mask, void *state)
2920 static NTSTATUS nt_status;
2921 static struct copy_clistate *local_state;
2922 static fstring filename, new_mask;
2926 local_state = (struct copy_clistate *)state;
2927 nt_status = NT_STATUS_UNSUCCESSFUL;
2929 if (strequal(f->name, ".") || strequal(f->name, ".."))
2932 DEBUG(3,("got mask: %s, name: %s\n", mask, f->name));
2935 if (f->mode & aDIR) {
2937 DEBUG(3,("got dir: %s\n", f->name));
2939 fstrcpy(dir, local_state->cwd);
2941 fstrcat(dir, f->name);
2943 switch (net_mode_share)
2945 case NET_MODE_SHARE_MIGRATE:
2946 /* create that directory */
2947 nt_status = net_copy_file(local_state->mem_ctx,
2948 local_state->cli_share_src,
2949 local_state->cli_share_dst,
2951 opt_acls? True : False,
2952 opt_attrs? True : False,
2953 opt_timestamps? True : False,
2957 d_printf("Unsupported mode %d\n", net_mode_share);
2961 if (!NT_STATUS_IS_OK(nt_status))
2962 printf("could not handle dir %s: %s\n",
2963 dir, nt_errstr(nt_status));
2965 /* search below that directory */
2966 fstrcpy(new_mask, dir);
2967 fstrcat(new_mask, "\\*");
2969 old_dir = local_state->cwd;
2970 local_state->cwd = dir;
2971 if (!sync_files(local_state, new_mask))
2972 printf("could not handle files\n");
2973 local_state->cwd = old_dir;
2980 fstrcpy(filename, local_state->cwd);
2981 fstrcat(filename, "\\");
2982 fstrcat(filename, f->name);
2984 DEBUG(3,("got file: %s\n", filename));
2986 switch (net_mode_share)
2988 case NET_MODE_SHARE_MIGRATE:
2989 nt_status = net_copy_file(local_state->mem_ctx,
2990 local_state->cli_share_src,
2991 local_state->cli_share_dst,
2993 opt_acls? True : False,
2994 opt_attrs? True : False,
2995 opt_timestamps? True: False,
2999 d_printf("Unsupported file mode %d\n", net_mode_share);
3003 if (!NT_STATUS_IS_OK(nt_status))
3004 printf("could not handle file %s: %s\n",
3005 filename, nt_errstr(nt_status));
3010 * sync files, can be called recursivly to list files
3011 * and then call copy_fn for each file
3013 * @param cp_clistate pointer to the copy_clistate we work with
3014 * @param mask the current search mask
3016 * @return Boolean result
3018 BOOL sync_files(struct copy_clistate *cp_clistate, pstring mask)
3021 DEBUG(3,("calling cli_list with mask: %s\n", mask));
3023 if (cli_list(cp_clistate->cli_share_src, mask, cp_clistate->attribute, copy_fn, cp_clistate) == -1) {
3024 d_printf("listing %s failed with error: %s\n",
3025 mask, cli_errstr(cp_clistate->cli_share_src));
3034 * Set the top level directory permissions before we do any further copies.
3035 * Should set up ACL inheritance.
3038 BOOL copy_top_level_perms(struct copy_clistate *cp_clistate,
3039 const char *sharename)
3043 switch (net_mode_share) {
3044 case NET_MODE_SHARE_MIGRATE:
3045 DEBUG(3,("calling net_copy_fileattr for '.' directory in share %s\n", sharename));
3046 nt_status = net_copy_fileattr(cp_clistate->mem_ctx,
3047 cp_clistate->cli_share_src,
3048 cp_clistate->cli_share_dst,
3050 opt_acls? True : False,
3051 opt_attrs? True : False,
3052 opt_timestamps? True: False,
3056 d_printf("Unsupported mode %d\n", net_mode_share);
3060 if (!NT_STATUS_IS_OK(nt_status)) {
3061 printf("Could handle directory attributes for top level directory of share %s. Error %s\n",
3062 sharename, nt_errstr(nt_status));
3071 * Sync all files inside a remote share to another share (over smb)
3073 * All parameters are provided by the run_rpc_command function, except for
3074 * argc, argv which are passes through.
3076 * @param domain_sid The domain sid acquired from the remote server
3077 * @param cli A cli_state connected to the server.
3078 * @param mem_ctx Talloc context, destoyed on completion of the function.
3079 * @param argc Standard main() style argc
3080 * @param argv Standard main() style argv. Initial components are already
3083 * @return Normal NTSTATUS return.
3086 rpc_share_migrate_files_internals(const DOM_SID *domain_sid, const char *domain_name,
3087 struct cli_state *cli, TALLOC_CTX *mem_ctx,
3088 int argc, const char **argv)
3091 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
3092 SRV_SHARE_INFO_CTR ctr_src;
3095 struct copy_clistate cp_clistate;
3096 BOOL got_src_share = False;
3097 BOOL got_dst_share = False;
3098 pstring mask = "\\*";
3101 dst = SMB_STRDUP(opt_destination?opt_destination:"127.0.0.1");
3103 result = get_share_info(cli, mem_ctx, level, argc, argv, &ctr_src);
3105 if (!W_ERROR_IS_OK(result))
3108 for (i = 0; i < ctr_src.num_entries; i++) {
3110 fstring netname = "";
3112 rpcstr_pull_unistr2_fstring(
3113 netname, &ctr_src.share.info502[i].info_502_str.uni_netname);
3115 if (!check_share_sanity(cli, netname, ctr_src.share.info502[i].info_502.type))
3118 /* one might not want to mirror whole discs :) */
3119 if (strequal(netname, "print$") || netname[1] == '$') {
3120 d_printf("skipping [%s]: builtin/hidden share\n", netname);
3124 switch (net_mode_share)
3126 case NET_MODE_SHARE_MIGRATE:
3130 d_printf("Unsupported mode %d\n", net_mode_share);
3133 printf(" [%s] files and directories %s ACLs, %s DOS Attributes %s\n",
3135 opt_acls ? "including" : "without",
3136 opt_attrs ? "including" : "without",
3137 opt_timestamps ? "(preserving timestamps)" : "");
3139 cp_clistate.mem_ctx = mem_ctx;
3140 cp_clistate.cli_share_src = NULL;
3141 cp_clistate.cli_share_dst = NULL;
3142 cp_clistate.cwd = NULL;
3143 cp_clistate.attribute = aSYSTEM | aHIDDEN | aDIR;
3145 /* open share source */
3146 nt_status = connect_to_service(&cp_clistate.cli_share_src,
3147 &cli->dest_ip, cli->desthost,
3149 if (!NT_STATUS_IS_OK(nt_status))
3152 got_src_share = True;
3154 if (net_mode_share == NET_MODE_SHARE_MIGRATE) {
3155 /* open share destination */
3156 nt_status = connect_to_service(&cp_clistate.cli_share_dst,
3157 NULL, dst, netname, "A:");
3158 if (!NT_STATUS_IS_OK(nt_status))
3161 got_dst_share = True;
3164 if (!copy_top_level_perms(&cp_clistate, netname)) {
3165 d_printf("Could not handle the top level directory permissions for the share: %s\n", netname);
3166 nt_status = NT_STATUS_UNSUCCESSFUL;
3170 if (!sync_files(&cp_clistate, mask)) {
3171 d_printf("could not handle files for share: %s\n", netname);
3172 nt_status = NT_STATUS_UNSUCCESSFUL;
3177 nt_status = NT_STATUS_OK;
3182 cli_shutdown(cp_clistate.cli_share_src);
3185 cli_shutdown(cp_clistate.cli_share_dst);
3191 static int rpc_share_migrate_files(int argc, const char **argv)
3195 printf("no server to migrate\n");
3199 return run_rpc_command(NULL, PI_SRVSVC, 0,
3200 rpc_share_migrate_files_internals,
3205 * Migrate share-ACLs from a remote RPC server to the local RPC srever
3207 * All parameters are provided by the run_rpc_command function, except for
3208 * argc, argv which are passes through.
3210 * @param domain_sid The domain sid acquired from the remote server
3211 * @param cli A cli_state connected to the server.
3212 * @param mem_ctx Talloc context, destoyed on completion of the function.
3213 * @param argc Standard main() style argc
3214 * @param argv Standard main() style argv. Initial components are already
3217 * @return Normal NTSTATUS return.
3220 rpc_share_migrate_security_internals(const DOM_SID *domain_sid, const char *domain_name,
3221 struct cli_state *cli, TALLOC_CTX *mem_ctx,
3222 int argc, const char **argv)
3225 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
3226 SRV_SHARE_INFO_CTR ctr_src;
3227 SRV_SHARE_INFO info;
3229 BOOL got_dst_srvsvc_pipe = False;
3230 struct cli_state *cli_dst = NULL;
3231 uint32 level = 502; /* includes secdesc */
3233 result = get_share_info(cli, mem_ctx, level, argc, argv, &ctr_src);
3235 if (!W_ERROR_IS_OK(result))
3238 /* connect destination PI_SRVSVC */
3239 nt_status = connect_dst_pipe(&cli_dst, PI_SRVSVC, &got_dst_srvsvc_pipe);
3240 if (!NT_STATUS_IS_OK(nt_status))
3244 for (i = 0; i < ctr_src.num_entries; i++) {
3246 fstring netname = "", remark = "", path = "";
3247 /* reset error-code */
3248 nt_status = NT_STATUS_UNSUCCESSFUL;
3250 rpcstr_pull_unistr2_fstring(
3251 netname, &ctr_src.share.info502[i].info_502_str.uni_netname);
3252 rpcstr_pull_unistr2_fstring(
3253 remark, &ctr_src.share.info502[i].info_502_str.uni_remark);
3254 rpcstr_pull_unistr2_fstring(
3255 path, &ctr_src.share.info502[i].info_502_str.uni_path);
3257 if (!check_share_sanity(cli, netname, ctr_src.share.info502[i].info_502.type))
3260 printf("migrating: [%s], path: %s, comment: %s, including share-ACLs\n",
3261 netname, path, remark);
3264 display_sec_desc(ctr_src.share.info502[i].info_502_str.sd);
3269 info.switch_value = level;
3270 info.ptr_share_ctr = 1;
3272 /* FIXME: shouldn't we be able to just set the security descriptor ? */
3273 info.share.info502 = ctr_src.share.info502[i];
3275 /* finally modify the share on the dst server */
3276 result = cli_srvsvc_net_share_set_info(cli_dst, mem_ctx, netname, level, &info);
3278 if (!W_ERROR_IS_OK(result)) {
3279 printf("cannot set share-acl: %s\n", dos_errstr(result));
3285 nt_status = NT_STATUS_OK;
3288 if (got_dst_srvsvc_pipe) {
3289 cli_nt_session_close(cli_dst);
3290 cli_shutdown(cli_dst);
3298 * Migrate share-acls from a rpc-server to another
3300 * @param argc Standard main() style argc
3301 * @param argv Standard main() style argv. Initial components are already
3304 * @return A shell status integer (0 for success)
3306 static int rpc_share_migrate_security(int argc, const char **argv)
3310 printf("no server to migrate\n");
3314 return run_rpc_command(NULL, PI_SRVSVC, 0,
3315 rpc_share_migrate_security_internals,
3320 * Migrate shares (including share-definitions, share-acls and files with acls/attrs)
3321 * from one server to another
3323 * @param argc Standard main() style argc
3324 * @param argv Standard main() style argv. Initial components are already
3327 * @return A shell status integer (0 for success)
3330 static int rpc_share_migrate_all(int argc, const char **argv)
3335 printf("no server to migrate\n");
3339 /* order is important. we don't want to be locked out by the share-acl
3340 * before copying files - gd */
3342 ret = run_rpc_command(NULL, PI_SRVSVC, 0, rpc_share_migrate_shares_internals, argc, argv);
3346 ret = run_rpc_command(NULL, PI_SRVSVC, 0, rpc_share_migrate_files_internals, argc, argv);
3350 return run_rpc_command(NULL, PI_SRVSVC, 0, rpc_share_migrate_security_internals, argc, argv);
3355 * 'net rpc share migrate' entrypoint.
3356 * @param argc Standard main() style argc
3357 * @param argv Standard main() style argv. Initial components are already
3360 static int rpc_share_migrate(int argc, const char **argv)
3363 struct functable func[] = {
3364 {"all", rpc_share_migrate_all},
3365 {"files", rpc_share_migrate_files},
3366 {"help", rpc_share_usage},
3367 {"security", rpc_share_migrate_security},
3368 {"shares", rpc_share_migrate_shares},
3372 net_mode_share = NET_MODE_SHARE_MIGRATE;
3374 return net_run_function(argc, argv, func, rpc_share_usage);
3383 static int num_server_aliases;
3384 static struct full_alias *server_aliases;
3387 * Add an alias to the static list.
3389 static void push_alias(TALLOC_CTX *mem_ctx, struct full_alias *alias)
3391 if (server_aliases == NULL)
3392 server_aliases = SMB_MALLOC_ARRAY(struct full_alias, 100);
3394 server_aliases[num_server_aliases] = *alias;
3395 num_server_aliases += 1;
3399 * For a specific domain on the server, fetch all the aliases
3400 * and their members. Add all of them to the server_aliases.
3403 rpc_fetch_domain_aliases(struct cli_state *cli, TALLOC_CTX *mem_ctx,
3404 POLICY_HND *connect_pol,
3405 const DOM_SID *domain_sid)
3407 uint32 start_idx, max_entries, num_entries, i;
3408 struct acct_info *groups;
3410 POLICY_HND domain_pol;
3412 /* Get domain policy handle */
3414 result = cli_samr_open_domain(cli, mem_ctx, connect_pol,
3415 MAXIMUM_ALLOWED_ACCESS,
3416 domain_sid, &domain_pol);
3417 if (!NT_STATUS_IS_OK(result))
3424 result = cli_samr_enum_als_groups(cli, mem_ctx, &domain_pol,
3425 &start_idx, max_entries,
3426 &groups, &num_entries);
3428 for (i = 0; i < num_entries; i++) {
3430 POLICY_HND alias_pol;
3431 struct full_alias alias;
3435 result = cli_samr_open_alias(cli, mem_ctx, &domain_pol,
3436 MAXIMUM_ALLOWED_ACCESS,
3439 if (!NT_STATUS_IS_OK(result))
3442 result = cli_samr_query_aliasmem(cli, mem_ctx,
3446 if (!NT_STATUS_IS_OK(result))
3449 result = cli_samr_close(cli, mem_ctx, &alias_pol);
3450 if (!NT_STATUS_IS_OK(result))
3453 alias.members = NULL;
3455 if (alias.num_members > 0) {
3456 alias.members = SMB_MALLOC_ARRAY(DOM_SID, alias.num_members);
3458 for (j = 0; j < alias.num_members; j++)
3459 sid_copy(&alias.members[j],
3463 sid_copy(&alias.sid, domain_sid);
3464 sid_append_rid(&alias.sid, groups[i].rid);
3466 push_alias(mem_ctx, &alias);
3468 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
3470 result = NT_STATUS_OK;
3473 cli_samr_close(cli, mem_ctx, &domain_pol);
3479 * Dump server_aliases as names for debugging purposes.
3482 rpc_aliaslist_dump(const DOM_SID *domain_sid, const char *domain_name,
3483 struct cli_state *cli, TALLOC_CTX *mem_ctx,
3484 int argc, const char **argv)
3490 result = cli_lsa_open_policy(cli, mem_ctx, True,
3491 SEC_RIGHTS_MAXIMUM_ALLOWED,
3493 if (!NT_STATUS_IS_OK(result))
3496 for (i=0; i<num_server_aliases; i++) {
3502 struct full_alias *alias = &server_aliases[i];
3504 result = cli_lsa_lookup_sids(cli, mem_ctx, &lsa_pol, 1,
3506 &domains, &names, &types);
3507 if (!NT_STATUS_IS_OK(result))
3510 DEBUG(1, ("%s\\%s %d: ", domains[0], names[0], types[0]));
3512 if (alias->num_members == 0) {
3517 result = cli_lsa_lookup_sids(cli, mem_ctx, &lsa_pol,
3520 &domains, &names, &types);
3522 if (!NT_STATUS_IS_OK(result) &&
3523 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
3526 for (j=0; j<alias->num_members; j++)
3527 DEBUG(1, ("%s\\%s (%d); ",
3528 domains[j] ? domains[j] : "*unknown*",
3529 names[j] ? names[j] : "*unknown*",types[j]));
3533 cli_lsa_close(cli, mem_ctx, &lsa_pol);
3535 return NT_STATUS_OK;
3539 * Fetch a list of all server aliases and their members into
3543 rpc_aliaslist_internals(const DOM_SID *domain_sid, const char *domain_name,
3544 struct cli_state *cli, TALLOC_CTX *mem_ctx,
3545 int argc, const char **argv)
3548 POLICY_HND connect_pol;
3550 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
3553 if (!NT_STATUS_IS_OK(result))
3556 result = rpc_fetch_domain_aliases(cli, mem_ctx, &connect_pol,
3557 &global_sid_Builtin);
3559 if (!NT_STATUS_IS_OK(result))
3562 result = rpc_fetch_domain_aliases(cli, mem_ctx, &connect_pol,
3565 cli_samr_close(cli, mem_ctx, &connect_pol);
3570 static void init_user_token(NT_USER_TOKEN *token, DOM_SID *user_sid)
3572 token->num_sids = 4;
3574 token->user_sids = SMB_MALLOC_ARRAY(DOM_SID, 4);
3576 token->user_sids[0] = *user_sid;
3577 sid_copy(&token->user_sids[1], &global_sid_World);
3578 sid_copy(&token->user_sids[2], &global_sid_Network);
3579 sid_copy(&token->user_sids[3], &global_sid_Authenticated_Users);
3582 static void free_user_token(NT_USER_TOKEN *token)
3584 SAFE_FREE(token->user_sids);
3587 static BOOL is_sid_in_token(NT_USER_TOKEN *token, DOM_SID *sid)
3591 for (i=0; i<token->num_sids; i++) {
3592 if (sid_compare(sid, &token->user_sids[i]) == 0)
3598 static void add_sid_to_token(NT_USER_TOKEN *token, DOM_SID *sid)
3600 if (is_sid_in_token(token, sid))
3603 token->user_sids = SMB_REALLOC_ARRAY(token->user_sids, DOM_SID, token->num_sids+1);
3605 sid_copy(&token->user_sids[token->num_sids], sid);
3607 token->num_sids += 1;
3612 NT_USER_TOKEN token;
3615 static void dump_user_token(struct user_token *token)
3619 d_printf("%s\n", token->name);
3621 for (i=0; i<token->token.num_sids; i++) {
3622 d_printf(" %s\n", sid_string_static(&token->token.user_sids[i]));
3626 static BOOL is_alias_member(DOM_SID *sid, struct full_alias *alias)
3630 for (i=0; i<alias->num_members; i++) {
3631 if (sid_compare(sid, &alias->members[i]) == 0)
3638 static void collect_sid_memberships(NT_USER_TOKEN *token, DOM_SID sid)
3642 for (i=0; i<num_server_aliases; i++) {
3643 if (is_alias_member(&sid, &server_aliases[i]))
3644 add_sid_to_token(token, &server_aliases[i].sid);
3649 * We got a user token with all the SIDs we can know about without asking the
3650 * server directly. These are the user and domain group sids. All of these can
3651 * be members of aliases. So scan the list of aliases for each of the SIDs and
3652 * add them to the token.
3655 static void collect_alias_memberships(NT_USER_TOKEN *token)
3657 int num_global_sids = token->num_sids;
3660 for (i=0; i<num_global_sids; i++) {
3661 collect_sid_memberships(token, token->user_sids[i]);
3665 static BOOL get_user_sids(const char *domain, const char *user,
3666 NT_USER_TOKEN *token)
3668 struct winbindd_request request;
3669 struct winbindd_response response;
3677 fstr_sprintf(full_name, "%s%c%s",
3678 domain, *lp_winbind_separator(), user);
3680 /* First let's find out the user sid */
3682 ZERO_STRUCT(request);
3683 ZERO_STRUCT(response);
3685 fstrcpy(request.data.name.dom_name, domain);
3686 fstrcpy(request.data.name.name, user);
3688 result = winbindd_request_response(WINBINDD_LOOKUPNAME, &request, &response);
3690 if (result != NSS_STATUS_SUCCESS) {
3691 DEBUG(1, ("winbind could not find %s\n", full_name));
3695 if (response.data.sid.type != SID_NAME_USER) {
3696 DEBUG(1, ("%s is not a user\n", full_name));
3700 string_to_sid(&user_sid, response.data.sid.sid);
3702 init_user_token(token, &user_sid);
3704 /* And now the groups winbind knows about */
3706 ZERO_STRUCT(response);
3708 fstrcpy(request.data.username, full_name);
3710 result = winbindd_request_response(WINBINDD_GETGROUPS, &request, &response);
3712 if (result != NSS_STATUS_SUCCESS) {
3713 DEBUG(1, ("winbind could not get groups of %s\n", full_name));
3717 for (i = 0; i < response.data.num_entries; i++) {
3718 gid_t gid = ((gid_t *)response.extra_data)[i];
3721 struct winbindd_request sidrequest;
3722 struct winbindd_response sidresponse;
3724 ZERO_STRUCT(sidrequest);
3725 ZERO_STRUCT(sidresponse);
3727 sidrequest.data.gid = gid;
3729 result = winbindd_request_response(WINBINDD_GID_TO_SID,
3730 &sidrequest, &sidresponse);
3732 if (result != NSS_STATUS_SUCCESS) {
3733 DEBUG(1, ("winbind could not find SID of gid %d\n",
3738 DEBUG(3, (" %s\n", sidresponse.data.sid.sid));
3740 string_to_sid(&sid, sidresponse.data.sid.sid);
3741 add_sid_to_token(token, &sid);
3744 SAFE_FREE(response.extra_data);
3750 * Get a list of all user tokens we want to look at
3752 static BOOL get_user_tokens(int *num_tokens, struct user_token **user_tokens)
3754 struct winbindd_request request;
3755 struct winbindd_response response;
3756 const char *extra_data;
3759 struct user_token *result;
3761 if (lp_winbind_use_default_domain() &&
3762 (opt_target_workgroup == NULL)) {
3763 d_printf("winbind use default domain = yes set, please "
3764 "specify a workgroup\n");
3768 /* Send request to winbind daemon */
3770 ZERO_STRUCT(request);
3771 ZERO_STRUCT(response);
3773 if (winbindd_request_response(WINBINDD_LIST_USERS, &request, &response) !=
3777 /* Look through extra data */
3779 if (!response.extra_data)
3782 extra_data = (const char *)response.extra_data;
3785 while(next_token(&extra_data, name, ",", sizeof(fstring))) {
3789 result = SMB_MALLOC_ARRAY(struct user_token, *num_tokens);
3791 if (result == NULL) {
3792 DEBUG(1, ("Could not malloc sid array\n"));
3796 extra_data = (const char *)response.extra_data;
3799 while(next_token(&extra_data, name, ",", sizeof(fstring))) {
3801 fstring domain, user;
3804 fstrcpy(result[i].name, name);
3806 p = strchr(name, *lp_winbind_separator());
3808 DEBUG(3, ("%s\n", name));
3811 fstrcpy(domain, opt_target_workgroup);
3812 fstrcpy(user, name);
3815 fstrcpy(domain, name);
3820 get_user_sids(domain, user, &(result[i].token));
3824 SAFE_FREE(response.extra_data);
3826 *user_tokens = result;
3831 static BOOL get_user_tokens_from_file(FILE *f,
3833 struct user_token **tokens)
3835 struct user_token *token = NULL;
3840 if (fgets(line, sizeof(line)-1, f) == NULL) {
3844 if (line[strlen(line)-1] == '\n')
3845 line[strlen(line)-1] = '\0';
3847 if (line[0] == ' ') {
3851 string_to_sid(&sid, &line[1]);
3853 if (token == NULL) {
3854 DEBUG(0, ("File does not begin with username"));
3858 add_sid_to_token(&token->token, &sid);
3862 /* And a new user... */
3865 *tokens = SMB_REALLOC_ARRAY(*tokens, struct user_token, *num_tokens);
3866 if (*tokens == NULL) {
3867 DEBUG(0, ("Could not realloc tokens\n"));
3871 token = &((*tokens)[*num_tokens-1]);
3873 fstrcpy(token->name, line);
3874 token->token.num_sids = 0;
3875 token->token.user_sids = NULL;
3884 * Show the list of all users that have access to a share
3887 static void show_userlist(struct cli_state *cli,
3888 TALLOC_CTX *mem_ctx, const char *netname,
3889 int num_tokens, struct user_token *tokens)
3892 SEC_DESC *share_sd = NULL;
3893 SEC_DESC *root_sd = NULL;
3895 SRV_SHARE_INFO info;
3899 result = cli_srvsvc_net_share_get_info(cli, mem_ctx, netname,
3902 if (!W_ERROR_IS_OK(result)) {
3903 DEBUG(1, ("Coult not query secdesc for share %s\n",
3908 share_sd = info.share.info502.info_502_str.sd;
3909 if (share_sd == NULL) {
3910 DEBUG(1, ("Got no secdesc for share %s\n",
3916 if (!cli_send_tconX(cli, netname, "A:", "", 0)) {
3920 fnum = cli_nt_create(cli, "\\", READ_CONTROL_ACCESS);
3923 root_sd = cli_query_secdesc(cli, fnum, mem_ctx);
3926 for (i=0; i<num_tokens; i++) {
3930 if (share_sd != NULL) {
3931 if (!se_access_check(share_sd, &tokens[i].token,
3932 1, &acc_granted, &status)) {
3933 DEBUG(1, ("Could not check share_sd for "
3939 if (!NT_STATUS_IS_OK(status))
3943 if (root_sd == NULL) {
3944 d_printf(" %s\n", tokens[i].name);
3948 if (!se_access_check(root_sd, &tokens[i].token,
3949 1, &acc_granted, &status)) {
3950 DEBUG(1, ("Could not check root_sd for user %s\n",
3955 if (!NT_STATUS_IS_OK(status))
3958 d_printf(" %s\n", tokens[i].name);
3962 cli_close(cli, fnum);
3974 static void collect_share(const char *name, uint32 m,
3975 const char *comment, void *state)
3977 struct share_list *share_list = (struct share_list *)state;
3979 if (m != STYPE_DISKTREE)
3982 share_list->num_shares += 1;
3983 share_list->shares = SMB_REALLOC_ARRAY(share_list->shares, char *, share_list->num_shares);
3984 share_list->shares[share_list->num_shares-1] = SMB_STRDUP(name);
3987 static void rpc_share_userlist_usage(void)
3993 * List shares on a remote RPC server, including the security descriptors
3995 * All parameters are provided by the run_rpc_command function, except for
3996 * argc, argv which are passes through.
3998 * @param domain_sid The domain sid acquired from the remote server
3999 * @param cli A cli_state connected to the server.
4000 * @param mem_ctx Talloc context, destoyed on completion of the function.
4001 * @param argc Standard main() style argc
4002 * @param argv Standard main() style argv. Initial components are already
4005 * @return Normal NTSTATUS return.
4009 rpc_share_allowedusers_internals(const DOM_SID *domain_sid,
4010 const char *domain_name,
4011 struct cli_state *cli,
4012 TALLOC_CTX *mem_ctx,
4013 int argc, const char **argv)
4021 struct user_token *tokens = NULL;
4024 struct share_list share_list;
4027 rpc_share_userlist_usage();
4028 return NT_STATUS_UNSUCCESSFUL;
4034 f = fopen(argv[0], "r");
4038 DEBUG(0, ("Could not open userlist: %s\n", strerror(errno)));
4039 return NT_STATUS_UNSUCCESSFUL;
4042 r = get_user_tokens_from_file(f, &num_tokens, &tokens);
4048 DEBUG(0, ("Could not read users from file\n"));
4049 return NT_STATUS_UNSUCCESSFUL;
4052 for (i=0; i<num_tokens; i++)
4053 collect_alias_memberships(&tokens[i].token);
4055 init_enum_hnd(&hnd, 0);
4057 share_list.num_shares = 0;
4058 share_list.shares = NULL;
4060 ret = cli_RNetShareEnum(cli, collect_share, &share_list);
4063 DEBUG(0, ("Error returning browse list: %s\n",
4068 for (i = 0; i < share_list.num_shares; i++) {
4069 char *netname = share_list.shares[i];
4071 if (netname[strlen(netname)-1] == '$')
4074 d_printf("%s\n", netname);
4076 show_userlist(cli, mem_ctx, netname,
4077 num_tokens, tokens);
4080 for (i=0; i<num_tokens; i++) {
4081 free_user_token(&tokens[i].token);
4084 SAFE_FREE(share_list.shares);
4086 return NT_STATUS_OK;
4090 rpc_share_allowedusers(int argc, const char **argv)
4094 result = run_rpc_command(NULL, PI_SAMR, 0,
4095 rpc_aliaslist_internals,
4100 result = run_rpc_command(NULL, PI_LSARPC, 0,
4106 return run_rpc_command(NULL, PI_SRVSVC, 0,
4107 rpc_share_allowedusers_internals,
4111 int net_usersidlist(int argc, const char **argv)
4114 struct user_token *tokens = NULL;
4118 net_usersidlist_usage(argc, argv);
4122 if (!get_user_tokens(&num_tokens, &tokens)) {
4123 DEBUG(0, ("Could not get the user/sid list\n"));
4127 for (i=0; i<num_tokens; i++) {
4128 dump_user_token(&tokens[i]);
4129 free_user_token(&tokens[i].token);
4136 int net_usersidlist_usage(int argc, const char **argv)
4138 d_printf("net usersidlist\n"
4139 "\tprints out a list of all users the running winbind knows\n"
4140 "\tabout, together with all their SIDs. This is used as\n"
4141 "\tinput to the 'net rpc share allowedusers' command.\n\n");
4143 net_common_flags_usage(argc, argv);
4148 * 'net rpc share' entrypoint.
4149 * @param argc Standard main() style argc
4150 * @param argv Standard main() style argv. Initial components are already
4154 int net_rpc_share(int argc, const char **argv)
4156 struct functable func[] = {
4157 {"add", rpc_share_add},
4158 {"delete", rpc_share_delete},
4159 {"allowedusers", rpc_share_allowedusers},
4160 {"migrate", rpc_share_migrate},
4161 {"list", rpc_share_list},
4166 return run_rpc_command(NULL, PI_SRVSVC, 0,
4167 rpc_share_list_internals,
4170 return net_run_function(argc, argv, func, rpc_share_usage);
4173 /****************************************************************************/
4175 static int rpc_file_usage(int argc, const char **argv)
4177 return net_help_file(argc, argv);
4181 * Close a file on a remote RPC server
4183 * All parameters are provided by the run_rpc_command function, except for
4184 * argc, argv which are passes through.
4186 * @param domain_sid The domain sid acquired from the remote server
4187 * @param cli A cli_state connected to the server.
4188 * @param mem_ctx Talloc context, destoyed on completion of the function.
4189 * @param argc Standard main() style argc
4190 * @param argv Standard main() style argv. Initial components are already
4193 * @return Normal NTSTATUS return.
4196 rpc_file_close_internals(const DOM_SID *domain_sid, const char *domain_name,
4197 struct cli_state *cli,
4198 TALLOC_CTX *mem_ctx, int argc, const char **argv)
4201 result = cli_srvsvc_net_file_close(cli, mem_ctx, atoi(argv[0]));
4202 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
4206 * Close a file on a remote RPC server
4208 * @param argc Standard main() style argc
4209 * @param argv Standard main() style argv. Initial components are already
4212 * @return A shell status integer (0 for success)
4214 static int rpc_file_close(int argc, const char **argv)
4217 DEBUG(1, ("No fileid given on close\n"));
4218 return(rpc_file_usage(argc, argv));
4221 return run_rpc_command(NULL, PI_SRVSVC, 0,
4222 rpc_file_close_internals,
4227 * Formatted print of open file info
4229 * @param info3 FILE_INFO_3 contents
4230 * @param str3 strings for FILE_INFO_3
4233 static void display_file_info_3(FILE_INFO_3 *info3, FILE_INFO_3_STR *str3)
4235 fstring user = "", path = "";
4237 rpcstr_pull_unistr2_fstring(user, &str3->uni_user_name);
4238 rpcstr_pull_unistr2_fstring(path, &str3->uni_path_name);
4240 d_printf("%-7.1d %-20.20s 0x%-4.2x %-6.1d %s\n",
4241 info3->id, user, info3->perms, info3->num_locks, path);
4245 * List open files on a remote RPC server
4247 * All parameters are provided by the run_rpc_command function, except for
4248 * argc, argv which are passes through.
4250 * @param domain_sid The domain sid acquired from the remote server
4251 * @param cli A cli_state connected to the server.
4252 * @param mem_ctx Talloc context, destoyed on completion of the function.
4253 * @param argc Standard main() style argc
4254 * @param argv Standard main() style argv. Initial components are already
4257 * @return Normal NTSTATUS return.
4261 rpc_file_list_internals(const DOM_SID *domain_sid, const char *domain_name,
4262 struct cli_state *cli,
4263 TALLOC_CTX *mem_ctx, int argc, const char **argv)
4265 SRV_FILE_INFO_CTR ctr;
4268 uint32 preferred_len = 0xffffffff, i;
4269 const char *username=NULL;
4271 init_enum_hnd(&hnd, 0);
4273 /* if argc > 0, must be user command */
4275 username = smb_xstrdup(argv[0]);
4277 result = cli_srvsvc_net_file_enum(
4278 cli, mem_ctx, 3, username, &ctr, preferred_len, &hnd);
4280 if (!W_ERROR_IS_OK(result))
4283 /* Display results */
4286 "\nEnumerating open files on remote server:\n\n"\
4287 "\nFileId Opened by Perms Locks Path"\
4288 "\n------ --------- ----- ----- ---- \n");
4289 for (i = 0; i < ctr.num_entries; i++)
4290 display_file_info_3(&ctr.file.info3[i].info_3,
4291 &ctr.file.info3[i].info_3_str);
4293 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
4298 * List files for a user on a remote RPC server
4300 * @param argc Standard main() style argc
4301 * @param argv Standard main() style argv. Initial components are already
4304 * @return A shell status integer (0 for success)
4306 static int rpc_file_user(int argc, const char **argv)
4309 DEBUG(1, ("No username given\n"));
4310 return(rpc_file_usage(argc, argv));
4313 return run_rpc_command(NULL, PI_SRVSVC, 0,
4314 rpc_file_list_internals,
4320 * 'net rpc file' entrypoint.
4321 * @param argc Standard main() style argc
4322 * @param argv Standard main() style argv. Initial components are already
4326 int net_rpc_file(int argc, const char **argv)
4328 struct functable func[] = {
4329 {"close", rpc_file_close},
4330 {"user", rpc_file_user},
4332 {"info", rpc_file_info},
4338 return run_rpc_command(NULL, PI_SRVSVC, 0,
4339 rpc_file_list_internals,
4342 return net_run_function(argc, argv, func, rpc_file_usage);
4345 /****************************************************************************/
4350 * ABORT the shutdown of a remote RPC Server over, initshutdown pipe
4352 * All parameters are provided by the run_rpc_command function, except for
4353 * argc, argv which are passed through.
4355 * @param domain_sid The domain sid aquired from the remote server
4356 * @param cli A cli_state connected to the server.
4357 * @param mem_ctx Talloc context, destoyed on compleation of the function.
4358 * @param argc Standard main() style argc
4359 * @param argv Standard main() style argv. Initial components are already
4362 * @return Normal NTSTATUS return.
4365 static NTSTATUS rpc_shutdown_abort_internals(const DOM_SID *domain_sid,
4366 const char *domain_name,
4367 struct cli_state *cli,
4368 TALLOC_CTX *mem_ctx,
4369 int argc, const char **argv)
4371 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
4373 result = cli_shutdown_abort(cli, mem_ctx);
4375 if (NT_STATUS_IS_OK(result)) {
4376 d_printf("\nShutdown successfully aborted\n");
4377 DEBUG(5,("cmd_shutdown_abort: query succeeded\n"));
4379 DEBUG(5,("cmd_shutdown_abort: query failed\n"));
4386 * ABORT the shutdown of a remote RPC Server, over winreg pipe
4388 * All parameters are provided by the run_rpc_command function, except for
4389 * argc, argv which are passed through.
4391 * @param domain_sid The domain sid aquired from the remote server
4392 * @param cli A cli_state connected to the server.
4393 * @param mem_ctx Talloc context, destoyed on compleation of the function.
4394 * @param argc Standard main() style argc
4395 * @param argv Standard main() style argv. Initial components are already
4398 * @return Normal NTSTATUS return.
4401 static NTSTATUS rpc_reg_shutdown_abort_internals(const DOM_SID *domain_sid,
4402 const char *domain_name,
4403 struct cli_state *cli,
4404 TALLOC_CTX *mem_ctx,
4405 int argc, const char **argv)
4407 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
4409 result = werror_to_ntstatus(cli_reg_abort_shutdown(cli, mem_ctx));
4411 if (NT_STATUS_IS_OK(result)) {
4412 d_printf("\nShutdown successfully aborted\n");
4413 DEBUG(5,("cmd_reg_abort_shutdown: query succeeded\n"));
4415 DEBUG(5,("cmd_reg_abort_shutdown: query failed\n"));
4421 * ABORT the Shut down of a remote RPC server
4423 * @param argc Standard main() style argc
4424 * @param argv Standard main() style argv. Initial components are already
4427 * @return A shell status integer (0 for success)
4430 static int rpc_shutdown_abort(int argc, const char **argv)
4432 int rc = run_rpc_command(NULL, PI_SHUTDOWN, 0,
4433 rpc_shutdown_abort_internals,
4439 DEBUG(1, ("initshutdown pipe didn't work, trying winreg pipe\n"));
4441 return run_rpc_command(NULL, PI_WINREG, 0,
4442 rpc_reg_shutdown_abort_internals,
4447 * Shut down a remote RPC Server via initshutdown pipe
4449 * All parameters are provided by the run_rpc_command function, except for
4450 * argc, argv which are passes through.
4452 * @param domain_sid The domain sid aquired from the remote server
4453 * @param cli A cli_state connected to the server.
4454 * @param mem_ctx Talloc context, destoyed on compleation of the function.
4455 * @param argc Standard main() style argc
4456 * @param argc Standard main() style argv. Initial components are already
4459 * @return Normal NTSTATUS return.
4462 static NTSTATUS rpc_init_shutdown_internals(const DOM_SID *domain_sid,
4463 const char *domain_name,
4464 struct cli_state *cli,
4465 TALLOC_CTX *mem_ctx,
4466 int argc, const char **argv)
4468 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
4469 const char *msg = "This machine will be shutdown shortly";
4470 uint32 timeout = 20;
4479 timeout = opt_timeout;
4482 /* create an entry */
4483 result = cli_shutdown_init(cli, mem_ctx, msg, timeout, opt_reboot,
4486 if (NT_STATUS_IS_OK(result)) {
4487 d_printf("\nShutdown of remote machine succeeded\n");
4488 DEBUG(5,("Shutdown of remote machine succeeded\n"));
4490 DEBUG(0,("Shutdown of remote machine failed!\n"));
4496 * Shut down a remote RPC Server via winreg pipe
4498 * All parameters are provided by the run_rpc_command function, except for
4499 * argc, argv which are passes through.
4501 * @param domain_sid The domain sid aquired from the remote server
4502 * @param cli A cli_state connected to the server.
4503 * @param mem_ctx Talloc context, destoyed on compleation of the function.
4504 * @param argc Standard main() style argc
4505 * @param argc Standard main() style argv. Initial components are already
4508 * @return Normal NTSTATUS return.
4511 static NTSTATUS rpc_reg_shutdown_internals(const DOM_SID *domain_sid,
4512 const char *domain_name,
4513 struct cli_state *cli,
4514 TALLOC_CTX *mem_ctx,
4515 int argc, const char **argv)
4517 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
4518 const char *msg = "This machine will be shutdown shortly";
4519 uint32 timeout = 20;
4524 struct poptOption long_options[] = {
4525 {"message", 'm', POPT_ARG_STRING, &msg},
4526 {"timeout", 't', POPT_ARG_INT, &timeout},
4527 {"reboot", 'r', POPT_ARG_NONE, &reboot},
4528 {"force", 'f', POPT_ARG_NONE, &force},
4532 pc = poptGetContext(NULL, argc, (const char **) argv, long_options,
4533 POPT_CONTEXT_KEEP_FIRST);
4535 rc = poptGetNextOpt(pc);
4538 /* an error occurred during option processing */
4539 DEBUG(0, ("%s: %s\n",
4540 poptBadOption(pc, POPT_BADOPTION_NOALIAS),
4542 return NT_STATUS_INVALID_PARAMETER;
4549 timeout = opt_timeout;
4552 /* create an entry */
4553 result = werror_to_ntstatus(cli_reg_shutdown(cli, mem_ctx, msg, timeout, opt_reboot, opt_force));
4555 if (NT_STATUS_IS_OK(result)) {
4556 d_printf("\nShutdown of remote machine succeeded\n");
4557 DEBUG(5,("Shutdown of remote machine succeeded\n"));
4560 DEBUG(0,("Shutdown of remote machine failed!\n"));
4566 * Shut down a remote RPC server
4568 * @param argc Standard main() style argc
4569 * @param argc Standard main() style argv. Initial components are already
4572 * @return A shell status integer (0 for success)
4575 static int rpc_shutdown(int argc, const char **argv)
4577 int rc = run_rpc_command(NULL, PI_SHUTDOWN, 0,
4578 rpc_init_shutdown_internals,
4583 DEBUG(1, ("initshutdown pipe didn't work, trying winreg pipe\n"));
4585 return run_rpc_command(NULL, PI_WINREG, 0, rpc_reg_shutdown_internals,
4589 /***************************************************************************
4590 NT Domain trusts code (i.e. 'net rpc trustdom' functionality)
4592 ***************************************************************************/
4595 * Add interdomain trust account to the RPC server.
4596 * All parameters (except for argc and argv) are passed by run_rpc_command
4599 * @param domain_sid The domain sid acquired from the server
4600 * @param cli A cli_state connected to the server.
4601 * @param mem_ctx Talloc context, destoyed on completion of the function.
4602 * @param argc Standard main() style argc
4603 * @param argc Standard main() style argv. Initial components are already
4606 * @return normal NTSTATUS return code
4609 static NTSTATUS rpc_trustdom_add_internals(const DOM_SID *domain_sid,
4610 const char *domain_name,
4611 struct cli_state *cli, TALLOC_CTX *mem_ctx,
4612 int argc, const char **argv) {
4614 POLICY_HND connect_pol, domain_pol, user_pol;
4615 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
4618 uint32 unknown, user_rid;
4621 d_printf("Usage: net rpc trustdom add <domain_name> <pw>\n");
4622 return NT_STATUS_INVALID_PARAMETER;
4626 * Make valid trusting domain account (ie. uppercased and with '$' appended)
4629 if (asprintf(&acct_name, "%s$", argv[0]) < 0) {
4630 return NT_STATUS_NO_MEMORY;
4633 strupper_m(acct_name);
4635 /* Get samr policy handle */
4636 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
4638 if (!NT_STATUS_IS_OK(result)) {
4642 /* Get domain policy handle */
4643 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
4644 MAXIMUM_ALLOWED_ACCESS,
4645 domain_sid, &domain_pol);
4646 if (!NT_STATUS_IS_OK(result)) {
4650 /* Create trusting domain's account */
4651 acb_info = ACB_NORMAL;
4652 unknown = 0xe00500b0; /* No idea what this is - a permission mask?
4653 mimir: yes, most probably it is */
4655 result = cli_samr_create_dom_user(cli, mem_ctx, &domain_pol,
4656 acct_name, acb_info, unknown,
4657 &user_pol, &user_rid);
4658 if (!NT_STATUS_IS_OK(result)) {
4663 SAM_USERINFO_CTR ctr;
4664 SAM_USER_INFO_23 p23;
4670 encode_pw_buffer((char *)pwbuf, argv[1], STR_UNICODE);
4674 ZERO_STRUCT(notime);
4678 memset(hrs.hours, 0xFF, sizeof(hrs.hours));
4679 acb_info = ACB_DOMTRUST;
4681 init_sam_user_info23A(&p23, ¬ime, ¬ime, ¬ime,
4682 ¬ime, ¬ime, ¬ime,
4683 nostr, nostr, nostr, nostr, nostr,
4684 nostr, nostr, nostr, nostr, nostr,
4685 0, 0, acb_info, ACCT_FLAGS, 168, &hrs,
4686 0, 0, (char *)pwbuf);
4687 ctr.switch_value = 23;
4688 ctr.info.id23 = &p23;
4689 p23.passmustchange = 0;
4691 result = cli_samr_set_userinfo(cli, mem_ctx, &user_pol, 23,
4692 &cli->user_session_key, &ctr);
4694 if (!NT_STATUS_IS_OK(result)) {
4695 DEBUG(0,("Could not set trust account password: %s\n",
4696 nt_errstr(result)));
4702 SAFE_FREE(acct_name);
4707 * Create interdomain trust account for a remote domain.
4709 * @param argc standard argc
4710 * @param argv standard argv without initial components
4712 * @return Integer status (0 means success)
4715 static int rpc_trustdom_add(int argc, const char **argv)
4718 return run_rpc_command(NULL, PI_SAMR, 0, rpc_trustdom_add_internals,
4721 d_printf("Usage: net rpc trustdom add <domain>\n");
4728 * Remove interdomain trust account from the RPC server.
4729 * All parameters (except for argc and argv) are passed by run_rpc_command
4732 * @param domain_sid The domain sid acquired from the server
4733 * @param cli A cli_state connected to the server.
4734 * @param mem_ctx Talloc context, destoyed on completion of the function.
4735 * @param argc Standard main() style argc
4736 * @param argc Standard main() style argv. Initial components are already
4739 * @return normal NTSTATUS return code
4742 static NTSTATUS rpc_trustdom_del_internals(const DOM_SID *domain_sid,
4743 const char *domain_name,
4744 struct cli_state *cli, TALLOC_CTX *mem_ctx,
4745 int argc, const char **argv) {
4747 POLICY_HND connect_pol, domain_pol, user_pol;
4748 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
4751 DOM_SID trust_acct_sid;
4752 uint32 *user_rids, num_rids, *name_types;
4753 uint32 flags = 0x000003e8; /* Unknown */
4756 d_printf("Usage: net rpc trustdom del <domain_name>\n");
4757 return NT_STATUS_INVALID_PARAMETER;
4761 * Make valid trusting domain account (ie. uppercased and with '$' appended)
4763 acct_name = talloc_asprintf(mem_ctx, "%s$", argv[0]);
4765 if (acct_name == NULL)
4766 return NT_STATUS_NO_MEMORY;
4768 strupper_m(acct_name);
4770 names = TALLOC_ARRAY(mem_ctx, const char *, 1);
4771 names[0] = acct_name;
4774 /* Get samr policy handle */
4775 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
4777 if (!NT_STATUS_IS_OK(result)) {
4781 /* Get domain policy handle */
4782 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
4783 MAXIMUM_ALLOWED_ACCESS,
4784 domain_sid, &domain_pol);
4785 if (!NT_STATUS_IS_OK(result)) {
4789 result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol, flags, 1,
4791 &user_rids, &name_types);
4793 if (!NT_STATUS_IS_OK(result)) {
4797 result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
4798 MAXIMUM_ALLOWED_ACCESS,
4799 user_rids[0], &user_pol);
4801 if (!NT_STATUS_IS_OK(result)) {
4805 /* append the rid to the domain sid */
4806 sid_copy(&trust_acct_sid, domain_sid);
4807 if (!sid_append_rid(&trust_acct_sid, user_rids[0])) {
4811 /* remove the sid */
4813 result = cli_samr_remove_sid_foreign_domain(cli, mem_ctx, &user_pol,
4816 if (!NT_STATUS_IS_OK(result)) {
4822 result = cli_samr_delete_dom_user(cli, mem_ctx, &user_pol);
4824 if (!NT_STATUS_IS_OK(result)) {
4828 if (!NT_STATUS_IS_OK(result)) {
4829 DEBUG(0,("Could not set trust account password: %s\n",
4830 nt_errstr(result)));
4839 * Delete interdomain trust account for a remote domain.
4841 * @param argc standard argc
4842 * @param argv standard argv without initial components
4844 * @return Integer status (0 means success)
4847 static int rpc_trustdom_del(int argc, const char **argv)
4850 return run_rpc_command(NULL, PI_SAMR, 0, rpc_trustdom_del_internals,
4853 d_printf("Usage: net rpc trustdom del <domain>\n");
4860 * Establish trust relationship to a trusting domain.
4861 * Interdomain account must already be created on remote PDC.
4863 * @param argc standard argc
4864 * @param argv standard argv without initial components
4866 * @return Integer status (0 means success)
4869 static int rpc_trustdom_establish(int argc, const char **argv)
4871 struct cli_state *cli;
4872 struct in_addr server_ip;
4873 POLICY_HND connect_hnd;
4874 TALLOC_CTX *mem_ctx;
4876 DOM_SID *domain_sid;
4877 smb_ucs2_t *uni_domain_name;
4880 char* domain_name_pol;
4885 * Connect to \\server\ipc$ as 'our domain' account with password
4889 d_printf("Usage: net rpc trustdom establish <domain_name>\n");
4893 domain_name = smb_xstrdup(argv[0]);
4894 strupper_m(domain_name);
4896 /* account name used at first is our domain's name with '$' */
4897 asprintf(&acct_name, "%s$", lp_workgroup());
4898 strupper_m(acct_name);
4901 * opt_workgroup will be used by connection functions further,
4902 * hence it should be set to remote domain name instead of ours
4904 if (opt_workgroup) {
4905 opt_workgroup = smb_xstrdup(domain_name);
4908 opt_user_name = acct_name;
4910 /* find the domain controller */
4911 if (!net_find_pdc(&server_ip, pdc_name, domain_name)) {
4912 DEBUG(0, ("Couldn't find domain controller for domain %s\n", domain_name));
4916 /* connect to ipc$ as username/password */
4917 nt_status = connect_to_ipc(&cli, &server_ip, pdc_name);
4918 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT)) {
4920 /* Is it trusting domain account for sure ? */
4921 DEBUG(0, ("Couldn't verify trusting domain account. Error was %s\n",
4922 nt_errstr(nt_status)));
4927 * Connect to \\server\ipc$ again (this time anonymously)
4930 nt_status = connect_to_ipc_anonymous(&cli, &server_ip, (char*)pdc_name);
4932 if (NT_STATUS_IS_ERR(nt_status)) {
4933 DEBUG(0, ("Couldn't connect to domain %s controller. Error was %s.\n",
4934 domain_name, nt_errstr(nt_status)));
4938 * Use NetServerEnum2 to make sure we're talking to a proper server
4941 if (!cli_get_pdc_name(cli, domain_name, (char*)pdc_name)) {
4942 DEBUG(0, ("NetServerEnum2 error: Couldn't find primary domain controller\
4943 for domain %s\n", domain_name));
4946 if (!(mem_ctx = talloc_init("establishing trust relationship to "
4947 "domain %s", domain_name))) {
4948 DEBUG(0, ("talloc_init() failed\n"));
4954 * Call LsaOpenPolicy and LsaQueryInfo
4957 if (!cli_nt_session_open(cli, PI_LSARPC)) {
4958 DEBUG(0, ("Could not initialise lsa pipe\n"));
4963 nt_status = cli_lsa_open_policy2(cli, mem_ctx, True, SEC_RIGHTS_QUERY_VALUE,
4965 if (NT_STATUS_IS_ERR(nt_status)) {
4966 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
4967 nt_errstr(nt_status)));
4971 /* Querying info level 5 */
4973 nt_status = cli_lsa_query_info_policy(cli, mem_ctx, &connect_hnd,
4975 &domain_name_pol, &domain_sid);
4976 if (NT_STATUS_IS_ERR(nt_status)) {
4977 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
4978 nt_errstr(nt_status)));
4982 if (push_ucs2_talloc(mem_ctx, &uni_domain_name, domain_name_pol) == (size_t)-1) {
4983 DEBUG(0, ("Could not convert domain name %s to unicode\n",
4988 /* There should be actually query info level 3 (following nt serv behaviour),
4989 but I still don't know if it's _really_ necessary */
4992 * Store the password in secrets db
4995 if (!secrets_store_trusted_domain_password(domain_name,
4997 strlen_w(uni_domain_name)+1,
5000 DEBUG(0, ("Storing password for trusted domain failed.\n"));
5005 * Close the pipes and clean up
5008 nt_status = cli_lsa_close(cli, mem_ctx, &connect_hnd);
5009 if (NT_STATUS_IS_ERR(nt_status)) {
5010 DEBUG(0, ("Couldn't close LSA pipe. Error was %s\n",
5011 nt_errstr(nt_status)));
5015 if (cli->pipes[cli->pipe_idx].fnum)
5016 cli_nt_session_close(cli);
5020 talloc_destroy(mem_ctx);
5022 d_printf("Trust to domain %s established\n", domain_name);
5027 * Revoke trust relationship to the remote domain
5029 * @param argc standard argc
5030 * @param argv standard argv without initial components
5032 * @return Integer status (0 means success)
5035 static int rpc_trustdom_revoke(int argc, const char **argv)
5039 if (argc < 1) return -1;
5041 /* generate upper cased domain name */
5042 domain_name = smb_xstrdup(argv[0]);
5043 strupper_m(domain_name);
5045 /* delete password of the trust */
5046 if (!trusted_domain_password_delete(domain_name)) {
5047 DEBUG(0, ("Failed to revoke relationship to the trusted domain %s\n",
5056 * Usage for 'net rpc trustdom' command
5058 * @param argc standard argc
5059 * @param argv standard argv without inital components
5061 * @return Integer status returned to shell
5064 static int rpc_trustdom_usage(int argc, const char **argv)
5066 d_printf(" net rpc trustdom add \t\t add trusting domain's account\n");
5067 d_printf(" net rpc trustdom del \t\t delete trusting domain's account\n");
5068 d_printf(" net rpc trustdom establish \t establish relationship to trusted domain\n");
5069 d_printf(" net rpc trustdom revoke \t abandon relationship to trusted domain\n");
5070 d_printf(" net rpc trustdom list \t show current interdomain trust relationships\n");
5071 d_printf(" net rpc trustdom vampire \t vampire interdomain trust relationships from remote server\n");
5076 static NTSTATUS rpc_query_domain_sid(const DOM_SID *domain_sid,
5077 const char *domain_name,
5078 struct cli_state *cli, TALLOC_CTX *mem_ctx,
5079 int argc, const char **argv)
5082 sid_to_string(str_sid, domain_sid);
5083 d_printf("%s\n", str_sid);
5084 return NT_STATUS_OK;
5087 static void print_trusted_domain(DOM_SID *dom_sid, const char *trusted_dom_name)
5089 fstring ascii_sid, padding;
5090 int pad_len, col_len = 20;
5092 /* convert sid into ascii string */
5093 sid_to_string(ascii_sid, dom_sid);
5095 /* calculate padding space for d_printf to look nicer */
5096 pad_len = col_len - strlen(trusted_dom_name);
5097 padding[pad_len] = 0;
5098 do padding[--pad_len] = ' '; while (pad_len);
5100 d_printf("%s%s%s\n", trusted_dom_name, padding, ascii_sid);
5103 static NTSTATUS vampire_trusted_domain(struct cli_state *cli,
5104 TALLOC_CTX *mem_ctx,
5107 const char *trusted_dom_name)
5110 LSA_TRUSTED_DOMAIN_INFO *info;
5111 char *cleartextpwd = NULL;
5113 smb_ucs2_t *uni_dom_name;
5115 nt_status = cli_lsa_query_trusted_domain_info_by_sid(cli, mem_ctx, pol, 4, &dom_sid, &info);
5117 if (NT_STATUS_IS_ERR(nt_status)) {
5118 DEBUG(0,("Could not query trusted domain info. Error was %s\n",
5119 nt_errstr(nt_status)));
5123 data = data_blob(NULL, info->password.password.length);
5125 memcpy(data.data, info->password.password.data, info->password.password.length);
5126 data.length = info->password.password.length;
5128 cleartextpwd = decrypt_trustdom_secret(cli->pwd.password, &data);
5130 if (cleartextpwd == NULL) {
5131 DEBUG(0,("retrieved NULL password\n"));
5132 nt_status = NT_STATUS_UNSUCCESSFUL;
5136 if (push_ucs2_talloc(mem_ctx, &uni_dom_name, trusted_dom_name) == (size_t)-1) {
5137 DEBUG(0, ("Could not convert domain name %s to unicode\n",
5139 nt_status = NT_STATUS_UNSUCCESSFUL;
5143 if (!secrets_store_trusted_domain_password(trusted_dom_name,
5145 strlen_w(uni_dom_name)+1,
5148 DEBUG(0, ("Storing password for trusted domain failed.\n"));
5149 nt_status = NT_STATUS_UNSUCCESSFUL;
5153 DEBUG(100,("sucessfully vampired trusted domain [%s], sid: [%s], password: [%s]\n",
5154 trusted_dom_name, sid_string_static(&dom_sid), cleartextpwd));
5157 SAFE_FREE(cleartextpwd);
5158 data_blob_free(&data);
5163 static int rpc_trustdom_vampire(int argc, const char **argv)
5165 /* common variables */
5166 TALLOC_CTX* mem_ctx;
5167 struct cli_state *cli;
5169 const char *domain_name = NULL;
5170 DOM_SID *queried_dom_sid;
5171 POLICY_HND connect_hnd;
5173 /* trusted domains listing variables */
5174 unsigned int num_domains, enum_ctx = 0;
5176 DOM_SID *domain_sids;
5177 char **trusted_dom_names;
5182 * Listing trusted domains (stored in secrets.tdb, if local)
5185 mem_ctx = talloc_init("trust relationships vampire");
5188 * set domain and pdc name to local samba server (default)
5189 * or to remote one given in command line
5192 if (StrCaseCmp(opt_workgroup, lp_workgroup())) {
5193 domain_name = opt_workgroup;
5194 opt_target_workgroup = opt_workgroup;
5196 fstrcpy(pdc_name, global_myname());
5197 domain_name = talloc_strdup(mem_ctx, lp_workgroup());
5198 opt_target_workgroup = domain_name;
5201 /* open \PIPE\lsarpc and open policy handle */
5202 if (!(cli = net_make_ipc_connection(NET_FLAGS_PDC))) {
5203 DEBUG(0, ("Couldn't connect to domain controller\n"));
5207 if (!cli_nt_session_open(cli, PI_LSARPC)) {
5208 DEBUG(0, ("Could not initialise lsa pipe\n"));
5212 nt_status = cli_lsa_open_policy2(cli, mem_ctx, False, SEC_RIGHTS_QUERY_VALUE,
5214 if (NT_STATUS_IS_ERR(nt_status)) {
5215 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
5216 nt_errstr(nt_status)));
5220 /* query info level 5 to obtain sid of a domain being queried */
5221 nt_status = cli_lsa_query_info_policy(
5222 cli, mem_ctx, &connect_hnd, 5 /* info level */,
5223 &dummy, &queried_dom_sid);
5225 if (NT_STATUS_IS_ERR(nt_status)) {
5226 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
5227 nt_errstr(nt_status)));
5232 * Keep calling LsaEnumTrustdom over opened pipe until
5233 * the end of enumeration is reached
5236 d_printf("Vampire trusted domains:\n\n");
5239 nt_status = cli_lsa_enum_trust_dom(cli, mem_ctx, &connect_hnd, &enum_ctx,
5241 &trusted_dom_names, &domain_sids);
5243 if (NT_STATUS_IS_ERR(nt_status)) {
5244 DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
5245 nt_errstr(nt_status)));
5249 for (i = 0; i < num_domains; i++) {
5251 print_trusted_domain(&(domain_sids[i]), trusted_dom_names[i]);
5253 nt_status = vampire_trusted_domain(cli, mem_ctx, &connect_hnd,
5254 domain_sids[i], trusted_dom_names[i]);
5255 if (!NT_STATUS_IS_OK(nt_status))
5260 * in case of no trusted domains say something rather
5261 * than just display blank line
5263 if (!num_domains) d_printf("none\n");
5265 } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
5267 /* close this connection before doing next one */
5268 nt_status = cli_lsa_close(cli, mem_ctx, &connect_hnd);
5269 if (NT_STATUS_IS_ERR(nt_status)) {
5270 DEBUG(0, ("Couldn't properly close lsa policy handle. Error was %s\n",
5271 nt_errstr(nt_status)));
5275 /* close lsarpc pipe and connection to IPC$ */
5276 cli_nt_session_close(cli);
5279 talloc_destroy(mem_ctx);
5283 static int rpc_trustdom_list(int argc, const char **argv)
5285 /* common variables */
5286 TALLOC_CTX* mem_ctx;
5287 struct cli_state *cli, *remote_cli;
5289 const char *domain_name = NULL;
5290 DOM_SID *queried_dom_sid;
5292 int ascii_dom_name_len;
5293 POLICY_HND connect_hnd;
5295 /* trusted domains listing variables */
5296 unsigned int num_domains, enum_ctx = 0;
5297 int i, pad_len, col_len = 20;
5298 DOM_SID *domain_sids;
5299 char **trusted_dom_names;
5303 /* trusting domains listing variables */
5304 POLICY_HND domain_hnd;
5305 char **trusting_dom_names;
5306 uint32 *trusting_dom_rids;
5309 * Listing trusted domains (stored in secrets.tdb, if local)
5312 mem_ctx = talloc_init("trust relationships listing");
5315 * set domain and pdc name to local samba server (default)
5316 * or to remote one given in command line
5319 if (StrCaseCmp(opt_workgroup, lp_workgroup())) {
5320 domain_name = opt_workgroup;
5321 opt_target_workgroup = opt_workgroup;
5323 fstrcpy(pdc_name, global_myname());
5324 domain_name = talloc_strdup(mem_ctx, lp_workgroup());
5325 opt_target_workgroup = domain_name;
5328 /* open \PIPE\lsarpc and open policy handle */
5329 if (!(cli = net_make_ipc_connection(NET_FLAGS_PDC))) {
5330 DEBUG(0, ("Couldn't connect to domain controller\n"));
5334 if (!cli_nt_session_open(cli, PI_LSARPC)) {
5335 DEBUG(0, ("Could not initialise lsa pipe\n"));
5339 nt_status = cli_lsa_open_policy2(cli, mem_ctx, False, SEC_RIGHTS_QUERY_VALUE,
5341 if (NT_STATUS_IS_ERR(nt_status)) {
5342 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
5343 nt_errstr(nt_status)));
5347 /* query info level 5 to obtain sid of a domain being queried */
5348 nt_status = cli_lsa_query_info_policy(
5349 cli, mem_ctx, &connect_hnd, 5 /* info level */,
5350 &dummy, &queried_dom_sid);
5352 if (NT_STATUS_IS_ERR(nt_status)) {
5353 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
5354 nt_errstr(nt_status)));
5359 * Keep calling LsaEnumTrustdom over opened pipe until
5360 * the end of enumeration is reached
5363 d_printf("Trusted domains list:\n\n");
5366 nt_status = cli_lsa_enum_trust_dom(cli, mem_ctx, &connect_hnd, &enum_ctx,
5368 &trusted_dom_names, &domain_sids);
5370 if (NT_STATUS_IS_ERR(nt_status)) {
5371 DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
5372 nt_errstr(nt_status)));
5376 for (i = 0; i < num_domains; i++) {
5377 print_trusted_domain(&(domain_sids[i]), trusted_dom_names[i]);
5381 * in case of no trusted domains say something rather
5382 * than just display blank line
5384 if (!num_domains) d_printf("none\n");
5386 } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
5388 /* close this connection before doing next one */
5389 nt_status = cli_lsa_close(cli, mem_ctx, &connect_hnd);
5390 if (NT_STATUS_IS_ERR(nt_status)) {
5391 DEBUG(0, ("Couldn't properly close lsa policy handle. Error was %s\n",
5392 nt_errstr(nt_status)));
5396 cli_nt_session_close(cli);
5399 * Listing trusting domains (stored in passdb backend, if local)
5402 d_printf("\nTrusting domains list:\n\n");
5405 * Open \PIPE\samr and get needed policy handles
5407 if (!cli_nt_session_open(cli, PI_SAMR)) {
5408 DEBUG(0, ("Could not initialise samr pipe\n"));
5413 nt_status = cli_samr_connect(cli, mem_ctx, SA_RIGHT_SAM_OPEN_DOMAIN,
5415 if (!NT_STATUS_IS_OK(nt_status)) {
5416 DEBUG(0, ("Couldn't open SAMR policy handle. Error was %s\n",
5417 nt_errstr(nt_status)));
5421 /* SamrOpenDomain - we have to open domain policy handle in order to be
5422 able to enumerate accounts*/
5423 nt_status = cli_samr_open_domain(cli, mem_ctx, &connect_hnd,
5424 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
5425 queried_dom_sid, &domain_hnd);
5426 if (!NT_STATUS_IS_OK(nt_status)) {
5427 DEBUG(0, ("Couldn't open domain object. Error was %s\n",
5428 nt_errstr(nt_status)));
5433 * perform actual enumeration
5436 enum_ctx = 0; /* reset enumeration context from last enumeration */
5439 nt_status = cli_samr_enum_dom_users(cli, mem_ctx, &domain_hnd,
5440 &enum_ctx, ACB_DOMTRUST, 0xffff,
5441 &trusting_dom_names, &trusting_dom_rids,
5443 if (NT_STATUS_IS_ERR(nt_status)) {
5444 DEBUG(0, ("Couldn't enumerate accounts. Error was: %s\n",
5445 nt_errstr(nt_status)));
5449 for (i = 0; i < num_domains; i++) {
5452 * get each single domain's sid (do we _really_ need this ?):
5453 * 1) connect to domain's pdc
5454 * 2) query the pdc for domain's sid
5457 /* get rid of '$' tail */
5458 ascii_dom_name_len = strlen(trusting_dom_names[i]);
5459 if (ascii_dom_name_len && ascii_dom_name_len < FSTRING_LEN)
5460 trusting_dom_names[i][ascii_dom_name_len - 1] = '\0';
5462 /* calculate padding space for d_printf to look nicer */
5463 pad_len = col_len - strlen(trusting_dom_names[i]);
5464 padding[pad_len] = 0;
5465 do padding[--pad_len] = ' '; while (pad_len);
5467 /* set opt_* variables to remote domain */
5468 strupper_m(trusting_dom_names[i]);
5469 opt_workgroup = talloc_strdup(mem_ctx, trusting_dom_names[i]);
5470 opt_target_workgroup = opt_workgroup;
5472 d_printf("%s%s", trusting_dom_names[i], padding);
5474 /* connect to remote domain controller */
5475 remote_cli = net_make_ipc_connection(NET_FLAGS_PDC | NET_FLAGS_ANONYMOUS);
5477 /* query for domain's sid */
5478 if (run_rpc_command(remote_cli, PI_LSARPC, 0, rpc_query_domain_sid, argc, argv))
5479 d_printf("couldn't get domain's sid\n");
5481 cli_shutdown(remote_cli);
5484 d_printf("domain controller is not responding\n");
5488 if (!num_domains) d_printf("none\n");
5490 } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
5492 /* close opened samr and domain policy handles */
5493 nt_status = cli_samr_close(cli, mem_ctx, &domain_hnd);
5494 if (!NT_STATUS_IS_OK(nt_status)) {
5495 DEBUG(0, ("Couldn't properly close domain policy handle for domain %s\n", domain_name));
5498 nt_status = cli_samr_close(cli, mem_ctx, &connect_hnd);
5499 if (!NT_STATUS_IS_OK(nt_status)) {
5500 DEBUG(0, ("Couldn't properly close samr policy handle for domain %s\n", domain_name));
5503 /* close samr pipe and connection to IPC$ */
5504 cli_nt_session_close(cli);
5507 talloc_destroy(mem_ctx);
5512 * Entrypoint for 'net rpc trustdom' code
5514 * @param argc standard argc
5515 * @param argv standard argv without initial components
5517 * @return Integer status (0 means success)
5520 static int rpc_trustdom(int argc, const char **argv)
5522 struct functable func[] = {
5523 {"add", rpc_trustdom_add},
5524 {"del", rpc_trustdom_del},
5525 {"establish", rpc_trustdom_establish},
5526 {"revoke", rpc_trustdom_revoke},
5527 {"help", rpc_trustdom_usage},
5528 {"list", rpc_trustdom_list},
5529 {"vampire", rpc_trustdom_vampire},
5534 rpc_trustdom_usage(argc, argv);
5538 return (net_run_function(argc, argv, func, rpc_user_usage));
5542 * Check if a server will take rpc commands
5543 * @param flags Type of server to connect to (PDC, DMB, localhost)
5544 * if the host is not explicitly specified
5545 * @return BOOL (true means rpc supported)
5547 BOOL net_rpc_check(unsigned flags)
5549 struct cli_state cli;
5551 struct in_addr server_ip;
5552 char *server_name = NULL;
5554 /* flags (i.e. server type) may depend on command */
5555 if (!net_find_server(flags, &server_ip, &server_name))
5559 if (cli_initialise(&cli) == False)
5562 if (!cli_connect(&cli, server_name, &server_ip))
5564 if (!attempt_netbios_session_request(&cli, global_myname(),
5565 server_name, &server_ip))
5567 if (!cli_negprot(&cli))
5569 if (cli.protocol < PROTOCOL_NT1)
5578 /* dump sam database via samsync rpc calls */
5579 static int rpc_samdump(int argc, const char **argv) {
5580 return run_rpc_command(NULL, PI_NETLOGON, NET_FLAGS_ANONYMOUS, rpc_samdump_internals,
5584 /* syncronise sam database via samsync rpc calls */
5585 static int rpc_vampire(int argc, const char **argv) {
5586 return run_rpc_command(NULL, PI_NETLOGON, NET_FLAGS_ANONYMOUS, rpc_vampire_internals,
5591 * Migrate everything from a print-server
5593 * @param argc Standard main() style argc
5594 * @param argv Standard main() style argv. Initial components are already
5597 * @return A shell status integer (0 for success)
5599 * The order is important !
5600 * To successfully add drivers the print-queues have to exist !
5601 * Applying ACLs should be the last step, because you're easily locked out
5604 static int rpc_printer_migrate_all(int argc, const char **argv)
5609 printf("no server to migrate\n");
5613 ret = run_rpc_command(NULL, PI_SPOOLSS, 0, rpc_printer_migrate_printers_internals, argc, argv);
5617 ret = run_rpc_command(NULL, PI_SPOOLSS, 0, rpc_printer_migrate_drivers_internals, argc, argv);
5621 ret = run_rpc_command(NULL, PI_SPOOLSS, 0, rpc_printer_migrate_forms_internals, argc, argv);
5625 ret = run_rpc_command(NULL, PI_SPOOLSS, 0, rpc_printer_migrate_settings_internals, argc, argv);
5629 return run_rpc_command(NULL, PI_SPOOLSS, 0, rpc_printer_migrate_security_internals, argc, argv);
5634 * Migrate print-drivers from a print-server
5636 * @param argc Standard main() style argc
5637 * @param argv Standard main() style argv. Initial components are already
5640 * @return A shell status integer (0 for success)
5642 static int rpc_printer_migrate_drivers(int argc, const char **argv)
5645 printf("no server to migrate\n");
5649 return run_rpc_command(NULL, PI_SPOOLSS, 0,
5650 rpc_printer_migrate_drivers_internals,
5655 * Migrate print-forms from a print-server
5657 * @param argc Standard main() style argc
5658 * @param argv Standard main() style argv. Initial components are already
5661 * @return A shell status integer (0 for success)
5663 static int rpc_printer_migrate_forms(int argc, const char **argv)
5666 printf("no server to migrate\n");
5670 return run_rpc_command(NULL, PI_SPOOLSS, 0,
5671 rpc_printer_migrate_forms_internals,
5676 * Migrate printers from a print-server
5678 * @param argc Standard main() style argc
5679 * @param argv Standard main() style argv. Initial components are already
5682 * @return A shell status integer (0 for success)
5684 static int rpc_printer_migrate_printers(int argc, const char **argv)
5687 printf("no server to migrate\n");
5691 return run_rpc_command(NULL, PI_SPOOLSS, 0,
5692 rpc_printer_migrate_printers_internals,
5697 * Migrate printer-ACLs from a print-server
5699 * @param argc Standard main() style argc
5700 * @param argv Standard main() style argv. Initial components are already
5703 * @return A shell status integer (0 for success)
5705 static int rpc_printer_migrate_security(int argc, const char **argv)
5708 printf("no server to migrate\n");
5712 return run_rpc_command(NULL, PI_SPOOLSS, 0,
5713 rpc_printer_migrate_security_internals,
5718 * Migrate printer-settings from a print-server
5720 * @param argc Standard main() style argc
5721 * @param argv Standard main() style argv. Initial components are already
5724 * @return A shell status integer (0 for success)
5726 static int rpc_printer_migrate_settings(int argc, const char **argv)
5729 printf("no server to migrate\n");
5733 return run_rpc_command(NULL, PI_SPOOLSS, 0,
5734 rpc_printer_migrate_settings_internals,
5739 * 'net rpc printer' entrypoint.
5740 * @param argc Standard main() style argc
5741 * @param argv Standard main() style argv. Initial components are already
5745 int rpc_printer_migrate(int argc, const char **argv)
5748 /* ouch: when addriver and setdriver are called from within
5749 rpc_printer_migrate_drivers_internals, the printer-queue already
5752 struct functable func[] = {
5753 {"all", rpc_printer_migrate_all},
5754 {"drivers", rpc_printer_migrate_drivers},
5755 {"forms", rpc_printer_migrate_forms},
5756 {"help", rpc_printer_usage},
5757 {"printers", rpc_printer_migrate_printers},
5758 {"security", rpc_printer_migrate_security},
5759 {"settings", rpc_printer_migrate_settings},
5763 return net_run_function(argc, argv, func, rpc_printer_usage);
5768 * List printers on a remote RPC server
5770 * @param argc Standard main() style argc
5771 * @param argv Standard main() style argv. Initial components are already
5774 * @return A shell status integer (0 for success)
5776 static int rpc_printer_list(int argc, const char **argv)
5779 return run_rpc_command(NULL, PI_SPOOLSS, 0,
5780 rpc_printer_list_internals,
5785 * List printer-drivers on a remote RPC server
5787 * @param argc Standard main() style argc
5788 * @param argv Standard main() style argv. Initial components are already
5791 * @return A shell status integer (0 for success)
5793 static int rpc_printer_driver_list(int argc, const char **argv)
5796 return run_rpc_command(NULL, PI_SPOOLSS, 0,
5797 rpc_printer_driver_list_internals,
5802 * Publish printer in ADS via MSRPC
5804 * @param argc Standard main() style argc
5805 * @param argv Standard main() style argv. Initial components are already
5808 * @return A shell status integer (0 for success)
5810 static int rpc_printer_publish_publish(int argc, const char **argv)
5813 return run_rpc_command(NULL, PI_SPOOLSS, 0,
5814 rpc_printer_publish_publish_internals,
5819 * Update printer in ADS via MSRPC
5821 * @param argc Standard main() style argc
5822 * @param argv Standard main() style argv. Initial components are already
5825 * @return A shell status integer (0 for success)
5827 static int rpc_printer_publish_update(int argc, const char **argv)
5830 return run_rpc_command(NULL, PI_SPOOLSS, 0,
5831 rpc_printer_publish_update_internals,
5836 * UnPublish printer in ADS via MSRPC
5838 * @param argc Standard main() style argc
5839 * @param argv Standard main() style argv. Initial components are already
5842 * @return A shell status integer (0 for success)
5844 static int rpc_printer_publish_unpublish(int argc, const char **argv)
5847 return run_rpc_command(NULL, PI_SPOOLSS, 0,
5848 rpc_printer_publish_unpublish_internals,
5853 * List published printers via MSRPC
5855 * @param argc Standard main() style argc
5856 * @param argv Standard main() style argv. Initial components are already
5859 * @return A shell status integer (0 for success)
5861 static int rpc_printer_publish_list(int argc, const char **argv)
5864 return run_rpc_command(NULL, PI_SPOOLSS, 0,
5865 rpc_printer_publish_list_internals,
5871 * Publish printer in ADS
5873 * @param argc Standard main() style argc
5874 * @param argv Standard main() style argv. Initial components are already
5877 * @return A shell status integer (0 for success)
5879 static int rpc_printer_publish(int argc, const char **argv)
5882 struct functable func[] = {
5883 {"publish", rpc_printer_publish_publish},
5884 {"update", rpc_printer_publish_update},
5885 {"unpublish", rpc_printer_publish_unpublish},
5886 {"list", rpc_printer_publish_list},
5887 {"help", rpc_printer_usage},
5892 return run_rpc_command(NULL, PI_SPOOLSS, 0,
5893 rpc_printer_publish_list_internals,
5896 return net_run_function(argc, argv, func, rpc_printer_usage);
5902 * Display rpc printer help page.
5903 * @param argc Standard main() style argc
5904 * @param argv Standard main() style argv. Initial components are already
5907 int rpc_printer_usage(int argc, const char **argv)
5909 return net_help_printer(argc, argv);
5913 * 'net rpc printer' entrypoint.
5914 * @param argc Standard main() style argc
5915 * @param argv Standard main() style argv. Initial components are already
5918 int net_rpc_printer(int argc, const char **argv)
5920 struct functable func[] = {
5921 {"list", rpc_printer_list},
5922 {"migrate", rpc_printer_migrate},
5923 {"driver", rpc_printer_driver_list},
5924 {"publish", rpc_printer_publish},
5929 return run_rpc_command(NULL, PI_SPOOLSS, 0,
5930 rpc_printer_list_internals,
5933 return net_run_function(argc, argv, func, rpc_printer_usage);
5936 /****************************************************************************/
5940 * Basic usage function for 'net rpc'
5941 * @param argc Standard main() style argc
5942 * @param argv Standard main() style argv. Initial components are already
5946 int net_rpc_usage(int argc, const char **argv)
5948 d_printf(" net rpc info \t\t\tshow basic info about a domain \n");
5949 d_printf(" net rpc join \t\t\tto join a domain \n");
5950 d_printf(" net rpc oldjoin \t\t\tto join a domain created in server manager\n");
5951 d_printf(" net rpc testjoin \t\ttests that a join is valid\n");
5952 d_printf(" net rpc user \t\t\tto add, delete and list users\n");
5953 d_printf(" net rpc password <username> [<password>] -Uadmin_username%%admin_pass\n");
5954 d_printf(" net rpc group \t\tto list groups\n");
5955 d_printf(" net rpc share \t\tto add, delete, list and migrate shares\n");
5956 d_printf(" net rpc printer \t\tto list and migrate printers\n");
5957 d_printf(" net rpc file \t\t\tto list open files\n");
5958 d_printf(" net rpc changetrustpw \tto change the trust account password\n");
5959 d_printf(" net rpc getsid \t\tfetch the domain sid into the local secrets.tdb\n");
5960 d_printf(" net rpc vampire \t\tsyncronise an NT PDC's users and groups into the local passdb\n");
5961 d_printf(" net rpc samdump \t\tdiplay an NT PDC's users, groups and other data\n");
5962 d_printf(" net rpc trustdom \t\tto create trusting domain's account or establish trust\n");
5963 d_printf(" net rpc abortshutdown \tto abort the shutdown of a remote server\n");
5964 d_printf(" net rpc shutdown \t\tto shutdown a remote server\n");
5965 d_printf(" net rpc rights\t\tto manage privileges assigned to SIDs\n");
5966 d_printf(" net rpc registry\t\tto manage registry hives\n");
5967 d_printf(" net rpc service\t\tto start, stop and query services\n");
5969 d_printf("'net rpc shutdown' also accepts the following miscellaneous options:\n"); /* misc options */
5970 d_printf("\t-r or --reboot\trequest remote server reboot on shutdown\n");
5971 d_printf("\t-f or --force\trequest the remote server force its shutdown\n");
5972 d_printf("\t-t or --timeout=<timeout>\tnumber of seconds before shutdown\n");
5973 d_printf("\t-C or --comment=<message>\ttext message to display on impending shutdown\n");
5979 * Help function for 'net rpc'. Calls command specific help if requested
5980 * or displays usage of net rpc
5981 * @param argc Standard main() style argc
5982 * @param argv Standard main() style argv. Initial components are already
5986 int net_rpc_help(int argc, const char **argv)
5988 struct functable func[] = {
5989 {"join", rpc_join_usage},
5990 {"user", rpc_user_usage},
5991 {"group", rpc_group_usage},
5992 {"share", rpc_share_usage},
5993 /*{"changetrustpw", rpc_changetrustpw_usage}, */
5994 {"trustdom", rpc_trustdom_usage},
5995 /*{"abortshutdown", rpc_shutdown_abort_usage},*/
5996 /*{"shutdown", rpc_shutdown_usage}, */
5997 {"vampire", rpc_vampire_usage},
6002 net_rpc_usage(argc, argv);
6006 return (net_run_function(argc, argv, func, rpc_user_usage));
6011 * 'net rpc' entrypoint.
6012 * @param argc Standard main() style argc
6013 * @param argv Standard main() style argv. Initial components are already
6017 int net_rpc(int argc, const char **argv)
6019 struct functable func[] = {
6020 {"info", net_rpc_info},
6021 {"join", net_rpc_join},
6022 {"oldjoin", net_rpc_oldjoin},
6023 {"testjoin", net_rpc_testjoin},
6024 {"user", net_rpc_user},
6025 {"password", rpc_user_password},
6026 {"group", net_rpc_group},
6027 {"share", net_rpc_share},
6028 {"file", net_rpc_file},
6029 {"printer", net_rpc_printer},
6030 {"changetrustpw", net_rpc_changetrustpw},
6031 {"trustdom", rpc_trustdom},
6032 {"abortshutdown", rpc_shutdown_abort},
6033 {"shutdown", rpc_shutdown},
6034 {"samdump", rpc_samdump},
6035 {"vampire", rpc_vampire},
6036 {"getsid", net_rpc_getsid},
6037 {"rights", net_rpc_rights},
6038 {"service", net_rpc_service},
6039 {"registry", net_rpc_registry},
6040 {"help", net_rpc_help},
6043 return net_run_function(argc, argv, func, net_rpc_usage);