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)
7 Copyright (C) 2005 Jeremy Allison (jra@samba.org)
8 Copyright (C) 2006 Jelmer Vernooij (jelmer@samba.org)
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>. */
24 #include "utils/net.h"
26 static int net_mode_share;
27 static bool sync_files(struct copy_clistate *cp_clistate, const char *mask);
32 * @brief RPC based subcommands for the 'net' utility.
34 * This file should contain much of the functionality that used to
35 * be found in rpcclient, execpt that the commands should change
36 * less often, and the fucntionality should be sane (the user is not
37 * expected to know a rid/sid before they conduct an operation etc.)
39 * @todo Perhaps eventually these should be split out into a number
40 * of files, as this could get quite big.
45 * Many of the RPC functions need the domain sid. This function gets
46 * it at the start of every run
48 * @param cli A cli_state already connected to the remote machine
50 * @return The Domain SID of the remote machine.
53 NTSTATUS net_get_remote_domain_sid(struct cli_state *cli, TALLOC_CTX *mem_ctx,
55 const char **domain_name)
57 struct rpc_pipe_client *lsa_pipe;
59 NTSTATUS result = NT_STATUS_OK;
60 uint32 info_class = 5;
62 lsa_pipe = cli_rpc_pipe_open_noauth(cli, PI_LSARPC, &result);
64 d_fprintf(stderr, "Could not initialise lsa pipe\n");
68 result = rpccli_lsa_open_policy(lsa_pipe, mem_ctx, False,
69 SEC_RIGHTS_MAXIMUM_ALLOWED,
71 if (!NT_STATUS_IS_OK(result)) {
72 d_fprintf(stderr, "open_policy failed: %s\n",
77 result = rpccli_lsa_query_info_policy(lsa_pipe, mem_ctx, &pol,
78 info_class, domain_name,
80 if (!NT_STATUS_IS_OK(result)) {
81 d_fprintf(stderr, "lsaquery failed: %s\n",
86 rpccli_lsa_Close(lsa_pipe, mem_ctx, &pol);
87 cli_rpc_pipe_close(lsa_pipe);
93 * Run a single RPC command, from start to finish.
95 * @param pipe_name the pipe to connect to (usually a PIPE_ constant)
96 * @param conn_flag a NET_FLAG_ combination. Passed to
97 * net_make_ipc_connection.
98 * @param argc Standard main() style argc
99 * @param argc Standard main() style argv. Initial components are already
101 * @return A shell status integer (0 for success)
104 int run_rpc_command(struct cli_state *cli_arg,
111 struct cli_state *cli = NULL;
112 struct rpc_pipe_client *pipe_hnd = NULL;
116 const char *domain_name;
118 /* make use of cli_state handed over as an argument, if possible */
120 nt_status = net_make_ipc_connection(conn_flags, &cli);
121 if (!NT_STATUS_IS_OK(nt_status)) {
122 DEBUG(1, ("failed to make ipc connection: %s\n",
123 nt_errstr(nt_status)));
136 if (!(mem_ctx = talloc_init("run_rpc_command"))) {
137 DEBUG(0, ("talloc_init() failed\n"));
142 nt_status = net_get_remote_domain_sid(cli, mem_ctx, &domain_sid,
144 if (!NT_STATUS_IS_OK(nt_status)) {
149 if (!(conn_flags & NET_FLAGS_NO_PIPE)) {
150 if (lp_client_schannel() && (pipe_idx == PI_NETLOGON)) {
151 /* Always try and create an schannel netlogon pipe. */
152 pipe_hnd = cli_rpc_pipe_open_schannel(cli, pipe_idx,
153 PIPE_AUTH_LEVEL_PRIVACY,
157 DEBUG(0, ("Could not initialise schannel netlogon pipe. Error was %s\n",
158 nt_errstr(nt_status) ));
163 pipe_hnd = cli_rpc_pipe_open_noauth(cli, pipe_idx, &nt_status);
165 DEBUG(0, ("Could not initialise pipe %s. Error was %s\n",
166 cli_get_pipe_name(pipe_idx),
167 nt_errstr(nt_status) ));
174 nt_status = fn(domain_sid, domain_name, cli, pipe_hnd, mem_ctx, argc, argv);
176 if (!NT_STATUS_IS_OK(nt_status)) {
177 DEBUG(1, ("rpc command function failed! (%s)\n", nt_errstr(nt_status)));
179 DEBUG(5, ("rpc command function succedded\n"));
182 if (!(conn_flags & NET_FLAGS_NO_PIPE)) {
184 cli_rpc_pipe_close(pipe_hnd);
188 /* close the connection only if it was opened here */
193 talloc_destroy(mem_ctx);
194 return (!NT_STATUS_IS_OK(nt_status));
198 * Force a change of the trust acccount password.
200 * All parameters are provided by the run_rpc_command function, except for
201 * argc, argv which are passes through.
203 * @param domain_sid The domain sid aquired from the remote server
204 * @param cli A cli_state connected to the server.
205 * @param mem_ctx Talloc context, destoyed on compleation of the function.
206 * @param argc Standard main() style argc
207 * @param argc Standard main() style argv. Initial components are already
210 * @return Normal NTSTATUS return.
213 static NTSTATUS rpc_changetrustpw_internals(const DOM_SID *domain_sid,
214 const char *domain_name,
215 struct cli_state *cli,
216 struct rpc_pipe_client *pipe_hnd,
222 return trust_pw_find_change_and_store_it(pipe_hnd, mem_ctx, opt_target_workgroup);
226 * Force a change of the trust acccount password.
228 * @param argc Standard main() style argc
229 * @param argc Standard main() style argv. Initial components are already
232 * @return A shell status integer (0 for success)
235 int net_rpc_changetrustpw(int argc, const char **argv)
237 return run_rpc_command(NULL, PI_NETLOGON, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC,
238 rpc_changetrustpw_internals,
243 * Join a domain, the old way.
245 * This uses 'machinename' as the inital password, and changes it.
247 * The password should be created with 'server manager' or equiv first.
249 * All parameters are provided by the run_rpc_command function, except for
250 * argc, argv which are passes through.
252 * @param domain_sid The domain sid aquired from the remote server
253 * @param cli A cli_state connected to the server.
254 * @param mem_ctx Talloc context, destoyed on compleation of the function.
255 * @param argc Standard main() style argc
256 * @param argc Standard main() style argv. Initial components are already
259 * @return Normal NTSTATUS return.
262 static NTSTATUS rpc_oldjoin_internals(const DOM_SID *domain_sid,
263 const char *domain_name,
264 struct cli_state *cli,
265 struct rpc_pipe_client *pipe_hnd,
271 fstring trust_passwd;
272 unsigned char orig_trust_passwd_hash[16];
274 uint32 sec_channel_type;
276 pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_NETLOGON, &result);
278 DEBUG(0,("rpc_oldjoin_internals: netlogon pipe open to machine %s failed. "
281 nt_errstr(result) ));
286 check what type of join - if the user want's to join as
287 a BDC, the server must agree that we are a BDC.
290 sec_channel_type = get_sec_channel_type(argv[0]);
292 sec_channel_type = get_sec_channel_type(NULL);
295 fstrcpy(trust_passwd, global_myname());
296 strlower_m(trust_passwd);
299 * Machine names can be 15 characters, but the max length on
300 * a password is 14. --jerry
303 trust_passwd[14] = '\0';
305 E_md4hash(trust_passwd, orig_trust_passwd_hash);
307 result = trust_pw_change_and_store_it(pipe_hnd, mem_ctx, opt_target_workgroup,
308 orig_trust_passwd_hash,
311 if (NT_STATUS_IS_OK(result))
312 printf("Joined domain %s.\n",opt_target_workgroup);
315 if (!secrets_store_domain_sid(opt_target_workgroup, domain_sid)) {
316 DEBUG(0, ("error storing domain sid for %s\n", opt_target_workgroup));
317 result = NT_STATUS_UNSUCCESSFUL;
324 * Join a domain, the old way.
326 * @param argc Standard main() style argc
327 * @param argc Standard main() style argv. Initial components are already
330 * @return A shell status integer (0 for success)
333 static int net_rpc_perform_oldjoin(int argc, const char **argv)
335 return run_rpc_command(NULL, PI_NETLOGON,
336 NET_FLAGS_NO_PIPE | NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC,
337 rpc_oldjoin_internals,
342 * Join a domain, the old way. This function exists to allow
343 * the message to be displayed when oldjoin was explicitly
344 * requested, but not when it was implied by "net rpc join"
346 * @param argc Standard main() style argc
347 * @param argc Standard main() style argv. Initial components are already
350 * @return A shell status integer (0 for success)
353 static int net_rpc_oldjoin(int argc, const char **argv)
355 int rc = net_rpc_perform_oldjoin(argc, argv);
358 d_fprintf(stderr, "Failed to join domain\n");
365 * Basic usage function for 'net rpc join'
366 * @param argc Standard main() style argc
367 * @param argc Standard main() style argv. Initial components are already
371 static int rpc_join_usage(int argc, const char **argv)
373 d_printf("net rpc join -U <username>[%%password] <type>[options]\n"\
374 "\t to join a domain with admin username & password\n"\
375 "\t\t password will be prompted if needed and none is specified\n"\
376 "\t <type> can be (default MEMBER)\n"\
377 "\t\t BDC - Join as a BDC\n"\
378 "\t\t PDC - Join as a PDC\n"\
379 "\t\t MEMBER - Join as a MEMBER server\n");
381 net_common_flags_usage(argc, argv);
386 * 'net rpc join' entrypoint.
387 * @param argc Standard main() style argc
388 * @param argc Standard main() style argv. Initial components are already
391 * Main 'net_rpc_join()' (where the admain username/password is used) is
393 * Try to just change the password, but if that doesn't work, use/prompt
394 * for a username/password.
397 int net_rpc_join(int argc, const char **argv)
399 if (lp_server_role() == ROLE_STANDALONE) {
400 d_printf("cannot join as standalone machine\n");
404 if (strlen(global_myname()) > 15) {
405 d_printf("Our netbios name can be at most 15 chars long, "
406 "\"%s\" is %u chars long\n",
407 global_myname(), (unsigned int)strlen(global_myname()));
411 if ((net_rpc_perform_oldjoin(argc, argv) == 0))
414 return net_rpc_join_newstyle(argc, argv);
418 * display info about a rpc domain
420 * All parameters are provided by the run_rpc_command function, except for
421 * argc, argv which are passed through.
423 * @param domain_sid The domain sid acquired from the remote server
424 * @param cli A cli_state connected to the server.
425 * @param mem_ctx Talloc context, destoyed on completion of the function.
426 * @param argc Standard main() style argc
427 * @param argv Standard main() style argv. Initial components are already
430 * @return Normal NTSTATUS return.
433 NTSTATUS rpc_info_internals(const DOM_SID *domain_sid,
434 const char *domain_name,
435 struct cli_state *cli,
436 struct rpc_pipe_client *pipe_hnd,
441 POLICY_HND connect_pol, domain_pol;
442 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
446 sid_to_fstring(sid_str, domain_sid);
448 /* Get sam policy handle */
449 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
451 if (!NT_STATUS_IS_OK(result)) {
452 d_fprintf(stderr, "Could not connect to SAM: %s\n", nt_errstr(result));
456 /* Get domain policy handle */
457 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
458 MAXIMUM_ALLOWED_ACCESS,
459 domain_sid, &domain_pol);
460 if (!NT_STATUS_IS_OK(result)) {
461 d_fprintf(stderr, "Could not open domain: %s\n", nt_errstr(result));
466 result = rpccli_samr_query_dom_info(pipe_hnd, mem_ctx, &domain_pol,
468 if (NT_STATUS_IS_OK(result)) {
469 TALLOC_CTX *ctx = talloc_init("rpc_info_internals");
470 d_printf("Domain Name: %s\n", unistr2_to_ascii_talloc(ctx, &ctr.info.inf2.uni_domain));
471 d_printf("Domain SID: %s\n", sid_str);
472 d_printf("Sequence number: %llu\n", (unsigned long long)ctr.info.inf2.seq_num);
473 d_printf("Num users: %u\n", ctr.info.inf2.num_domain_usrs);
474 d_printf("Num domain groups: %u\n", ctr.info.inf2.num_domain_grps);
475 d_printf("Num local groups: %u\n", ctr.info.inf2.num_local_grps);
484 * 'net rpc info' entrypoint.
485 * @param argc Standard main() style argc
486 * @param argc Standard main() style argv. Initial components are already
490 int net_rpc_info(int argc, const char **argv)
492 return run_rpc_command(NULL, PI_SAMR, NET_FLAGS_PDC,
498 * Fetch domain SID into the local secrets.tdb
500 * All parameters are provided by the run_rpc_command function, except for
501 * argc, argv which are passes through.
503 * @param domain_sid The domain sid acquired from the remote server
504 * @param cli A cli_state connected to the server.
505 * @param mem_ctx Talloc context, destoyed on completion of the function.
506 * @param argc Standard main() style argc
507 * @param argv Standard main() style argv. Initial components are already
510 * @return Normal NTSTATUS return.
513 static NTSTATUS rpc_getsid_internals(const DOM_SID *domain_sid,
514 const char *domain_name,
515 struct cli_state *cli,
516 struct rpc_pipe_client *pipe_hnd,
523 sid_to_fstring(sid_str, domain_sid);
524 d_printf("Storing SID %s for Domain %s in secrets.tdb\n",
525 sid_str, domain_name);
527 if (!secrets_store_domain_sid(domain_name, domain_sid)) {
528 DEBUG(0,("Can't store domain SID\n"));
529 return NT_STATUS_UNSUCCESSFUL;
536 * 'net rpc getsid' entrypoint.
537 * @param argc Standard main() style argc
538 * @param argc Standard main() style argv. Initial components are already
542 int net_rpc_getsid(int argc, const char **argv)
544 return run_rpc_command(NULL, PI_SAMR, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC,
545 rpc_getsid_internals,
549 /****************************************************************************/
552 * Basic usage function for 'net rpc user'
553 * @param argc Standard main() style argc.
554 * @param argv Standard main() style argv. Initial components are already
558 static int rpc_user_usage(int argc, const char **argv)
560 return net_help_user(argc, argv);
564 * Add a new user to a remote RPC server
566 * All parameters are provided by the run_rpc_command function, except for
567 * argc, argv which are passes through.
569 * @param domain_sid The domain sid acquired from the remote server
570 * @param cli A cli_state connected to the server.
571 * @param mem_ctx Talloc context, destoyed on completion of the function.
572 * @param argc Standard main() style argc
573 * @param argv Standard main() style argv. Initial components are already
576 * @return Normal NTSTATUS return.
579 static NTSTATUS rpc_user_add_internals(const DOM_SID *domain_sid,
580 const char *domain_name,
581 struct cli_state *cli,
582 struct rpc_pipe_client *pipe_hnd,
584 int argc, const char **argv)
587 POLICY_HND connect_pol, domain_pol, user_pol;
588 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
589 const char *acct_name;
591 uint32 access_mask, user_rid;
594 d_printf("User must be specified\n");
595 rpc_user_usage(argc, argv);
601 /* Get sam policy handle */
603 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
605 if (!NT_STATUS_IS_OK(result)) {
609 /* Get domain policy handle */
611 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
612 MAXIMUM_ALLOWED_ACCESS,
613 domain_sid, &domain_pol);
614 if (!NT_STATUS_IS_OK(result)) {
618 /* Create domain user */
620 acb_info = ACB_NORMAL;
621 access_mask = 0xe005000b;
623 result = rpccli_samr_create_dom_user(pipe_hnd, mem_ctx, &domain_pol,
624 acct_name, acb_info, access_mask,
625 &user_pol, &user_rid);
626 if (!NT_STATUS_IS_OK(result)) {
632 uint32 *user_rids, num_rids, *name_types;
633 uint32 flags = 0x000003e8; /* Unknown */
634 SAM_USERINFO_CTR ctr;
635 SAM_USER_INFO_24 p24;
638 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol,
639 flags, 1, &acct_name,
640 &num_rids, &user_rids,
643 if (!NT_STATUS_IS_OK(result)) {
647 result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
648 MAXIMUM_ALLOWED_ACCESS,
649 user_rids[0], &user_pol);
651 if (!NT_STATUS_IS_OK(result)) {
655 /* Set password on account */
660 encode_pw_buffer(pwbuf, argv[1], STR_UNICODE);
662 init_sam_user_info24(&p24, (char *)pwbuf,24);
664 ctr.switch_value = 24;
665 ctr.info.id24 = &p24;
667 result = rpccli_samr_set_userinfo(pipe_hnd, mem_ctx, &user_pol, 24,
668 &cli->user_session_key, &ctr);
670 if (!NT_STATUS_IS_OK(result)) {
671 d_fprintf(stderr, "Failed to set password for user %s - %s\n",
672 acct_name, nt_errstr(result));
674 result = rpccli_samr_delete_dom_user(pipe_hnd, mem_ctx, &user_pol);
676 if (!NT_STATUS_IS_OK(result)) {
677 d_fprintf(stderr, "Failed to delete user %s - %s\n",
678 acct_name, nt_errstr(result));
685 if (!NT_STATUS_IS_OK(result)) {
686 d_fprintf(stderr, "Failed to add user '%s' with %s.\n",
687 acct_name, nt_errstr(result));
689 d_printf("Added user '%s'.\n", acct_name);
695 * Add a new user to a remote RPC server
697 * @param argc Standard main() style argc
698 * @param argv Standard main() style argv. Initial components are already
701 * @return A shell status integer (0 for success)
704 static int rpc_user_add(int argc, const char **argv)
706 return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_add_internals,
711 * Delete a user from a remote RPC server
713 * All parameters are provided by the run_rpc_command function, except for
714 * argc, argv which are passes through.
716 * @param domain_sid The domain sid acquired from the remote server
717 * @param cli A cli_state connected to the server.
718 * @param mem_ctx Talloc context, destoyed on completion of the function.
719 * @param argc Standard main() style argc
720 * @param argv Standard main() style argv. Initial components are already
723 * @return Normal NTSTATUS return.
726 static NTSTATUS rpc_user_del_internals(const DOM_SID *domain_sid,
727 const char *domain_name,
728 struct cli_state *cli,
729 struct rpc_pipe_client *pipe_hnd,
734 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
735 POLICY_HND connect_pol, domain_pol, user_pol;
736 const char *acct_name;
739 d_printf("User must be specified\n");
740 rpc_user_usage(argc, argv);
746 /* Get sam policy and domain handles */
748 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
751 if (!NT_STATUS_IS_OK(result)) {
755 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
756 MAXIMUM_ALLOWED_ACCESS,
757 domain_sid, &domain_pol);
759 if (!NT_STATUS_IS_OK(result)) {
763 /* Get handle on user */
766 uint32 *user_rids, num_rids, *name_types;
767 uint32 flags = 0x000003e8; /* Unknown */
769 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol,
770 flags, 1, &acct_name,
771 &num_rids, &user_rids,
774 if (!NT_STATUS_IS_OK(result)) {
778 result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
779 MAXIMUM_ALLOWED_ACCESS,
780 user_rids[0], &user_pol);
782 if (!NT_STATUS_IS_OK(result)) {
789 result = rpccli_samr_delete_dom_user(pipe_hnd, mem_ctx, &user_pol);
791 if (!NT_STATUS_IS_OK(result)) {
796 if (!NT_STATUS_IS_OK(result)) {
797 d_fprintf(stderr, "Failed to delete user '%s' with %s.\n",
798 acct_name, nt_errstr(result));
800 d_printf("Deleted user '%s'.\n", acct_name);
807 * Rename a user on a remote RPC server
809 * All parameters are provided by the run_rpc_command function, except for
810 * argc, argv which are passes through.
812 * @param domain_sid The domain sid acquired from the remote server
813 * @param cli A cli_state connected to the server.
814 * @param mem_ctx Talloc context, destoyed on completion of the function.
815 * @param argc Standard main() style argc
816 * @param argv Standard main() style argv. Initial components are already
819 * @return Normal NTSTATUS return.
822 static NTSTATUS rpc_user_rename_internals(const DOM_SID *domain_sid,
823 const char *domain_name,
824 struct cli_state *cli,
825 struct rpc_pipe_client *pipe_hnd,
830 POLICY_HND connect_pol, domain_pol, user_pol;
831 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
832 uint32 info_level = 7;
833 const char *old_name, *new_name;
835 uint32 flags = 0x000003e8; /* Unknown */
836 uint32 num_rids, *name_types;
837 uint32 num_names = 1;
839 SAM_USERINFO_CTR *user_ctr;
840 SAM_USERINFO_CTR ctr;
841 SAM_USER_INFO_7 info7;
844 d_printf("Old and new username must be specified\n");
845 rpc_user_usage(argc, argv);
853 ZERO_STRUCT(user_ctr);
855 /* Get sam policy handle */
857 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
859 if (!NT_STATUS_IS_OK(result)) {
863 /* Get domain policy handle */
865 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
866 MAXIMUM_ALLOWED_ACCESS,
867 domain_sid, &domain_pol);
868 if (!NT_STATUS_IS_OK(result)) {
872 if ((names = TALLOC_ARRAY(mem_ctx, const char *, num_names)) == NULL) {
873 result = NT_STATUS_NO_MEMORY;
877 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol,
878 flags, num_names, names,
879 &num_rids, &user_rid, &name_types);
880 if (!NT_STATUS_IS_OK(result)) {
884 /* Open domain user */
885 result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
886 MAXIMUM_ALLOWED_ACCESS, user_rid[0], &user_pol);
888 if (!NT_STATUS_IS_OK(result)) {
892 /* Query user info */
893 result = rpccli_samr_query_userinfo(pipe_hnd, mem_ctx, &user_pol,
894 info_level, &user_ctr);
896 if (!NT_STATUS_IS_OK(result)) {
900 ctr.switch_value = info_level;
901 ctr.info.id7 = &info7;
903 init_sam_user_info7(&info7, new_name);
906 result = rpccli_samr_set_userinfo(pipe_hnd, mem_ctx, &user_pol,
907 info_level, &cli->user_session_key, &ctr);
909 if (!NT_STATUS_IS_OK(result)) {
914 if (!NT_STATUS_IS_OK(result)) {
915 d_fprintf(stderr, "Failed to rename user from %s to %s - %s\n", old_name, new_name,
918 d_printf("Renamed user from %s to %s\n", old_name, new_name);
924 * Rename a user on a remote RPC server
926 * @param argc Standard main() style argc
927 * @param argv Standard main() style argv. Initial components are already
930 * @return A shell status integer (0 for success)
933 static int rpc_user_rename(int argc, const char **argv)
935 return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_rename_internals,
940 * Delete a user from a remote RPC server
942 * @param argc Standard main() style argc
943 * @param argv Standard main() style argv. Initial components are already
946 * @return A shell status integer (0 for success)
949 static int rpc_user_delete(int argc, const char **argv)
951 return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_del_internals,
956 * Set a password for a user on a remote RPC server
958 * All parameters are provided by the run_rpc_command function, except for
959 * argc, argv which are passes through.
961 * @param domain_sid The domain sid acquired from the remote server
962 * @param cli A cli_state connected to the server.
963 * @param mem_ctx Talloc context, destoyed on completion of the function.
964 * @param argc Standard main() style argc
965 * @param argv Standard main() style argv. Initial components are already
968 * @return Normal NTSTATUS return.
971 static NTSTATUS rpc_user_password_internals(const DOM_SID *domain_sid,
972 const char *domain_name,
973 struct cli_state *cli,
974 struct rpc_pipe_client *pipe_hnd,
979 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
980 POLICY_HND connect_pol, domain_pol, user_pol;
981 SAM_USERINFO_CTR ctr;
982 SAM_USER_INFO_24 p24;
985 const char *new_password;
989 d_printf("User must be specified\n");
990 rpc_user_usage(argc, argv);
997 new_password = argv[1];
999 asprintf(&prompt, "Enter new password for %s:", user);
1000 new_password = getpass(prompt);
1004 /* Get sam policy and domain handles */
1006 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1009 if (!NT_STATUS_IS_OK(result)) {
1013 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
1014 MAXIMUM_ALLOWED_ACCESS,
1015 domain_sid, &domain_pol);
1017 if (!NT_STATUS_IS_OK(result)) {
1021 /* Get handle on user */
1024 uint32 *user_rids, num_rids, *name_types;
1025 uint32 flags = 0x000003e8; /* Unknown */
1027 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol,
1029 &num_rids, &user_rids,
1032 if (!NT_STATUS_IS_OK(result)) {
1036 result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
1037 MAXIMUM_ALLOWED_ACCESS,
1038 user_rids[0], &user_pol);
1040 if (!NT_STATUS_IS_OK(result)) {
1045 /* Set password on account */
1050 encode_pw_buffer(pwbuf, new_password, STR_UNICODE);
1052 init_sam_user_info24(&p24, (char *)pwbuf,24);
1054 ctr.switch_value = 24;
1055 ctr.info.id24 = &p24;
1057 result = rpccli_samr_set_userinfo(pipe_hnd, mem_ctx, &user_pol, 24,
1058 &cli->user_session_key, &ctr);
1060 if (!NT_STATUS_IS_OK(result)) {
1064 /* Display results */
1072 * Set a user's password on a remote RPC server
1074 * @param argc Standard main() style argc
1075 * @param argv Standard main() style argv. Initial components are already
1078 * @return A shell status integer (0 for success)
1081 static int rpc_user_password(int argc, const char **argv)
1083 return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_password_internals,
1088 * List user's groups on a remote RPC server
1090 * All parameters are provided by the run_rpc_command function, except for
1091 * argc, argv which are passes through.
1093 * @param domain_sid The domain sid acquired from the remote server
1094 * @param cli A cli_state connected to the server.
1095 * @param mem_ctx Talloc context, destoyed on completion of the function.
1096 * @param argc Standard main() style argc
1097 * @param argv Standard main() style argv. Initial components are already
1100 * @return Normal NTSTATUS return.
1103 static NTSTATUS rpc_user_info_internals(const DOM_SID *domain_sid,
1104 const char *domain_name,
1105 struct cli_state *cli,
1106 struct rpc_pipe_client *pipe_hnd,
1107 TALLOC_CTX *mem_ctx,
1111 POLICY_HND connect_pol, domain_pol, user_pol;
1112 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1113 uint32 *rids, num_rids, *name_types, num_names;
1114 uint32 flags = 0x000003e8; /* Unknown */
1120 d_printf("User must be specified\n");
1121 rpc_user_usage(argc, argv);
1122 return NT_STATUS_OK;
1124 /* Get sam policy handle */
1126 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1128 if (!NT_STATUS_IS_OK(result)) goto done;
1130 /* Get domain policy handle */
1132 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
1133 MAXIMUM_ALLOWED_ACCESS,
1134 domain_sid, &domain_pol);
1135 if (!NT_STATUS_IS_OK(result)) goto done;
1137 /* Get handle on user */
1139 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol,
1141 &num_rids, &rids, &name_types);
1143 if (!NT_STATUS_IS_OK(result)) goto done;
1145 result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
1146 MAXIMUM_ALLOWED_ACCESS,
1147 rids[0], &user_pol);
1148 if (!NT_STATUS_IS_OK(result)) goto done;
1150 result = rpccli_samr_query_usergroups(pipe_hnd, mem_ctx, &user_pol,
1151 &num_rids, &user_gids);
1153 if (!NT_STATUS_IS_OK(result)) goto done;
1158 if ((rids = TALLOC_ARRAY(mem_ctx, uint32, num_rids)) == NULL) {
1159 result = NT_STATUS_NO_MEMORY;
1163 for (i = 0; i < num_rids; i++)
1164 rids[i] = user_gids[i].g_rid;
1166 result = rpccli_samr_lookup_rids(pipe_hnd, mem_ctx, &domain_pol,
1168 &num_names, &names, &name_types);
1170 if (!NT_STATUS_IS_OK(result)) {
1174 /* Display results */
1176 for (i = 0; i < num_names; i++)
1177 printf("%s\n", names[i]);
1184 * List a user's groups from a remote RPC server
1186 * @param argc Standard main() style argc
1187 * @param argv Standard main() style argv. Initial components are already
1190 * @return A shell status integer (0 for success)
1193 static int rpc_user_info(int argc, const char **argv)
1195 return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_info_internals,
1200 * List users on a remote RPC server
1202 * All parameters are provided by the run_rpc_command function, except for
1203 * argc, argv which are passes through.
1205 * @param domain_sid The domain sid acquired from the remote server
1206 * @param cli A cli_state connected to the server.
1207 * @param mem_ctx Talloc context, destoyed on completion of the function.
1208 * @param argc Standard main() style argc
1209 * @param argv Standard main() style argv. Initial components are already
1212 * @return Normal NTSTATUS return.
1215 static NTSTATUS rpc_user_list_internals(const DOM_SID *domain_sid,
1216 const char *domain_name,
1217 struct cli_state *cli,
1218 struct rpc_pipe_client *pipe_hnd,
1219 TALLOC_CTX *mem_ctx,
1223 POLICY_HND connect_pol, domain_pol;
1224 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1225 uint32 start_idx=0, num_entries, i, loop_count = 0;
1226 SAM_DISPINFO_CTR ctr;
1227 SAM_DISPINFO_1 info1;
1229 /* Get sam policy handle */
1231 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1233 if (!NT_STATUS_IS_OK(result)) {
1237 /* Get domain policy handle */
1239 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
1240 MAXIMUM_ALLOWED_ACCESS,
1241 domain_sid, &domain_pol);
1242 if (!NT_STATUS_IS_OK(result)) {
1246 /* Query domain users */
1249 ctr.sam.info1 = &info1;
1250 if (opt_long_list_entries)
1251 d_printf("\nUser name Comment"\
1252 "\n-----------------------------\n");
1255 uint32 max_entries, max_size;
1257 get_query_dispinfo_params(
1258 loop_count, &max_entries, &max_size);
1260 result = rpccli_samr_query_dispinfo(pipe_hnd, mem_ctx, &domain_pol,
1261 &start_idx, 1, &num_entries,
1262 max_entries, max_size, &ctr);
1265 for (i = 0; i < num_entries; i++) {
1266 unistr2_to_ascii(user, &(&ctr.sam.info1->str[i])->uni_acct_name, sizeof(user));
1267 if (opt_long_list_entries)
1268 unistr2_to_ascii(desc, &(&ctr.sam.info1->str[i])->uni_acct_desc, sizeof(desc));
1270 if (opt_long_list_entries)
1271 printf("%-21.21s %s\n", user, desc);
1273 printf("%s\n", user);
1275 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
1282 * 'net rpc user' entrypoint.
1283 * @param argc Standard main() style argc
1284 * @param argc Standard main() style argv. Initial components are already
1288 int net_rpc_user(int argc, const char **argv)
1290 struct functable func[] = {
1291 {"add", rpc_user_add},
1292 {"info", rpc_user_info},
1293 {"delete", rpc_user_delete},
1294 {"password", rpc_user_password},
1295 {"rename", rpc_user_rename},
1300 return run_rpc_command(NULL,PI_SAMR, 0,
1301 rpc_user_list_internals,
1305 return net_run_function(argc, argv, func, rpc_user_usage);
1308 static NTSTATUS rpc_sh_user_list(TALLOC_CTX *mem_ctx,
1309 struct rpc_sh_ctx *ctx,
1310 struct rpc_pipe_client *pipe_hnd,
1311 int argc, const char **argv)
1313 return rpc_user_list_internals(ctx->domain_sid, ctx->domain_name,
1314 ctx->cli, pipe_hnd, mem_ctx,
1318 static NTSTATUS rpc_sh_user_info(TALLOC_CTX *mem_ctx,
1319 struct rpc_sh_ctx *ctx,
1320 struct rpc_pipe_client *pipe_hnd,
1321 int argc, const char **argv)
1323 return rpc_user_info_internals(ctx->domain_sid, ctx->domain_name,
1324 ctx->cli, pipe_hnd, mem_ctx,
1328 static NTSTATUS rpc_sh_handle_user(TALLOC_CTX *mem_ctx,
1329 struct rpc_sh_ctx *ctx,
1330 struct rpc_pipe_client *pipe_hnd,
1331 int argc, const char **argv,
1333 TALLOC_CTX *mem_ctx,
1334 struct rpc_sh_ctx *ctx,
1335 struct rpc_pipe_client *pipe_hnd,
1336 const POLICY_HND *user_hnd,
1337 int argc, const char **argv))
1340 POLICY_HND connect_pol, domain_pol, user_pol;
1341 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1344 enum lsa_SidType type;
1347 d_fprintf(stderr, "usage: %s <username>\n", ctx->whoami);
1348 return NT_STATUS_INVALID_PARAMETER;
1351 ZERO_STRUCT(connect_pol);
1352 ZERO_STRUCT(domain_pol);
1353 ZERO_STRUCT(user_pol);
1355 result = net_rpc_lookup_name(mem_ctx, pipe_hnd->cli, argv[0],
1356 NULL, NULL, &sid, &type);
1357 if (!NT_STATUS_IS_OK(result)) {
1358 d_fprintf(stderr, "Could not lookup %s: %s\n", argv[0],
1363 if (type != SID_NAME_USER) {
1364 d_fprintf(stderr, "%s is a %s, not a user\n", argv[0],
1365 sid_type_lookup(type));
1366 result = NT_STATUS_NO_SUCH_USER;
1370 if (!sid_peek_check_rid(ctx->domain_sid, &sid, &rid)) {
1371 d_fprintf(stderr, "%s is not in our domain\n", argv[0]);
1372 result = NT_STATUS_NO_SUCH_USER;
1376 result = rpccli_samr_connect(pipe_hnd, mem_ctx,
1377 MAXIMUM_ALLOWED_ACCESS, &connect_pol);
1378 if (!NT_STATUS_IS_OK(result)) {
1382 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
1383 MAXIMUM_ALLOWED_ACCESS,
1384 ctx->domain_sid, &domain_pol);
1385 if (!NT_STATUS_IS_OK(result)) {
1389 result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
1390 MAXIMUM_ALLOWED_ACCESS,
1392 if (!NT_STATUS_IS_OK(result)) {
1396 result = fn(mem_ctx, ctx, pipe_hnd, &user_pol, argc-1, argv+1);
1399 if (is_valid_policy_hnd(&user_pol)) {
1400 rpccli_samr_close(pipe_hnd, mem_ctx, &user_pol);
1402 if (is_valid_policy_hnd(&domain_pol)) {
1403 rpccli_samr_close(pipe_hnd, mem_ctx, &domain_pol);
1405 if (is_valid_policy_hnd(&connect_pol)) {
1406 rpccli_samr_close(pipe_hnd, mem_ctx, &connect_pol);
1411 static NTSTATUS rpc_sh_user_show_internals(TALLOC_CTX *mem_ctx,
1412 struct rpc_sh_ctx *ctx,
1413 struct rpc_pipe_client *pipe_hnd,
1414 const POLICY_HND *user_hnd,
1415 int argc, const char **argv)
1418 SAM_USERINFO_CTR *ctr;
1419 SAM_USER_INFO_21 *info;
1422 d_fprintf(stderr, "usage: %s show <username>\n", ctx->whoami);
1423 return NT_STATUS_INVALID_PARAMETER;
1426 result = rpccli_samr_query_userinfo(pipe_hnd, mem_ctx, user_hnd,
1428 if (!NT_STATUS_IS_OK(result)) {
1432 info = ctr->info.id21;
1434 d_printf("user rid: %d, group rid: %d\n", info->user_rid,
1440 static NTSTATUS rpc_sh_user_show(TALLOC_CTX *mem_ctx,
1441 struct rpc_sh_ctx *ctx,
1442 struct rpc_pipe_client *pipe_hnd,
1443 int argc, const char **argv)
1445 return rpc_sh_handle_user(mem_ctx, ctx, pipe_hnd, argc, argv,
1446 rpc_sh_user_show_internals);
1449 #define FETCHSTR(name, rec) \
1450 do { if (strequal(ctx->thiscmd, name)) { \
1451 oldval = rpcstr_pull_unistr2_talloc(mem_ctx, &usr->uni_##rec); } \
1454 #define SETSTR(name, rec, flag) \
1455 do { if (strequal(ctx->thiscmd, name)) { \
1456 init_unistr2(&usr->uni_##rec, argv[0], UNI_STR_TERMINATE); \
1457 init_uni_hdr(&usr->hdr_##rec, &usr->uni_##rec); \
1458 usr->fields_present |= ACCT_##flag; } \
1461 static NTSTATUS rpc_sh_user_str_edit_internals(TALLOC_CTX *mem_ctx,
1462 struct rpc_sh_ctx *ctx,
1463 struct rpc_pipe_client *pipe_hnd,
1464 const POLICY_HND *user_hnd,
1465 int argc, const char **argv)
1468 SAM_USERINFO_CTR *ctr;
1469 SAM_USER_INFO_21 *usr;
1470 const char *username;
1471 const char *oldval = "";
1474 d_fprintf(stderr, "usage: %s <username> [new value|NULL]\n",
1476 return NT_STATUS_INVALID_PARAMETER;
1479 result = rpccli_samr_query_userinfo(pipe_hnd, mem_ctx, user_hnd,
1481 if (!NT_STATUS_IS_OK(result)) {
1485 usr = ctr->info.id21;
1487 username = rpcstr_pull_unistr2_talloc(mem_ctx, &usr->uni_user_name);
1489 FETCHSTR("fullname", full_name);
1490 FETCHSTR("homedir", home_dir);
1491 FETCHSTR("homedrive", dir_drive);
1492 FETCHSTR("logonscript", logon_script);
1493 FETCHSTR("profilepath", profile_path);
1494 FETCHSTR("description", acct_desc);
1497 d_printf("%s's %s: [%s]\n", username, ctx->thiscmd, oldval);
1503 if (strcmp(argv[0], "NULL") == 0) {
1507 SETSTR("fullname", full_name, FULL_NAME);
1508 SETSTR("homedir", home_dir, HOME_DIR);
1509 SETSTR("homedrive", dir_drive, HOME_DRIVE);
1510 SETSTR("logonscript", logon_script, LOGON_SCRIPT);
1511 SETSTR("profilepath", profile_path, PROFILE);
1512 SETSTR("description", acct_desc, DESCRIPTION);
1514 result = rpccli_samr_set_userinfo2(
1515 pipe_hnd, mem_ctx, user_hnd, 21,
1516 &pipe_hnd->cli->user_session_key, ctr);
1518 d_printf("Set %s's %s from [%s] to [%s]\n", username,
1519 ctx->thiscmd, oldval, argv[0]);
1526 #define HANDLEFLG(name, rec) \
1527 do { if (strequal(ctx->thiscmd, name)) { \
1528 oldval = (oldflags & ACB_##rec) ? "yes" : "no"; \
1530 newflags = oldflags | ACB_##rec; \
1532 newflags = oldflags & ~ACB_##rec; \
1535 static NTSTATUS rpc_sh_user_str_edit(TALLOC_CTX *mem_ctx,
1536 struct rpc_sh_ctx *ctx,
1537 struct rpc_pipe_client *pipe_hnd,
1538 int argc, const char **argv)
1540 return rpc_sh_handle_user(mem_ctx, ctx, pipe_hnd, argc, argv,
1541 rpc_sh_user_str_edit_internals);
1544 static NTSTATUS rpc_sh_user_flag_edit_internals(TALLOC_CTX *mem_ctx,
1545 struct rpc_sh_ctx *ctx,
1546 struct rpc_pipe_client *pipe_hnd,
1547 const POLICY_HND *user_hnd,
1548 int argc, const char **argv)
1551 SAM_USERINFO_CTR *ctr;
1552 SAM_USER_INFO_21 *usr;
1553 const char *username;
1554 const char *oldval = "unknown";
1555 uint32 oldflags, newflags;
1559 ((argc == 1) && !strequal(argv[0], "yes") &&
1560 !strequal(argv[0], "no"))) {
1561 d_fprintf(stderr, "usage: %s <username> [yes|no]\n",
1563 return NT_STATUS_INVALID_PARAMETER;
1566 newval = strequal(argv[0], "yes");
1568 result = rpccli_samr_query_userinfo(pipe_hnd, mem_ctx, user_hnd,
1570 if (!NT_STATUS_IS_OK(result)) {
1574 usr = ctr->info.id21;
1576 username = rpcstr_pull_unistr2_talloc(mem_ctx, &usr->uni_user_name);
1577 oldflags = usr->acb_info;
1578 newflags = usr->acb_info;
1580 HANDLEFLG("disabled", DISABLED);
1581 HANDLEFLG("pwnotreq", PWNOTREQ);
1582 HANDLEFLG("autolock", AUTOLOCK);
1583 HANDLEFLG("pwnoexp", PWNOEXP);
1586 d_printf("%s's %s flag: %s\n", username, ctx->thiscmd, oldval);
1592 usr->acb_info = newflags;
1593 usr->fields_present = ACCT_FLAGS;
1595 result = rpccli_samr_set_userinfo2(
1596 pipe_hnd, mem_ctx, user_hnd, 21,
1597 &pipe_hnd->cli->user_session_key, ctr);
1599 if (NT_STATUS_IS_OK(result)) {
1600 d_printf("Set %s's %s flag from [%s] to [%s]\n", username,
1601 ctx->thiscmd, oldval, argv[0]);
1609 static NTSTATUS rpc_sh_user_flag_edit(TALLOC_CTX *mem_ctx,
1610 struct rpc_sh_ctx *ctx,
1611 struct rpc_pipe_client *pipe_hnd,
1612 int argc, const char **argv)
1614 return rpc_sh_handle_user(mem_ctx, ctx, pipe_hnd, argc, argv,
1615 rpc_sh_user_flag_edit_internals);
1618 struct rpc_sh_cmd *net_rpc_user_edit_cmds(TALLOC_CTX *mem_ctx,
1619 struct rpc_sh_ctx *ctx)
1621 static struct rpc_sh_cmd cmds[] = {
1623 { "fullname", NULL, PI_SAMR, rpc_sh_user_str_edit,
1624 "Show/Set a user's full name" },
1626 { "homedir", NULL, PI_SAMR, rpc_sh_user_str_edit,
1627 "Show/Set a user's home directory" },
1629 { "homedrive", NULL, PI_SAMR, rpc_sh_user_str_edit,
1630 "Show/Set a user's home drive" },
1632 { "logonscript", NULL, PI_SAMR, rpc_sh_user_str_edit,
1633 "Show/Set a user's logon script" },
1635 { "profilepath", NULL, PI_SAMR, rpc_sh_user_str_edit,
1636 "Show/Set a user's profile path" },
1638 { "description", NULL, PI_SAMR, rpc_sh_user_str_edit,
1639 "Show/Set a user's description" },
1641 { "disabled", NULL, PI_SAMR, rpc_sh_user_flag_edit,
1642 "Show/Set whether a user is disabled" },
1644 { "autolock", NULL, PI_SAMR, rpc_sh_user_flag_edit,
1645 "Show/Set whether a user locked out" },
1647 { "pwnotreq", NULL, PI_SAMR, rpc_sh_user_flag_edit,
1648 "Show/Set whether a user does not need a password" },
1650 { "pwnoexp", NULL, PI_SAMR, rpc_sh_user_flag_edit,
1651 "Show/Set whether a user's password does not expire" },
1653 { NULL, NULL, 0, NULL, NULL }
1659 struct rpc_sh_cmd *net_rpc_user_cmds(TALLOC_CTX *mem_ctx,
1660 struct rpc_sh_ctx *ctx)
1662 static struct rpc_sh_cmd cmds[] = {
1664 { "list", NULL, PI_SAMR, rpc_sh_user_list,
1665 "List available users" },
1667 { "info", NULL, PI_SAMR, rpc_sh_user_info,
1668 "List the domain groups a user is member of" },
1670 { "show", NULL, PI_SAMR, rpc_sh_user_show,
1671 "Show info about a user" },
1673 { "edit", net_rpc_user_edit_cmds, 0, NULL,
1674 "Show/Modify a user's fields" },
1676 { NULL, NULL, 0, NULL, NULL }
1682 /****************************************************************************/
1685 * Basic usage function for 'net rpc group'
1686 * @param argc Standard main() style argc.
1687 * @param argv Standard main() style argv. Initial components are already
1691 static int rpc_group_usage(int argc, const char **argv)
1693 return net_help_group(argc, argv);
1697 * Delete group on a remote RPC server
1699 * All parameters are provided by the run_rpc_command function, except for
1700 * argc, argv which are passes through.
1702 * @param domain_sid The domain sid acquired from the remote server
1703 * @param cli A cli_state connected to the server.
1704 * @param mem_ctx Talloc context, destoyed on completion of the function.
1705 * @param argc Standard main() style argc
1706 * @param argv Standard main() style argv. Initial components are already
1709 * @return Normal NTSTATUS return.
1712 static NTSTATUS rpc_group_delete_internals(const DOM_SID *domain_sid,
1713 const char *domain_name,
1714 struct cli_state *cli,
1715 struct rpc_pipe_client *pipe_hnd,
1716 TALLOC_CTX *mem_ctx,
1720 POLICY_HND connect_pol, domain_pol, group_pol, user_pol;
1721 bool group_is_primary = False;
1722 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1724 uint32 *group_rids, num_rids, *name_types, num_members,
1725 *group_attrs, group_rid;
1726 uint32 flags = 0x000003e8; /* Unknown */
1729 /* DOM_GID *user_gids; */
1730 SAM_USERINFO_CTR *user_ctr;
1734 d_printf("specify group\n");
1735 rpc_group_usage(argc,argv);
1736 return NT_STATUS_OK; /* ok? */
1739 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1742 if (!NT_STATUS_IS_OK(result)) {
1743 d_fprintf(stderr, "Request samr_connect failed\n");
1747 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
1748 MAXIMUM_ALLOWED_ACCESS,
1749 domain_sid, &domain_pol);
1751 if (!NT_STATUS_IS_OK(result)) {
1752 d_fprintf(stderr, "Request open_domain failed\n");
1756 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol,
1758 &num_rids, &group_rids,
1761 if (!NT_STATUS_IS_OK(result)) {
1762 d_fprintf(stderr, "Lookup of '%s' failed\n",argv[0]);
1766 switch (name_types[0])
1768 case SID_NAME_DOM_GRP:
1769 result = rpccli_samr_open_group(pipe_hnd, mem_ctx, &domain_pol,
1770 MAXIMUM_ALLOWED_ACCESS,
1771 group_rids[0], &group_pol);
1772 if (!NT_STATUS_IS_OK(result)) {
1773 d_fprintf(stderr, "Request open_group failed");
1777 group_rid = group_rids[0];
1779 result = rpccli_samr_query_groupmem(pipe_hnd, mem_ctx, &group_pol,
1780 &num_members, &group_rids,
1783 if (!NT_STATUS_IS_OK(result)) {
1784 d_fprintf(stderr, "Unable to query group members of %s",argv[0]);
1789 d_printf("Domain Group %s (rid: %d) has %d members\n",
1790 argv[0],group_rid,num_members);
1793 /* Check if group is anyone's primary group */
1794 for (i = 0; i < num_members; i++)
1796 result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
1797 MAXIMUM_ALLOWED_ACCESS,
1798 group_rids[i], &user_pol);
1800 if (!NT_STATUS_IS_OK(result)) {
1801 d_fprintf(stderr, "Unable to open group member %d\n",group_rids[i]);
1805 ZERO_STRUCT(user_ctr);
1807 result = rpccli_samr_query_userinfo(pipe_hnd, mem_ctx, &user_pol,
1810 if (!NT_STATUS_IS_OK(result)) {
1811 d_fprintf(stderr, "Unable to lookup userinfo for group member %d\n",group_rids[i]);
1815 if (user_ctr->info.id21->group_rid == group_rid) {
1816 unistr2_to_ascii(temp, &(user_ctr->info.id21)->uni_user_name,
1819 d_printf("Group is primary group of %s\n",temp);
1820 group_is_primary = True;
1823 rpccli_samr_close(pipe_hnd, mem_ctx, &user_pol);
1826 if (group_is_primary) {
1827 d_fprintf(stderr, "Unable to delete group because some "
1828 "of it's members have it as primary group\n");
1829 result = NT_STATUS_MEMBERS_PRIMARY_GROUP;
1833 /* remove all group members */
1834 for (i = 0; i < num_members; i++)
1837 d_printf("Remove group member %d...",group_rids[i]);
1838 result = rpccli_samr_del_groupmem(pipe_hnd, mem_ctx, &group_pol, group_rids[i]);
1840 if (NT_STATUS_IS_OK(result)) {
1845 d_printf("failed\n");
1850 result = rpccli_samr_delete_dom_group(pipe_hnd, mem_ctx, &group_pol);
1853 /* removing a local group is easier... */
1854 case SID_NAME_ALIAS:
1855 result = rpccli_samr_open_alias(pipe_hnd, mem_ctx, &domain_pol,
1856 MAXIMUM_ALLOWED_ACCESS,
1857 group_rids[0], &group_pol);
1859 if (!NT_STATUS_IS_OK(result)) {
1860 d_fprintf(stderr, "Request open_alias failed\n");
1864 result = rpccli_samr_delete_dom_alias(pipe_hnd, mem_ctx, &group_pol);
1867 d_fprintf(stderr, "%s is of type %s. This command is only for deleting local or global groups\n",
1868 argv[0],sid_type_lookup(name_types[0]));
1869 result = NT_STATUS_UNSUCCESSFUL;
1874 if (NT_STATUS_IS_OK(result)) {
1876 d_printf("Deleted %s '%s'\n",sid_type_lookup(name_types[0]),argv[0]);
1878 d_fprintf(stderr, "Deleting of %s failed: %s\n",argv[0],
1879 get_friendly_nt_error_msg(result));
1887 static int rpc_group_delete(int argc, const char **argv)
1889 return run_rpc_command(NULL, PI_SAMR, 0, rpc_group_delete_internals,
1893 static NTSTATUS rpc_group_add_internals(const DOM_SID *domain_sid,
1894 const char *domain_name,
1895 struct cli_state *cli,
1896 struct rpc_pipe_client *pipe_hnd,
1897 TALLOC_CTX *mem_ctx,
1901 POLICY_HND connect_pol, domain_pol, group_pol;
1902 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1903 GROUP_INFO_CTR group_info;
1906 d_printf("Group name must be specified\n");
1907 rpc_group_usage(argc, argv);
1908 return NT_STATUS_OK;
1911 /* Get sam policy handle */
1913 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1915 if (!NT_STATUS_IS_OK(result)) goto done;
1917 /* Get domain policy handle */
1919 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
1920 MAXIMUM_ALLOWED_ACCESS,
1921 domain_sid, &domain_pol);
1922 if (!NT_STATUS_IS_OK(result)) goto done;
1924 /* Create the group */
1926 result = rpccli_samr_create_dom_group(pipe_hnd, mem_ctx, &domain_pol,
1927 argv[0], MAXIMUM_ALLOWED_ACCESS,
1929 if (!NT_STATUS_IS_OK(result)) goto done;
1931 if (strlen(opt_comment) == 0) goto done;
1933 /* We've got a comment to set */
1935 group_info.switch_value1 = 4;
1936 init_samr_group_info4(&group_info.group.info4, opt_comment);
1938 result = rpccli_samr_set_groupinfo(pipe_hnd, mem_ctx, &group_pol, &group_info);
1939 if (!NT_STATUS_IS_OK(result)) goto done;
1942 if (NT_STATUS_IS_OK(result))
1943 DEBUG(5, ("add group succeeded\n"));
1945 d_fprintf(stderr, "add group failed: %s\n", nt_errstr(result));
1950 static NTSTATUS rpc_alias_add_internals(const DOM_SID *domain_sid,
1951 const char *domain_name,
1952 struct cli_state *cli,
1953 struct rpc_pipe_client *pipe_hnd,
1954 TALLOC_CTX *mem_ctx,
1958 POLICY_HND connect_pol, domain_pol, alias_pol;
1959 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1960 ALIAS_INFO_CTR alias_info;
1963 d_printf("Alias name must be specified\n");
1964 rpc_group_usage(argc, argv);
1965 return NT_STATUS_OK;
1968 /* Get sam policy handle */
1970 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1972 if (!NT_STATUS_IS_OK(result)) goto done;
1974 /* Get domain policy handle */
1976 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
1977 MAXIMUM_ALLOWED_ACCESS,
1978 domain_sid, &domain_pol);
1979 if (!NT_STATUS_IS_OK(result)) goto done;
1981 /* Create the group */
1983 result = rpccli_samr_create_dom_alias(pipe_hnd, mem_ctx, &domain_pol,
1984 argv[0], &alias_pol);
1985 if (!NT_STATUS_IS_OK(result)) goto done;
1987 if (strlen(opt_comment) == 0) goto done;
1989 /* We've got a comment to set */
1991 alias_info.level = 3;
1992 init_samr_alias_info3(&alias_info.alias.info3, opt_comment);
1994 result = rpccli_samr_set_aliasinfo(pipe_hnd, mem_ctx, &alias_pol, &alias_info);
1995 if (!NT_STATUS_IS_OK(result)) goto done;
1998 if (NT_STATUS_IS_OK(result))
1999 DEBUG(5, ("add alias succeeded\n"));
2001 d_fprintf(stderr, "add alias failed: %s\n", nt_errstr(result));
2006 static int rpc_group_add(int argc, const char **argv)
2009 return run_rpc_command(NULL, PI_SAMR, 0,
2010 rpc_alias_add_internals,
2013 return run_rpc_command(NULL, PI_SAMR, 0,
2014 rpc_group_add_internals,
2018 static NTSTATUS get_sid_from_name(struct cli_state *cli,
2019 TALLOC_CTX *mem_ctx,
2022 enum lsa_SidType *type)
2024 DOM_SID *sids = NULL;
2025 enum lsa_SidType *types = NULL;
2026 struct rpc_pipe_client *pipe_hnd;
2028 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2030 pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_LSARPC, &result);
2035 result = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, False,
2036 SEC_RIGHTS_MAXIMUM_ALLOWED, &lsa_pol);
2038 if (!NT_STATUS_IS_OK(result)) {
2042 result = rpccli_lsa_lookup_names(pipe_hnd, mem_ctx, &lsa_pol, 1,
2043 &name, NULL, 1, &sids, &types);
2045 if (NT_STATUS_IS_OK(result)) {
2046 sid_copy(sid, &sids[0]);
2050 rpccli_lsa_Close(pipe_hnd, mem_ctx, &lsa_pol);
2054 cli_rpc_pipe_close(pipe_hnd);
2057 if (!NT_STATUS_IS_OK(result) && (StrnCaseCmp(name, "S-", 2) == 0)) {
2059 /* Try as S-1-5-whatever */
2063 if (string_to_sid(&tmp_sid, name)) {
2064 sid_copy(sid, &tmp_sid);
2065 *type = SID_NAME_UNKNOWN;
2066 result = NT_STATUS_OK;
2073 static NTSTATUS rpc_add_groupmem(struct rpc_pipe_client *pipe_hnd,
2074 TALLOC_CTX *mem_ctx,
2075 const DOM_SID *group_sid,
2078 POLICY_HND connect_pol, domain_pol;
2081 POLICY_HND group_pol;
2084 uint32 *rids = NULL;
2085 uint32 *rid_types = NULL;
2089 sid_copy(&sid, group_sid);
2091 if (!sid_split_rid(&sid, &group_rid)) {
2092 return NT_STATUS_UNSUCCESSFUL;
2095 /* Get sam policy handle */
2096 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
2098 if (!NT_STATUS_IS_OK(result)) {
2102 /* Get domain policy handle */
2103 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
2104 MAXIMUM_ALLOWED_ACCESS,
2106 if (!NT_STATUS_IS_OK(result)) {
2110 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, 1000,
2112 &num_rids, &rids, &rid_types);
2114 if (!NT_STATUS_IS_OK(result)) {
2115 d_fprintf(stderr, "Could not lookup up group member %s\n", member);
2119 result = rpccli_samr_open_group(pipe_hnd, mem_ctx, &domain_pol,
2120 MAXIMUM_ALLOWED_ACCESS,
2121 group_rid, &group_pol);
2123 if (!NT_STATUS_IS_OK(result)) {
2127 result = rpccli_samr_add_groupmem(pipe_hnd, mem_ctx, &group_pol, rids[0]);
2130 rpccli_samr_close(pipe_hnd, mem_ctx, &connect_pol);
2134 static NTSTATUS rpc_add_aliasmem(struct rpc_pipe_client *pipe_hnd,
2135 TALLOC_CTX *mem_ctx,
2136 const DOM_SID *alias_sid,
2139 POLICY_HND connect_pol, domain_pol;
2142 POLICY_HND alias_pol;
2145 enum lsa_SidType member_type;
2149 sid_copy(&sid, alias_sid);
2151 if (!sid_split_rid(&sid, &alias_rid)) {
2152 return NT_STATUS_UNSUCCESSFUL;
2155 result = get_sid_from_name(pipe_hnd->cli, mem_ctx, member,
2156 &member_sid, &member_type);
2158 if (!NT_STATUS_IS_OK(result)) {
2159 d_fprintf(stderr, "Could not lookup up group member %s\n", member);
2163 /* Get sam policy handle */
2164 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
2166 if (!NT_STATUS_IS_OK(result)) {
2170 /* Get domain policy handle */
2171 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
2172 MAXIMUM_ALLOWED_ACCESS,
2174 if (!NT_STATUS_IS_OK(result)) {
2178 result = rpccli_samr_open_alias(pipe_hnd, mem_ctx, &domain_pol,
2179 MAXIMUM_ALLOWED_ACCESS,
2180 alias_rid, &alias_pol);
2182 if (!NT_STATUS_IS_OK(result)) {
2186 result = rpccli_samr_add_aliasmem(pipe_hnd, mem_ctx, &alias_pol, &member_sid);
2188 if (!NT_STATUS_IS_OK(result)) {
2193 rpccli_samr_close(pipe_hnd, mem_ctx, &connect_pol);
2197 static NTSTATUS rpc_group_addmem_internals(const DOM_SID *domain_sid,
2198 const char *domain_name,
2199 struct cli_state *cli,
2200 struct rpc_pipe_client *pipe_hnd,
2201 TALLOC_CTX *mem_ctx,
2206 enum lsa_SidType group_type;
2209 d_printf("Usage: 'net rpc group addmem <group> <member>\n");
2210 return NT_STATUS_UNSUCCESSFUL;
2213 if (!NT_STATUS_IS_OK(get_sid_from_name(cli, mem_ctx, argv[0],
2214 &group_sid, &group_type))) {
2215 d_fprintf(stderr, "Could not lookup group name %s\n", argv[0]);
2216 return NT_STATUS_UNSUCCESSFUL;
2219 if (group_type == SID_NAME_DOM_GRP) {
2220 NTSTATUS result = rpc_add_groupmem(pipe_hnd, mem_ctx,
2221 &group_sid, argv[1]);
2223 if (!NT_STATUS_IS_OK(result)) {
2224 d_fprintf(stderr, "Could not add %s to %s: %s\n",
2225 argv[1], argv[0], nt_errstr(result));
2230 if (group_type == SID_NAME_ALIAS) {
2231 NTSTATUS result = rpc_add_aliasmem(pipe_hnd, mem_ctx,
2232 &group_sid, argv[1]);
2234 if (!NT_STATUS_IS_OK(result)) {
2235 d_fprintf(stderr, "Could not add %s to %s: %s\n",
2236 argv[1], argv[0], nt_errstr(result));
2241 d_fprintf(stderr, "Can only add members to global or local groups "
2242 "which %s is not\n", argv[0]);
2244 return NT_STATUS_UNSUCCESSFUL;
2247 static int rpc_group_addmem(int argc, const char **argv)
2249 return run_rpc_command(NULL, PI_SAMR, 0,
2250 rpc_group_addmem_internals,
2254 static NTSTATUS rpc_del_groupmem(struct rpc_pipe_client *pipe_hnd,
2255 TALLOC_CTX *mem_ctx,
2256 const DOM_SID *group_sid,
2259 POLICY_HND connect_pol, domain_pol;
2262 POLICY_HND group_pol;
2265 uint32 *rids = NULL;
2266 uint32 *rid_types = NULL;
2270 sid_copy(&sid, group_sid);
2272 if (!sid_split_rid(&sid, &group_rid))
2273 return NT_STATUS_UNSUCCESSFUL;
2275 /* Get sam policy handle */
2276 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
2278 if (!NT_STATUS_IS_OK(result))
2281 /* Get domain policy handle */
2282 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
2283 MAXIMUM_ALLOWED_ACCESS,
2285 if (!NT_STATUS_IS_OK(result))
2288 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, 1000,
2290 &num_rids, &rids, &rid_types);
2292 if (!NT_STATUS_IS_OK(result)) {
2293 d_fprintf(stderr, "Could not lookup up group member %s\n", member);
2297 result = rpccli_samr_open_group(pipe_hnd, mem_ctx, &domain_pol,
2298 MAXIMUM_ALLOWED_ACCESS,
2299 group_rid, &group_pol);
2301 if (!NT_STATUS_IS_OK(result))
2304 result = rpccli_samr_del_groupmem(pipe_hnd, mem_ctx, &group_pol, rids[0]);
2307 rpccli_samr_close(pipe_hnd, mem_ctx, &connect_pol);
2311 static NTSTATUS rpc_del_aliasmem(struct rpc_pipe_client *pipe_hnd,
2312 TALLOC_CTX *mem_ctx,
2313 const DOM_SID *alias_sid,
2316 POLICY_HND connect_pol, domain_pol;
2319 POLICY_HND alias_pol;
2322 enum lsa_SidType member_type;
2326 sid_copy(&sid, alias_sid);
2328 if (!sid_split_rid(&sid, &alias_rid))
2329 return NT_STATUS_UNSUCCESSFUL;
2331 result = get_sid_from_name(pipe_hnd->cli, mem_ctx, member,
2332 &member_sid, &member_type);
2334 if (!NT_STATUS_IS_OK(result)) {
2335 d_fprintf(stderr, "Could not lookup up group member %s\n", member);
2339 /* Get sam policy handle */
2340 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
2342 if (!NT_STATUS_IS_OK(result)) {
2346 /* Get domain policy handle */
2347 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
2348 MAXIMUM_ALLOWED_ACCESS,
2350 if (!NT_STATUS_IS_OK(result)) {
2354 result = rpccli_samr_open_alias(pipe_hnd, mem_ctx, &domain_pol,
2355 MAXIMUM_ALLOWED_ACCESS,
2356 alias_rid, &alias_pol);
2358 if (!NT_STATUS_IS_OK(result))
2361 result = rpccli_samr_del_aliasmem(pipe_hnd, mem_ctx, &alias_pol, &member_sid);
2363 if (!NT_STATUS_IS_OK(result))
2367 rpccli_samr_close(pipe_hnd, mem_ctx, &connect_pol);
2371 static NTSTATUS rpc_group_delmem_internals(const DOM_SID *domain_sid,
2372 const char *domain_name,
2373 struct cli_state *cli,
2374 struct rpc_pipe_client *pipe_hnd,
2375 TALLOC_CTX *mem_ctx,
2380 enum lsa_SidType group_type;
2383 d_printf("Usage: 'net rpc group delmem <group> <member>\n");
2384 return NT_STATUS_UNSUCCESSFUL;
2387 if (!NT_STATUS_IS_OK(get_sid_from_name(cli, mem_ctx, argv[0],
2388 &group_sid, &group_type))) {
2389 d_fprintf(stderr, "Could not lookup group name %s\n", argv[0]);
2390 return NT_STATUS_UNSUCCESSFUL;
2393 if (group_type == SID_NAME_DOM_GRP) {
2394 NTSTATUS result = rpc_del_groupmem(pipe_hnd, mem_ctx,
2395 &group_sid, argv[1]);
2397 if (!NT_STATUS_IS_OK(result)) {
2398 d_fprintf(stderr, "Could not del %s from %s: %s\n",
2399 argv[1], argv[0], nt_errstr(result));
2404 if (group_type == SID_NAME_ALIAS) {
2405 NTSTATUS result = rpc_del_aliasmem(pipe_hnd, mem_ctx,
2406 &group_sid, argv[1]);
2408 if (!NT_STATUS_IS_OK(result)) {
2409 d_fprintf(stderr, "Could not del %s from %s: %s\n",
2410 argv[1], argv[0], nt_errstr(result));
2415 d_fprintf(stderr, "Can only delete members from global or local groups "
2416 "which %s is not\n", argv[0]);
2418 return NT_STATUS_UNSUCCESSFUL;
2421 static int rpc_group_delmem(int argc, const char **argv)
2423 return run_rpc_command(NULL, PI_SAMR, 0,
2424 rpc_group_delmem_internals,
2429 * List groups on a remote RPC server
2431 * All parameters are provided by the run_rpc_command function, except for
2432 * argc, argv which are passes through.
2434 * @param domain_sid The domain sid acquired from the remote server
2435 * @param cli A cli_state connected to the server.
2436 * @param mem_ctx Talloc context, destoyed on completion of the function.
2437 * @param argc Standard main() style argc
2438 * @param argv Standard main() style argv. Initial components are already
2441 * @return Normal NTSTATUS return.
2444 static NTSTATUS rpc_group_list_internals(const DOM_SID *domain_sid,
2445 const char *domain_name,
2446 struct cli_state *cli,
2447 struct rpc_pipe_client *pipe_hnd,
2448 TALLOC_CTX *mem_ctx,
2452 POLICY_HND connect_pol, domain_pol;
2453 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2454 uint32 start_idx=0, max_entries=250, num_entries, i, loop_count = 0;
2455 struct acct_info *groups;
2456 bool global = False;
2458 bool builtin = False;
2466 for (i=0; i<argc; i++) {
2467 if (strequal(argv[i], "global"))
2470 if (strequal(argv[i], "local"))
2473 if (strequal(argv[i], "builtin"))
2477 /* Get sam policy handle */
2479 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
2481 if (!NT_STATUS_IS_OK(result)) {
2485 /* Get domain policy handle */
2487 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
2488 MAXIMUM_ALLOWED_ACCESS,
2489 domain_sid, &domain_pol);
2490 if (!NT_STATUS_IS_OK(result)) {
2494 /* Query domain groups */
2495 if (opt_long_list_entries)
2496 d_printf("\nGroup name Comment"\
2497 "\n-----------------------------\n");
2499 SAM_DISPINFO_CTR ctr;
2500 SAM_DISPINFO_3 info3;
2505 ctr.sam.info3 = &info3;
2509 get_query_dispinfo_params(
2510 loop_count, &max_entries, &max_size);
2512 result = rpccli_samr_query_dispinfo(pipe_hnd, mem_ctx, &domain_pol,
2513 &start_idx, 3, &num_entries,
2514 max_entries, max_size, &ctr);
2516 if (!NT_STATUS_IS_OK(result) &&
2517 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
2520 for (i = 0; i < num_entries; i++) {
2522 fstring group, desc;
2524 unistr2_to_ascii(group, &(&ctr.sam.info3->str[i])->uni_grp_name, sizeof(group));
2525 unistr2_to_ascii(desc, &(&ctr.sam.info3->str[i])->uni_grp_desc, sizeof(desc));
2527 if (opt_long_list_entries)
2528 printf("%-21.21s %-50.50s\n",
2531 printf("%s\n", group);
2533 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
2534 /* query domain aliases */
2539 /* The max_size field in cli_samr_enum_als_groups is more like
2540 * an account_control field with indiviual bits what to
2541 * retrieve. Set this to 0xffff as NT4 usrmgr.exe does to get
2542 * everything. I'm too lazy (sorry) to get this through to
2543 * rpc_parse/ etc. Volker */
2545 result = rpccli_samr_enum_als_groups(pipe_hnd, mem_ctx, &domain_pol,
2547 &groups, &num_entries);
2549 if (!NT_STATUS_IS_OK(result) &&
2550 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
2553 for (i = 0; i < num_entries; i++) {
2555 char *description = NULL;
2557 if (opt_long_list_entries) {
2559 POLICY_HND alias_pol;
2562 if ((NT_STATUS_IS_OK(rpccli_samr_open_alias(pipe_hnd, mem_ctx,
2567 (NT_STATUS_IS_OK(rpccli_samr_query_alias_info(pipe_hnd, mem_ctx,
2570 (NT_STATUS_IS_OK(rpccli_samr_close(pipe_hnd, mem_ctx,
2572 description = unistr2_to_ascii_talloc(mem_ctx,
2573 ctr.alias.info3.description.string);
2577 if (description != NULL) {
2578 printf("%-21.21s %-50.50s\n",
2579 groups[i].acct_name,
2582 printf("%s\n", groups[i].acct_name);
2585 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
2586 rpccli_samr_close(pipe_hnd, mem_ctx, &domain_pol);
2587 /* Get builtin policy handle */
2589 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
2590 MAXIMUM_ALLOWED_ACCESS,
2591 &global_sid_Builtin, &domain_pol);
2592 if (!NT_STATUS_IS_OK(result)) {
2595 /* query builtin aliases */
2598 if (!builtin) break;
2600 result = rpccli_samr_enum_als_groups(pipe_hnd, mem_ctx, &domain_pol,
2601 &start_idx, max_entries,
2602 &groups, &num_entries);
2604 if (!NT_STATUS_IS_OK(result) &&
2605 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
2608 for (i = 0; i < num_entries; i++) {
2610 char *description = NULL;
2612 if (opt_long_list_entries) {
2614 POLICY_HND alias_pol;
2617 if ((NT_STATUS_IS_OK(rpccli_samr_open_alias(pipe_hnd, mem_ctx,
2622 (NT_STATUS_IS_OK(rpccli_samr_query_alias_info(pipe_hnd, mem_ctx,
2625 (NT_STATUS_IS_OK(rpccli_samr_close(pipe_hnd, mem_ctx,
2627 description = unistr2_to_ascii_talloc(mem_ctx,
2628 ctr.alias.info3.description.string);
2632 if (description != NULL) {
2633 printf("%-21.21s %-50.50s\n",
2634 groups[i].acct_name,
2637 printf("%s\n", groups[i].acct_name);
2640 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
2646 static int rpc_group_list(int argc, const char **argv)
2648 return run_rpc_command(NULL, PI_SAMR, 0,
2649 rpc_group_list_internals,
2653 static NTSTATUS rpc_list_group_members(struct rpc_pipe_client *pipe_hnd,
2654 TALLOC_CTX *mem_ctx,
2655 const char *domain_name,
2656 const DOM_SID *domain_sid,
2657 POLICY_HND *domain_pol,
2661 POLICY_HND group_pol;
2662 uint32 num_members, *group_rids, *group_attrs;
2669 sid_to_fstring(sid_str, domain_sid);
2671 result = rpccli_samr_open_group(pipe_hnd, mem_ctx, domain_pol,
2672 MAXIMUM_ALLOWED_ACCESS,
2675 if (!NT_STATUS_IS_OK(result))
2678 result = rpccli_samr_query_groupmem(pipe_hnd, mem_ctx, &group_pol,
2679 &num_members, &group_rids,
2682 if (!NT_STATUS_IS_OK(result))
2685 while (num_members > 0) {
2686 int this_time = 512;
2688 if (num_members < this_time)
2689 this_time = num_members;
2691 result = rpccli_samr_lookup_rids(pipe_hnd, mem_ctx, domain_pol,
2692 this_time, group_rids,
2693 &num_names, &names, &name_types);
2695 if (!NT_STATUS_IS_OK(result))
2698 /* We only have users as members, but make the output
2699 the same as the output of alias members */
2701 for (i = 0; i < this_time; i++) {
2703 if (opt_long_list_entries) {
2704 printf("%s-%d %s\\%s %d\n", sid_str,
2705 group_rids[i], domain_name, names[i],
2708 printf("%s\\%s\n", domain_name, names[i]);
2712 num_members -= this_time;
2716 return NT_STATUS_OK;
2719 static NTSTATUS rpc_list_alias_members(struct rpc_pipe_client *pipe_hnd,
2720 TALLOC_CTX *mem_ctx,
2721 POLICY_HND *domain_pol,
2725 struct rpc_pipe_client *lsa_pipe;
2726 POLICY_HND alias_pol, lsa_pol;
2728 DOM_SID *alias_sids;
2731 enum lsa_SidType *types;
2734 result = rpccli_samr_open_alias(pipe_hnd, mem_ctx, domain_pol,
2735 MAXIMUM_ALLOWED_ACCESS, rid, &alias_pol);
2737 if (!NT_STATUS_IS_OK(result))
2740 result = rpccli_samr_query_aliasmem(pipe_hnd, mem_ctx, &alias_pol,
2741 &num_members, &alias_sids);
2743 if (!NT_STATUS_IS_OK(result)) {
2744 d_fprintf(stderr, "Couldn't list alias members\n");
2748 if (num_members == 0) {
2749 return NT_STATUS_OK;
2752 lsa_pipe = cli_rpc_pipe_open_noauth(pipe_hnd->cli, PI_LSARPC, &result);
2754 d_fprintf(stderr, "Couldn't open LSA pipe. Error was %s\n",
2755 nt_errstr(result) );
2759 result = rpccli_lsa_open_policy(lsa_pipe, mem_ctx, True,
2760 SEC_RIGHTS_MAXIMUM_ALLOWED, &lsa_pol);
2762 if (!NT_STATUS_IS_OK(result)) {
2763 d_fprintf(stderr, "Couldn't open LSA policy handle\n");
2764 cli_rpc_pipe_close(lsa_pipe);
2768 result = rpccli_lsa_lookup_sids(lsa_pipe, mem_ctx, &lsa_pol, num_members,
2770 &domains, &names, &types);
2772 if (!NT_STATUS_IS_OK(result) &&
2773 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
2774 d_fprintf(stderr, "Couldn't lookup SIDs\n");
2775 cli_rpc_pipe_close(lsa_pipe);
2779 for (i = 0; i < num_members; i++) {
2781 sid_to_fstring(sid_str, &alias_sids[i]);
2783 if (opt_long_list_entries) {
2784 printf("%s %s\\%s %d\n", sid_str,
2785 domains[i] ? domains[i] : "*unknown*",
2786 names[i] ? names[i] : "*unknown*", types[i]);
2789 printf("%s\\%s\n", domains[i], names[i]);
2791 printf("%s\n", sid_str);
2795 cli_rpc_pipe_close(lsa_pipe);
2796 return NT_STATUS_OK;
2799 static NTSTATUS rpc_group_members_internals(const DOM_SID *domain_sid,
2800 const char *domain_name,
2801 struct cli_state *cli,
2802 struct rpc_pipe_client *pipe_hnd,
2803 TALLOC_CTX *mem_ctx,
2808 POLICY_HND connect_pol, domain_pol;
2809 uint32 num_rids, *rids, *rid_types;
2811 /* Get sam policy handle */
2813 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
2816 if (!NT_STATUS_IS_OK(result))
2819 /* Get domain policy handle */
2821 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
2822 MAXIMUM_ALLOWED_ACCESS,
2823 domain_sid, &domain_pol);
2825 if (!NT_STATUS_IS_OK(result))
2828 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, 1000,
2829 1, argv, &num_rids, &rids, &rid_types);
2831 if (!NT_STATUS_IS_OK(result)) {
2833 /* Ok, did not find it in the global sam, try with builtin */
2835 DOM_SID sid_Builtin;
2837 rpccli_samr_close(pipe_hnd, mem_ctx, &domain_pol);
2839 string_to_sid(&sid_Builtin, "S-1-5-32");
2841 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
2842 MAXIMUM_ALLOWED_ACCESS,
2843 &sid_Builtin, &domain_pol);
2845 if (!NT_STATUS_IS_OK(result)) {
2846 d_fprintf(stderr, "Couldn't find group %s\n", argv[0]);
2850 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, 1000,
2854 if (!NT_STATUS_IS_OK(result)) {
2855 d_fprintf(stderr, "Couldn't find group %s\n", argv[0]);
2860 if (num_rids != 1) {
2861 d_fprintf(stderr, "Couldn't find group %s\n", argv[0]);
2865 if (rid_types[0] == SID_NAME_DOM_GRP) {
2866 return rpc_list_group_members(pipe_hnd, mem_ctx, domain_name,
2867 domain_sid, &domain_pol,
2871 if (rid_types[0] == SID_NAME_ALIAS) {
2872 return rpc_list_alias_members(pipe_hnd, mem_ctx, &domain_pol,
2876 return NT_STATUS_NO_SUCH_GROUP;
2879 static int rpc_group_members(int argc, const char **argv)
2882 return rpc_group_usage(argc, argv);
2885 return run_rpc_command(NULL, PI_SAMR, 0,
2886 rpc_group_members_internals,
2890 static NTSTATUS rpc_group_rename_internals(const DOM_SID *domain_sid,
2891 const char *domain_name,
2892 struct cli_state *cli,
2893 struct rpc_pipe_client *pipe_hnd,
2894 TALLOC_CTX *mem_ctx,
2899 POLICY_HND connect_pol, domain_pol, group_pol;
2900 uint32 num_rids, *rids, *rid_types;
2904 d_printf("Usage: 'net rpc group rename group newname'\n");
2905 return NT_STATUS_UNSUCCESSFUL;
2908 /* Get sam policy handle */
2910 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
2913 if (!NT_STATUS_IS_OK(result))
2916 /* Get domain policy handle */
2918 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
2919 MAXIMUM_ALLOWED_ACCESS,
2920 domain_sid, &domain_pol);
2922 if (!NT_STATUS_IS_OK(result))
2925 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, 1000,
2926 1, argv, &num_rids, &rids, &rid_types);
2928 if (num_rids != 1) {
2929 d_fprintf(stderr, "Couldn't find group %s\n", argv[0]);
2933 if (rid_types[0] != SID_NAME_DOM_GRP) {
2934 d_fprintf(stderr, "Can only rename domain groups\n");
2935 return NT_STATUS_UNSUCCESSFUL;
2938 result = rpccli_samr_open_group(pipe_hnd, mem_ctx, &domain_pol,
2939 MAXIMUM_ALLOWED_ACCESS,
2940 rids[0], &group_pol);
2942 if (!NT_STATUS_IS_OK(result))
2947 ctr.switch_value1 = 2;
2948 init_samr_group_info2(&ctr.group.info2, argv[1]);
2950 result = rpccli_samr_set_groupinfo(pipe_hnd, mem_ctx, &group_pol, &ctr);
2952 if (!NT_STATUS_IS_OK(result))
2955 return NT_STATUS_NO_SUCH_GROUP;
2958 static int rpc_group_rename(int argc, const char **argv)
2961 return rpc_group_usage(argc, argv);
2964 return run_rpc_command(NULL, PI_SAMR, 0,
2965 rpc_group_rename_internals,
2970 * 'net rpc group' entrypoint.
2971 * @param argc Standard main() style argc
2972 * @param argc Standard main() style argv. Initial components are already
2976 int net_rpc_group(int argc, const char **argv)
2978 struct functable func[] = {
2979 {"add", rpc_group_add},
2980 {"delete", rpc_group_delete},
2981 {"addmem", rpc_group_addmem},
2982 {"delmem", rpc_group_delmem},
2983 {"list", rpc_group_list},
2984 {"members", rpc_group_members},
2985 {"rename", rpc_group_rename},
2990 return run_rpc_command(NULL, PI_SAMR, 0,
2991 rpc_group_list_internals,
2995 return net_run_function(argc, argv, func, rpc_group_usage);
2998 /****************************************************************************/
3000 static int rpc_share_usage(int argc, const char **argv)
3002 return net_help_share(argc, argv);
3006 * Add a share on a remote RPC server
3008 * All parameters are provided by the run_rpc_command function, except for
3009 * argc, argv which are passes through.
3011 * @param domain_sid The domain sid acquired from the remote server
3012 * @param cli A cli_state connected to the server.
3013 * @param mem_ctx Talloc context, destoyed on completion of the function.
3014 * @param argc Standard main() style argc
3015 * @param argv Standard main() style argv. Initial components are already
3018 * @return Normal NTSTATUS return.
3020 static NTSTATUS rpc_share_add_internals(const DOM_SID *domain_sid,
3021 const char *domain_name,
3022 struct cli_state *cli,
3023 struct rpc_pipe_client *pipe_hnd,
3024 TALLOC_CTX *mem_ctx,int argc,
3030 uint32 type = STYPE_DISKTREE; /* only allow disk shares to be added */
3031 uint32 num_users=0, perms=0;
3032 char *password=NULL; /* don't allow a share password */
3035 if ((sharename = talloc_strdup(mem_ctx, argv[0])) == NULL) {
3036 return NT_STATUS_NO_MEMORY;
3039 path = strchr(sharename, '=');
3041 return NT_STATUS_UNSUCCESSFUL;
3044 result = rpccli_srvsvc_net_share_add(pipe_hnd, mem_ctx, sharename, type,
3045 opt_comment, perms, opt_maxusers,
3046 num_users, path, password,
3048 return werror_to_ntstatus(result);
3051 static int rpc_share_add(int argc, const char **argv)
3053 if ((argc < 1) || !strchr(argv[0], '=')) {
3054 DEBUG(1,("Sharename or path not specified on add\n"));
3055 return rpc_share_usage(argc, argv);
3057 return run_rpc_command(NULL, PI_SRVSVC, 0,
3058 rpc_share_add_internals,
3063 * Delete a share on a remote RPC server
3065 * All parameters are provided by the run_rpc_command function, except for
3066 * argc, argv which are passes through.
3068 * @param domain_sid The domain sid acquired from the remote server
3069 * @param cli A cli_state connected to the server.
3070 * @param mem_ctx Talloc context, destoyed on completion of the function.
3071 * @param argc Standard main() style argc
3072 * @param argv Standard main() style argv. Initial components are already
3075 * @return Normal NTSTATUS return.
3077 static NTSTATUS rpc_share_del_internals(const DOM_SID *domain_sid,
3078 const char *domain_name,
3079 struct cli_state *cli,
3080 struct rpc_pipe_client *pipe_hnd,
3081 TALLOC_CTX *mem_ctx,
3087 result = rpccli_srvsvc_net_share_del(pipe_hnd, mem_ctx, argv[0]);
3088 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
3092 * Delete a share on a remote RPC server
3094 * @param domain_sid The domain sid acquired from the remote server
3095 * @param argc Standard main() style argc
3096 * @param argv Standard main() style argv. Initial components are already
3099 * @return A shell status integer (0 for success)
3101 static int rpc_share_delete(int argc, const char **argv)
3104 DEBUG(1,("Sharename not specified on delete\n"));
3105 return rpc_share_usage(argc, argv);
3107 return run_rpc_command(NULL, PI_SRVSVC, 0,
3108 rpc_share_del_internals,
3113 * Formatted print of share info
3115 * @param info1 pointer to SRV_SHARE_INFO_1 to format
3118 static void display_share_info_1(SRV_SHARE_INFO_1 *info1)
3120 fstring netname = "", remark = "";
3122 rpcstr_pull_unistr2_fstring(netname, &info1->info_1_str.uni_netname);
3123 rpcstr_pull_unistr2_fstring(remark, &info1->info_1_str.uni_remark);
3125 if (opt_long_list_entries) {
3126 d_printf("%-12s %-8.8s %-50s\n",
3127 netname, share_type[info1->info_1.type & ~(STYPE_TEMPORARY|STYPE_HIDDEN)], remark);
3129 d_printf("%s\n", netname);
3134 static WERROR get_share_info(struct rpc_pipe_client *pipe_hnd,
3135 TALLOC_CTX *mem_ctx,
3139 SRV_SHARE_INFO_CTR *ctr)
3142 SRV_SHARE_INFO info;
3144 /* no specific share requested, enumerate all */
3148 uint32 preferred_len = 0xffffffff;
3150 init_enum_hnd(&hnd, 0);
3152 return rpccli_srvsvc_net_share_enum(pipe_hnd, mem_ctx, level, ctr,
3153 preferred_len, &hnd);
3156 /* request just one share */
3157 result = rpccli_srvsvc_net_share_get_info(pipe_hnd, mem_ctx, argv[0], level, &info);
3159 if (!W_ERROR_IS_OK(result))
3165 ctr->info_level = ctr->switch_value = level;
3166 ctr->ptr_share_info = ctr->ptr_entries = 1;
3167 ctr->num_entries = ctr->num_entries2 = 1;
3173 SRV_SHARE_INFO_1 *info1;
3175 ctr->share.info1 = TALLOC_ARRAY(mem_ctx, SRV_SHARE_INFO_1, 1);
3176 if (ctr->share.info1 == NULL) {
3177 result = WERR_NOMEM;
3180 info1 = ctr->share.info1;
3182 memset(ctr->share.info1, 0, sizeof(SRV_SHARE_INFO_1));
3184 /* Copy pointer crap */
3186 memcpy(&info1->info_1, &info.share.info1.info_1, sizeof(SH_INFO_1));
3188 /* Duplicate strings */
3190 s = unistr2_to_ascii_talloc(mem_ctx, &info.share.info1.info_1_str.uni_netname);
3192 init_unistr2(&info1->info_1_str.uni_netname, s, UNI_STR_TERMINATE);
3194 s = unistr2_to_ascii_talloc(mem_ctx, &info.share.info1.info_1_str.uni_remark);
3196 init_unistr2(&info1->info_1_str.uni_remark, s, UNI_STR_TERMINATE);
3201 SRV_SHARE_INFO_2 *info2;
3203 ctr->share.info2 = TALLOC_ARRAY(mem_ctx, SRV_SHARE_INFO_2, 1);
3204 if (ctr->share.info2 == NULL) {
3205 result = WERR_NOMEM;
3208 info2 = ctr->share.info2;
3210 memset(ctr->share.info2, 0, sizeof(SRV_SHARE_INFO_2));
3212 /* Copy pointer crap */
3214 memcpy(&info2->info_2, &info.share.info2.info_2, sizeof(SH_INFO_2));
3216 /* Duplicate strings */
3218 s = unistr2_to_ascii_talloc(mem_ctx, &info.share.info2.info_2_str.uni_netname);
3220 init_unistr2(&info2->info_2_str.uni_netname, s, UNI_STR_TERMINATE);
3222 s = unistr2_to_ascii_talloc(mem_ctx, &info.share.info2.info_2_str.uni_remark);
3224 init_unistr2(&info2->info_2_str.uni_remark, s, UNI_STR_TERMINATE);
3226 s = unistr2_to_ascii_talloc(mem_ctx, &info.share.info2.info_2_str.uni_path);
3228 init_unistr2(&info2->info_2_str.uni_path, s, UNI_STR_TERMINATE);
3230 s = unistr2_to_ascii_talloc(mem_ctx, &info.share.info2.info_2_str.uni_passwd);
3232 init_unistr2(&info2->info_2_str.uni_passwd, s, UNI_STR_TERMINATE);
3237 SRV_SHARE_INFO_502 *info502;
3239 ctr->share.info502 = TALLOC_ARRAY(mem_ctx, SRV_SHARE_INFO_502, 1);
3240 if (ctr->share.info502 == NULL) {
3241 result = WERR_NOMEM;
3244 info502 = ctr->share.info502;
3246 memset(ctr->share.info502, 0, sizeof(SRV_SHARE_INFO_502));
3248 /* Copy pointer crap */
3250 memcpy(&info502->info_502, &info.share.info502.info_502, sizeof(SH_INFO_502));
3252 /* Duplicate strings */
3254 s = unistr2_to_ascii_talloc(mem_ctx, &info.share.info502.info_502_str.uni_netname);
3256 init_unistr2(&info502->info_502_str.uni_netname, s, UNI_STR_TERMINATE);
3258 s = unistr2_to_ascii_talloc(mem_ctx, &info.share.info502.info_502_str.uni_remark);
3260 init_unistr2(&info502->info_502_str.uni_remark, s, UNI_STR_TERMINATE);
3262 s = unistr2_to_ascii_talloc(mem_ctx, &info.share.info502.info_502_str.uni_path);
3264 init_unistr2(&info502->info_502_str.uni_path, s, UNI_STR_TERMINATE);
3266 s = unistr2_to_ascii_talloc(mem_ctx, &info.share.info502.info_502_str.uni_passwd);
3268 init_unistr2(&info502->info_502_str.uni_passwd, s, UNI_STR_TERMINATE);
3270 info502->info_502_str.sd = dup_sec_desc(mem_ctx, info.share.info502.info_502_str.sd);
3281 * List shares on a remote RPC server
3283 * All parameters are provided by the run_rpc_command function, except for
3284 * argc, argv which are passes through.
3286 * @param domain_sid The domain sid acquired from the remote server
3287 * @param cli A cli_state connected to the server.
3288 * @param mem_ctx Talloc context, destoyed on completion of the function.
3289 * @param argc Standard main() style argc
3290 * @param argv Standard main() style argv. Initial components are already
3293 * @return Normal NTSTATUS return.
3296 static NTSTATUS rpc_share_list_internals(const DOM_SID *domain_sid,
3297 const char *domain_name,
3298 struct cli_state *cli,
3299 struct rpc_pipe_client *pipe_hnd,
3300 TALLOC_CTX *mem_ctx,
3304 SRV_SHARE_INFO_CTR ctr;
3306 uint32 i, level = 1;
3308 result = get_share_info(pipe_hnd, mem_ctx, level, argc, argv, &ctr);
3309 if (!W_ERROR_IS_OK(result))
3312 /* Display results */
3314 if (opt_long_list_entries) {
3316 "\nEnumerating shared resources (exports) on remote server:\n\n"\
3317 "\nShare name Type Description\n"\
3318 "---------- ---- -----------\n");
3320 for (i = 0; i < ctr.num_entries; i++)
3321 display_share_info_1(&ctr.share.info1[i]);
3323 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
3327 * 'net rpc share list' entrypoint.
3328 * @param argc Standard main() style argc
3329 * @param argv Standard main() style argv. Initial components are already
3332 static int rpc_share_list(int argc, const char **argv)
3334 return run_rpc_command(NULL, PI_SRVSVC, 0, rpc_share_list_internals, argc, argv);
3337 static bool check_share_availability(struct cli_state *cli, const char *netname)
3339 if (!cli_send_tconX(cli, netname, "A:", "", 0)) {
3340 d_printf("skipping [%s]: not a file share.\n", netname);
3350 static bool check_share_sanity(struct cli_state *cli, fstring netname, uint32 type)
3352 /* only support disk shares */
3353 if (! ( type == STYPE_DISKTREE || type == (STYPE_DISKTREE | STYPE_HIDDEN)) ) {
3354 printf("share [%s] is not a diskshare (type: %x)\n", netname, type);
3358 /* skip builtin shares */
3359 /* FIXME: should print$ be added too ? */
3360 if (strequal(netname,"IPC$") || strequal(netname,"ADMIN$") ||
3361 strequal(netname,"global"))
3364 if (opt_exclude && in_list(netname, opt_exclude, False)) {
3365 printf("excluding [%s]\n", netname);
3369 return check_share_availability(cli, netname);
3373 * Migrate shares from a remote RPC server to the local RPC srever
3375 * All parameters are provided by the run_rpc_command function, except for
3376 * argc, argv which are passes through.
3378 * @param domain_sid The domain sid acquired from the remote server
3379 * @param cli A cli_state connected to the server.
3380 * @param mem_ctx Talloc context, destoyed on completion of the function.
3381 * @param argc Standard main() style argc
3382 * @param argv Standard main() style argv. Initial components are already
3385 * @return Normal NTSTATUS return.
3388 static NTSTATUS rpc_share_migrate_shares_internals(const DOM_SID *domain_sid,
3389 const char *domain_name,
3390 struct cli_state *cli,
3391 struct rpc_pipe_client *pipe_hnd,
3392 TALLOC_CTX *mem_ctx,
3397 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
3398 SRV_SHARE_INFO_CTR ctr_src;
3399 uint32 type = STYPE_DISKTREE; /* only allow disk shares to be added */
3400 char *password = NULL; /* don't allow a share password */
3402 struct rpc_pipe_client *srvsvc_pipe = NULL;
3403 struct cli_state *cli_dst = NULL;
3404 uint32 level = 502; /* includes secdesc */
3406 result = get_share_info(pipe_hnd, mem_ctx, level, argc, argv, &ctr_src);
3407 if (!W_ERROR_IS_OK(result))
3410 /* connect destination PI_SRVSVC */
3411 nt_status = connect_dst_pipe(&cli_dst, &srvsvc_pipe, PI_SRVSVC);
3412 if (!NT_STATUS_IS_OK(nt_status))
3416 for (i = 0; i < ctr_src.num_entries; i++) {
3418 fstring netname = "", remark = "", path = "";
3419 /* reset error-code */
3420 nt_status = NT_STATUS_UNSUCCESSFUL;
3422 rpcstr_pull_unistr2_fstring(
3423 netname, &ctr_src.share.info502[i].info_502_str.uni_netname);
3424 rpcstr_pull_unistr2_fstring(
3425 remark, &ctr_src.share.info502[i].info_502_str.uni_remark);
3426 rpcstr_pull_unistr2_fstring(
3427 path, &ctr_src.share.info502[i].info_502_str.uni_path);
3429 if (!check_share_sanity(cli, netname, ctr_src.share.info502[i].info_502.type))
3432 /* finally add the share on the dst server */
3434 printf("migrating: [%s], path: %s, comment: %s, without share-ACLs\n",
3435 netname, path, remark);
3437 result = rpccli_srvsvc_net_share_add(srvsvc_pipe, mem_ctx, netname, type, remark,
3438 ctr_src.share.info502[i].info_502.perms,
3439 ctr_src.share.info502[i].info_502.max_uses,
3440 ctr_src.share.info502[i].info_502.num_uses,
3441 path, password, level,
3444 if (W_ERROR_V(result) == W_ERROR_V(WERR_ALREADY_EXISTS)) {
3445 printf(" [%s] does already exist\n", netname);
3449 if (!W_ERROR_IS_OK(result)) {
3450 printf("cannot add share: %s\n", dos_errstr(result));
3456 nt_status = NT_STATUS_OK;
3460 cli_shutdown(cli_dst);
3468 * Migrate shares from a rpc-server to another
3470 * @param argc Standard main() style argc
3471 * @param argv Standard main() style argv. Initial components are already
3474 * @return A shell status integer (0 for success)
3476 static int rpc_share_migrate_shares(int argc, const char **argv)
3480 printf("no server to migrate\n");
3484 return run_rpc_command(NULL, PI_SRVSVC, 0,
3485 rpc_share_migrate_shares_internals,
3492 * @param f file_info
3493 * @param mask current search mask
3494 * @param state arg-pointer
3497 static void copy_fn(const char *mnt, file_info *f, const char *mask, void *state)
3499 static NTSTATUS nt_status;
3500 static struct copy_clistate *local_state;
3501 static fstring filename, new_mask;
3505 local_state = (struct copy_clistate *)state;
3506 nt_status = NT_STATUS_UNSUCCESSFUL;
3508 if (strequal(f->name, ".") || strequal(f->name, ".."))
3511 DEBUG(3,("got mask: %s, name: %s\n", mask, f->name));
3514 if (f->mode & aDIR) {
3516 DEBUG(3,("got dir: %s\n", f->name));
3518 fstrcpy(dir, local_state->cwd);
3520 fstrcat(dir, f->name);
3522 switch (net_mode_share)
3524 case NET_MODE_SHARE_MIGRATE:
3525 /* create that directory */
3526 nt_status = net_copy_file(local_state->mem_ctx,
3527 local_state->cli_share_src,
3528 local_state->cli_share_dst,
3530 opt_acls? True : False,
3531 opt_attrs? True : False,
3532 opt_timestamps? True : False,
3536 d_fprintf(stderr, "Unsupported mode %d\n", net_mode_share);
3540 if (!NT_STATUS_IS_OK(nt_status))
3541 printf("could not handle dir %s: %s\n",
3542 dir, nt_errstr(nt_status));
3544 /* search below that directory */
3545 fstrcpy(new_mask, dir);
3546 fstrcat(new_mask, "\\*");
3548 old_dir = local_state->cwd;
3549 local_state->cwd = dir;
3550 if (!sync_files(local_state, new_mask))
3551 printf("could not handle files\n");
3552 local_state->cwd = old_dir;
3559 fstrcpy(filename, local_state->cwd);
3560 fstrcat(filename, "\\");
3561 fstrcat(filename, f->name);
3563 DEBUG(3,("got file: %s\n", filename));
3565 switch (net_mode_share)
3567 case NET_MODE_SHARE_MIGRATE:
3568 nt_status = net_copy_file(local_state->mem_ctx,
3569 local_state->cli_share_src,
3570 local_state->cli_share_dst,
3572 opt_acls? True : False,
3573 opt_attrs? True : False,
3574 opt_timestamps? True: False,
3578 d_fprintf(stderr, "Unsupported file mode %d\n", net_mode_share);
3582 if (!NT_STATUS_IS_OK(nt_status))
3583 printf("could not handle file %s: %s\n",
3584 filename, nt_errstr(nt_status));
3589 * sync files, can be called recursivly to list files
3590 * and then call copy_fn for each file
3592 * @param cp_clistate pointer to the copy_clistate we work with
3593 * @param mask the current search mask
3595 * @return Boolean result
3597 static bool sync_files(struct copy_clistate *cp_clistate, const char *mask)
3599 struct cli_state *targetcli;
3600 char *targetpath = NULL;
3602 DEBUG(3,("calling cli_list with mask: %s\n", mask));
3604 if ( !cli_resolve_path(talloc_tos(), "", cp_clistate->cli_share_src,
3605 mask, &targetcli, &targetpath ) ) {
3606 d_fprintf(stderr, "cli_resolve_path %s failed with error: %s\n",
3607 mask, cli_errstr(cp_clistate->cli_share_src));
3611 if (cli_list(targetcli, targetpath, cp_clistate->attribute, copy_fn, cp_clistate) == -1) {
3612 d_fprintf(stderr, "listing %s failed with error: %s\n",
3613 mask, cli_errstr(targetcli));
3622 * Set the top level directory permissions before we do any further copies.
3623 * Should set up ACL inheritance.
3626 bool copy_top_level_perms(struct copy_clistate *cp_clistate,
3627 const char *sharename)
3629 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
3631 switch (net_mode_share) {
3632 case NET_MODE_SHARE_MIGRATE:
3633 DEBUG(3,("calling net_copy_fileattr for '.' directory in share %s\n", sharename));
3634 nt_status = net_copy_fileattr(cp_clistate->mem_ctx,
3635 cp_clistate->cli_share_src,
3636 cp_clistate->cli_share_dst,
3638 opt_acls? True : False,
3639 opt_attrs? True : False,
3640 opt_timestamps? True: False,
3644 d_fprintf(stderr, "Unsupported mode %d\n", net_mode_share);
3648 if (!NT_STATUS_IS_OK(nt_status)) {
3649 printf("Could handle directory attributes for top level directory of share %s. Error %s\n",
3650 sharename, nt_errstr(nt_status));
3658 * Sync all files inside a remote share to another share (over smb)
3660 * All parameters are provided by the run_rpc_command function, except for
3661 * argc, argv which are passes through.
3663 * @param domain_sid The domain sid acquired from the remote server
3664 * @param cli A cli_state connected to the server.
3665 * @param mem_ctx Talloc context, destoyed on completion of the function.
3666 * @param argc Standard main() style argc
3667 * @param argv Standard main() style argv. Initial components are already
3670 * @return Normal NTSTATUS return.
3673 static NTSTATUS rpc_share_migrate_files_internals(const DOM_SID *domain_sid,
3674 const char *domain_name,
3675 struct cli_state *cli,
3676 struct rpc_pipe_client *pipe_hnd,
3677 TALLOC_CTX *mem_ctx,
3682 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
3683 SRV_SHARE_INFO_CTR ctr_src;
3686 struct copy_clistate cp_clistate;
3687 bool got_src_share = False;
3688 bool got_dst_share = False;
3689 const char *mask = "\\*";
3692 dst = SMB_STRDUP(opt_destination?opt_destination:"127.0.0.1");
3694 result = get_share_info(pipe_hnd, mem_ctx, level, argc, argv, &ctr_src);
3696 if (!W_ERROR_IS_OK(result))
3699 for (i = 0; i < ctr_src.num_entries; i++) {
3701 fstring netname = "";
3703 rpcstr_pull_unistr2_fstring(
3704 netname, &ctr_src.share.info502[i].info_502_str.uni_netname);
3706 if (!check_share_sanity(cli, netname, ctr_src.share.info502[i].info_502.type))
3709 /* one might not want to mirror whole discs :) */
3710 if (strequal(netname, "print$") || netname[1] == '$') {
3711 d_printf("skipping [%s]: builtin/hidden share\n", netname);
3715 switch (net_mode_share)
3717 case NET_MODE_SHARE_MIGRATE:
3721 d_fprintf(stderr, "Unsupported mode %d\n", net_mode_share);
3724 printf(" [%s] files and directories %s ACLs, %s DOS Attributes %s\n",
3726 opt_acls ? "including" : "without",
3727 opt_attrs ? "including" : "without",
3728 opt_timestamps ? "(preserving timestamps)" : "");
3730 cp_clistate.mem_ctx = mem_ctx;
3731 cp_clistate.cli_share_src = NULL;
3732 cp_clistate.cli_share_dst = NULL;
3733 cp_clistate.cwd = NULL;
3734 cp_clistate.attribute = aSYSTEM | aHIDDEN | aDIR;
3736 /* open share source */
3737 nt_status = connect_to_service(&cp_clistate.cli_share_src,
3738 &cli->dest_ss, cli->desthost,
3740 if (!NT_STATUS_IS_OK(nt_status))
3743 got_src_share = True;
3745 if (net_mode_share == NET_MODE_SHARE_MIGRATE) {
3746 /* open share destination */
3747 nt_status = connect_to_service(&cp_clistate.cli_share_dst,
3748 NULL, dst, netname, "A:");
3749 if (!NT_STATUS_IS_OK(nt_status))
3752 got_dst_share = True;
3755 if (!copy_top_level_perms(&cp_clistate, netname)) {
3756 d_fprintf(stderr, "Could not handle the top level directory permissions for the share: %s\n", netname);
3757 nt_status = NT_STATUS_UNSUCCESSFUL;
3761 if (!sync_files(&cp_clistate, mask)) {
3762 d_fprintf(stderr, "could not handle files for share: %s\n", netname);
3763 nt_status = NT_STATUS_UNSUCCESSFUL;
3768 nt_status = NT_STATUS_OK;
3773 cli_shutdown(cp_clistate.cli_share_src);
3776 cli_shutdown(cp_clistate.cli_share_dst);
3782 static int rpc_share_migrate_files(int argc, const char **argv)
3786 printf("no server to migrate\n");
3790 return run_rpc_command(NULL, PI_SRVSVC, 0,
3791 rpc_share_migrate_files_internals,
3796 * Migrate share-ACLs from a remote RPC server to the local RPC srever
3798 * All parameters are provided by the run_rpc_command function, except for
3799 * argc, argv which are passes through.
3801 * @param domain_sid The domain sid acquired from the remote server
3802 * @param cli A cli_state connected to the server.
3803 * @param mem_ctx Talloc context, destoyed on completion of the function.
3804 * @param argc Standard main() style argc
3805 * @param argv Standard main() style argv. Initial components are already
3808 * @return Normal NTSTATUS return.
3811 static NTSTATUS rpc_share_migrate_security_internals(const DOM_SID *domain_sid,
3812 const char *domain_name,
3813 struct cli_state *cli,
3814 struct rpc_pipe_client *pipe_hnd,
3815 TALLOC_CTX *mem_ctx,
3820 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
3821 SRV_SHARE_INFO_CTR ctr_src;
3822 SRV_SHARE_INFO info;
3824 struct rpc_pipe_client *srvsvc_pipe = NULL;
3825 struct cli_state *cli_dst = NULL;
3826 uint32 level = 502; /* includes secdesc */
3828 result = get_share_info(pipe_hnd, mem_ctx, level, argc, argv, &ctr_src);
3830 if (!W_ERROR_IS_OK(result))
3833 /* connect destination PI_SRVSVC */
3834 nt_status = connect_dst_pipe(&cli_dst, &srvsvc_pipe, PI_SRVSVC);
3835 if (!NT_STATUS_IS_OK(nt_status))
3839 for (i = 0; i < ctr_src.num_entries; i++) {
3841 fstring netname = "", remark = "", path = "";
3842 /* reset error-code */
3843 nt_status = NT_STATUS_UNSUCCESSFUL;
3845 rpcstr_pull_unistr2_fstring(
3846 netname, &ctr_src.share.info502[i].info_502_str.uni_netname);
3847 rpcstr_pull_unistr2_fstring(
3848 remark, &ctr_src.share.info502[i].info_502_str.uni_remark);
3849 rpcstr_pull_unistr2_fstring(
3850 path, &ctr_src.share.info502[i].info_502_str.uni_path);
3852 if (!check_share_sanity(cli, netname, ctr_src.share.info502[i].info_502.type))
3855 printf("migrating: [%s], path: %s, comment: %s, including share-ACLs\n",
3856 netname, path, remark);
3859 display_sec_desc(ctr_src.share.info502[i].info_502_str.sd);
3864 info.switch_value = level;
3865 info.ptr_share_ctr = 1;
3867 /* FIXME: shouldn't we be able to just set the security descriptor ? */
3868 info.share.info502 = ctr_src.share.info502[i];
3870 /* finally modify the share on the dst server */
3871 result = rpccli_srvsvc_net_share_set_info(srvsvc_pipe, mem_ctx, netname, level, &info);
3873 if (!W_ERROR_IS_OK(result)) {
3874 printf("cannot set share-acl: %s\n", dos_errstr(result));
3880 nt_status = NT_STATUS_OK;
3884 cli_shutdown(cli_dst);
3892 * Migrate share-acls from a rpc-server to another
3894 * @param argc Standard main() style argc
3895 * @param argv Standard main() style argv. Initial components are already
3898 * @return A shell status integer (0 for success)
3900 static int rpc_share_migrate_security(int argc, const char **argv)
3904 printf("no server to migrate\n");
3908 return run_rpc_command(NULL, PI_SRVSVC, 0,
3909 rpc_share_migrate_security_internals,
3914 * Migrate shares (including share-definitions, share-acls and files with acls/attrs)
3915 * from one server to another
3917 * @param argc Standard main() style argc
3918 * @param argv Standard main() style argv. Initial components are already
3921 * @return A shell status integer (0 for success)
3924 static int rpc_share_migrate_all(int argc, const char **argv)
3929 printf("no server to migrate\n");
3933 /* order is important. we don't want to be locked out by the share-acl
3934 * before copying files - gd */
3936 ret = run_rpc_command(NULL, PI_SRVSVC, 0, rpc_share_migrate_shares_internals, argc, argv);
3940 ret = run_rpc_command(NULL, PI_SRVSVC, 0, rpc_share_migrate_files_internals, argc, argv);
3944 return run_rpc_command(NULL, PI_SRVSVC, 0, rpc_share_migrate_security_internals, argc, argv);
3949 * 'net rpc share migrate' entrypoint.
3950 * @param argc Standard main() style argc
3951 * @param argv Standard main() style argv. Initial components are already
3954 static int rpc_share_migrate(int argc, const char **argv)
3957 struct functable func[] = {
3958 {"all", rpc_share_migrate_all},
3959 {"files", rpc_share_migrate_files},
3960 {"help", rpc_share_usage},
3961 {"security", rpc_share_migrate_security},
3962 {"shares", rpc_share_migrate_shares},
3966 net_mode_share = NET_MODE_SHARE_MIGRATE;
3968 return net_run_function(argc, argv, func, rpc_share_usage);
3977 static int num_server_aliases;
3978 static struct full_alias *server_aliases;
3981 * Add an alias to the static list.
3983 static void push_alias(TALLOC_CTX *mem_ctx, struct full_alias *alias)
3985 if (server_aliases == NULL)
3986 server_aliases = SMB_MALLOC_ARRAY(struct full_alias, 100);
3988 server_aliases[num_server_aliases] = *alias;
3989 num_server_aliases += 1;
3993 * For a specific domain on the server, fetch all the aliases
3994 * and their members. Add all of them to the server_aliases.
3997 static NTSTATUS rpc_fetch_domain_aliases(struct rpc_pipe_client *pipe_hnd,
3998 TALLOC_CTX *mem_ctx,
3999 POLICY_HND *connect_pol,
4000 const DOM_SID *domain_sid)
4002 uint32 start_idx, max_entries, num_entries, i;
4003 struct acct_info *groups;
4005 POLICY_HND domain_pol;
4007 /* Get domain policy handle */
4009 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, connect_pol,
4010 MAXIMUM_ALLOWED_ACCESS,
4011 domain_sid, &domain_pol);
4012 if (!NT_STATUS_IS_OK(result))
4019 result = rpccli_samr_enum_als_groups(pipe_hnd, mem_ctx, &domain_pol,
4020 &start_idx, max_entries,
4021 &groups, &num_entries);
4023 for (i = 0; i < num_entries; i++) {
4025 POLICY_HND alias_pol;
4026 struct full_alias alias;
4030 result = rpccli_samr_open_alias(pipe_hnd, mem_ctx, &domain_pol,
4031 MAXIMUM_ALLOWED_ACCESS,
4034 if (!NT_STATUS_IS_OK(result))
4037 result = rpccli_samr_query_aliasmem(pipe_hnd, mem_ctx,
4041 if (!NT_STATUS_IS_OK(result))
4044 result = rpccli_samr_close(pipe_hnd, mem_ctx, &alias_pol);
4045 if (!NT_STATUS_IS_OK(result))
4048 alias.members = NULL;
4050 if (alias.num_members > 0) {
4051 alias.members = SMB_MALLOC_ARRAY(DOM_SID, alias.num_members);
4053 for (j = 0; j < alias.num_members; j++)
4054 sid_copy(&alias.members[j],
4058 sid_copy(&alias.sid, domain_sid);
4059 sid_append_rid(&alias.sid, groups[i].rid);
4061 push_alias(mem_ctx, &alias);
4063 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
4065 result = NT_STATUS_OK;
4068 rpccli_samr_close(pipe_hnd, mem_ctx, &domain_pol);
4074 * Dump server_aliases as names for debugging purposes.
4077 static NTSTATUS rpc_aliaslist_dump(const DOM_SID *domain_sid,
4078 const char *domain_name,
4079 struct cli_state *cli,
4080 struct rpc_pipe_client *pipe_hnd,
4081 TALLOC_CTX *mem_ctx,
4089 result = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, True,
4090 SEC_RIGHTS_MAXIMUM_ALLOWED,
4092 if (!NT_STATUS_IS_OK(result))
4095 for (i=0; i<num_server_aliases; i++) {
4098 enum lsa_SidType *types;
4101 struct full_alias *alias = &server_aliases[i];
4103 result = rpccli_lsa_lookup_sids(pipe_hnd, mem_ctx, &lsa_pol, 1,
4105 &domains, &names, &types);
4106 if (!NT_STATUS_IS_OK(result))
4109 DEBUG(1, ("%s\\%s %d: ", domains[0], names[0], types[0]));
4111 if (alias->num_members == 0) {
4116 result = rpccli_lsa_lookup_sids(pipe_hnd, mem_ctx, &lsa_pol,
4119 &domains, &names, &types);
4121 if (!NT_STATUS_IS_OK(result) &&
4122 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
4125 for (j=0; j<alias->num_members; j++)
4126 DEBUG(1, ("%s\\%s (%d); ",
4127 domains[j] ? domains[j] : "*unknown*",
4128 names[j] ? names[j] : "*unknown*",types[j]));
4132 rpccli_lsa_Close(pipe_hnd, mem_ctx, &lsa_pol);
4134 return NT_STATUS_OK;
4138 * Fetch a list of all server aliases and their members into
4142 static NTSTATUS rpc_aliaslist_internals(const DOM_SID *domain_sid,
4143 const char *domain_name,
4144 struct cli_state *cli,
4145 struct rpc_pipe_client *pipe_hnd,
4146 TALLOC_CTX *mem_ctx,
4151 POLICY_HND connect_pol;
4153 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
4156 if (!NT_STATUS_IS_OK(result))
4159 result = rpc_fetch_domain_aliases(pipe_hnd, mem_ctx, &connect_pol,
4160 &global_sid_Builtin);
4162 if (!NT_STATUS_IS_OK(result))
4165 result = rpc_fetch_domain_aliases(pipe_hnd, mem_ctx, &connect_pol,
4168 rpccli_samr_close(pipe_hnd, mem_ctx, &connect_pol);
4173 static void init_user_token(NT_USER_TOKEN *token, DOM_SID *user_sid)
4175 token->num_sids = 4;
4177 if (!(token->user_sids = SMB_MALLOC_ARRAY(DOM_SID, 4))) {
4178 d_fprintf(stderr, "malloc failed\n");
4179 token->num_sids = 0;
4183 token->user_sids[0] = *user_sid;
4184 sid_copy(&token->user_sids[1], &global_sid_World);
4185 sid_copy(&token->user_sids[2], &global_sid_Network);
4186 sid_copy(&token->user_sids[3], &global_sid_Authenticated_Users);
4189 static void free_user_token(NT_USER_TOKEN *token)
4191 SAFE_FREE(token->user_sids);
4194 static bool is_sid_in_token(NT_USER_TOKEN *token, DOM_SID *sid)
4198 for (i=0; i<token->num_sids; i++) {
4199 if (sid_compare(sid, &token->user_sids[i]) == 0)
4205 static void add_sid_to_token(NT_USER_TOKEN *token, DOM_SID *sid)
4207 if (is_sid_in_token(token, sid))
4210 token->user_sids = SMB_REALLOC_ARRAY(token->user_sids, DOM_SID, token->num_sids+1);
4211 if (!token->user_sids) {
4215 sid_copy(&token->user_sids[token->num_sids], sid);
4217 token->num_sids += 1;
4222 NT_USER_TOKEN token;
4225 static void dump_user_token(struct user_token *token)
4229 d_printf("%s\n", token->name);
4231 for (i=0; i<token->token.num_sids; i++) {
4232 d_printf(" %s\n", sid_string_tos(&token->token.user_sids[i]));
4236 static bool is_alias_member(DOM_SID *sid, struct full_alias *alias)
4240 for (i=0; i<alias->num_members; i++) {
4241 if (sid_compare(sid, &alias->members[i]) == 0)
4248 static void collect_sid_memberships(NT_USER_TOKEN *token, DOM_SID sid)
4252 for (i=0; i<num_server_aliases; i++) {
4253 if (is_alias_member(&sid, &server_aliases[i]))
4254 add_sid_to_token(token, &server_aliases[i].sid);
4259 * We got a user token with all the SIDs we can know about without asking the
4260 * server directly. These are the user and domain group sids. All of these can
4261 * be members of aliases. So scan the list of aliases for each of the SIDs and
4262 * add them to the token.
4265 static void collect_alias_memberships(NT_USER_TOKEN *token)
4267 int num_global_sids = token->num_sids;
4270 for (i=0; i<num_global_sids; i++) {
4271 collect_sid_memberships(token, token->user_sids[i]);
4275 static bool get_user_sids(const char *domain, const char *user, NT_USER_TOKEN *token)
4277 struct winbindd_request request;
4278 struct winbindd_response response;
4286 fstr_sprintf(full_name, "%s%c%s",
4287 domain, *lp_winbind_separator(), user);
4289 /* First let's find out the user sid */
4291 ZERO_STRUCT(request);
4292 ZERO_STRUCT(response);
4294 fstrcpy(request.data.name.dom_name, domain);
4295 fstrcpy(request.data.name.name, user);
4297 result = winbindd_request_response(WINBINDD_LOOKUPNAME, &request, &response);
4299 if (result != NSS_STATUS_SUCCESS) {
4300 DEBUG(1, ("winbind could not find %s\n", full_name));
4304 if (response.data.sid.type != SID_NAME_USER) {
4305 DEBUG(1, ("%s is not a user\n", full_name));
4309 string_to_sid(&user_sid, response.data.sid.sid);
4311 init_user_token(token, &user_sid);
4313 /* And now the groups winbind knows about */
4315 ZERO_STRUCT(response);
4317 fstrcpy(request.data.username, full_name);
4319 result = winbindd_request_response(WINBINDD_GETGROUPS, &request, &response);
4321 if (result != NSS_STATUS_SUCCESS) {
4322 DEBUG(1, ("winbind could not get groups of %s\n", full_name));
4326 for (i = 0; i < response.data.num_entries; i++) {
4327 gid_t gid = ((gid_t *)response.extra_data.data)[i];
4330 struct winbindd_request sidrequest;
4331 struct winbindd_response sidresponse;
4333 ZERO_STRUCT(sidrequest);
4334 ZERO_STRUCT(sidresponse);
4336 sidrequest.data.gid = gid;
4338 result = winbindd_request_response(WINBINDD_GID_TO_SID,
4339 &sidrequest, &sidresponse);
4341 if (result != NSS_STATUS_SUCCESS) {
4342 DEBUG(1, ("winbind could not find SID of gid %d\n",
4347 DEBUG(3, (" %s\n", sidresponse.data.sid.sid));
4349 string_to_sid(&sid, sidresponse.data.sid.sid);
4350 add_sid_to_token(token, &sid);
4353 SAFE_FREE(response.extra_data.data);
4359 * Get a list of all user tokens we want to look at
4362 static bool get_user_tokens(int *num_tokens, struct user_token **user_tokens)
4364 struct winbindd_request request;
4365 struct winbindd_response response;
4366 const char *extra_data;
4369 struct user_token *result;
4370 TALLOC_CTX *frame = NULL;
4372 if (lp_winbind_use_default_domain() &&
4373 (opt_target_workgroup == NULL)) {
4374 d_fprintf(stderr, "winbind use default domain = yes set, "
4375 "please specify a workgroup\n");
4379 /* Send request to winbind daemon */
4381 ZERO_STRUCT(request);
4382 ZERO_STRUCT(response);
4384 if (winbindd_request_response(WINBINDD_LIST_USERS, &request, &response) !=
4388 /* Look through extra data */
4390 if (!response.extra_data.data)
4393 extra_data = (const char *)response.extra_data.data;
4396 frame = talloc_stackframe();
4397 while(next_token_talloc(frame, &extra_data, &name, ",")) {
4401 result = SMB_MALLOC_ARRAY(struct user_token, *num_tokens);
4403 if (result == NULL) {
4404 DEBUG(1, ("Could not malloc sid array\n"));
4409 extra_data = (const char *)response.extra_data.data;
4412 while(next_token_talloc(frame, &extra_data, &name, ",")) {
4413 fstring domain, user;
4416 fstrcpy(result[i].name, name);
4418 p = strchr(name, *lp_winbind_separator());
4420 DEBUG(3, ("%s\n", name));
4423 fstrcpy(domain, opt_target_workgroup);
4424 fstrcpy(user, name);
4427 fstrcpy(domain, name);
4432 get_user_sids(domain, user, &(result[i].token));
4436 SAFE_FREE(response.extra_data.data);
4438 *user_tokens = result;
4443 static bool get_user_tokens_from_file(FILE *f,
4445 struct user_token **tokens)
4447 struct user_token *token = NULL;
4452 if (fgets(line, sizeof(line)-1, f) == NULL) {
4456 if (line[strlen(line)-1] == '\n')
4457 line[strlen(line)-1] = '\0';
4459 if (line[0] == ' ') {
4463 string_to_sid(&sid, &line[1]);
4465 if (token == NULL) {
4466 DEBUG(0, ("File does not begin with username"));
4470 add_sid_to_token(&token->token, &sid);
4474 /* And a new user... */
4477 *tokens = SMB_REALLOC_ARRAY(*tokens, struct user_token, *num_tokens);
4478 if (*tokens == NULL) {
4479 DEBUG(0, ("Could not realloc tokens\n"));
4483 token = &((*tokens)[*num_tokens-1]);
4485 fstrcpy(token->name, line);
4486 token->token.num_sids = 0;
4487 token->token.user_sids = NULL;
4496 * Show the list of all users that have access to a share
4499 static void show_userlist(struct rpc_pipe_client *pipe_hnd,
4500 TALLOC_CTX *mem_ctx,
4501 const char *netname,
4503 struct user_token *tokens)
4506 SEC_DESC *share_sd = NULL;
4507 SEC_DESC *root_sd = NULL;
4508 struct cli_state *cli = pipe_hnd->cli;
4510 SRV_SHARE_INFO info;
4514 result = rpccli_srvsvc_net_share_get_info(pipe_hnd, mem_ctx, netname,
4517 if (!W_ERROR_IS_OK(result)) {
4518 DEBUG(1, ("Coult not query secdesc for share %s\n",
4523 share_sd = info.share.info502.info_502_str.sd;
4524 if (share_sd == NULL) {
4525 DEBUG(1, ("Got no secdesc for share %s\n",
4531 if (!cli_send_tconX(cli, netname, "A:", "", 0)) {
4535 fnum = cli_nt_create(cli, "\\", READ_CONTROL_ACCESS);
4538 root_sd = cli_query_secdesc(cli, fnum, mem_ctx);
4541 for (i=0; i<num_tokens; i++) {
4545 if (share_sd != NULL) {
4546 if (!se_access_check(share_sd, &tokens[i].token,
4547 1, &acc_granted, &status)) {
4548 DEBUG(1, ("Could not check share_sd for "
4554 if (!NT_STATUS_IS_OK(status))
4558 if (root_sd == NULL) {
4559 d_printf(" %s\n", tokens[i].name);
4563 if (!se_access_check(root_sd, &tokens[i].token,
4564 1, &acc_granted, &status)) {
4565 DEBUG(1, ("Could not check root_sd for user %s\n",
4570 if (!NT_STATUS_IS_OK(status))
4573 d_printf(" %s\n", tokens[i].name);
4577 cli_close(cli, fnum);
4589 static void collect_share(const char *name, uint32 m,
4590 const char *comment, void *state)
4592 struct share_list *share_list = (struct share_list *)state;
4594 if (m != STYPE_DISKTREE)
4597 share_list->num_shares += 1;
4598 share_list->shares = SMB_REALLOC_ARRAY(share_list->shares, char *, share_list->num_shares);
4599 if (!share_list->shares) {
4600 share_list->num_shares = 0;
4603 share_list->shares[share_list->num_shares-1] = SMB_STRDUP(name);
4606 static void rpc_share_userlist_usage(void)
4612 * List shares on a remote RPC server, including the security descriptors
4614 * All parameters are provided by the run_rpc_command function, except for
4615 * argc, argv which are passes through.
4617 * @param domain_sid The domain sid acquired from the remote server
4618 * @param cli A cli_state connected to the server.
4619 * @param mem_ctx Talloc context, destoyed on completion of the function.
4620 * @param argc Standard main() style argc
4621 * @param argv Standard main() style argv. Initial components are already
4624 * @return Normal NTSTATUS return.
4627 static NTSTATUS rpc_share_allowedusers_internals(const DOM_SID *domain_sid,
4628 const char *domain_name,
4629 struct cli_state *cli,
4630 struct rpc_pipe_client *pipe_hnd,
4631 TALLOC_CTX *mem_ctx,
4641 struct user_token *tokens = NULL;
4644 struct share_list share_list;
4647 rpc_share_userlist_usage();
4648 return NT_STATUS_UNSUCCESSFUL;
4654 f = fopen(argv[0], "r");
4658 DEBUG(0, ("Could not open userlist: %s\n", strerror(errno)));
4659 return NT_STATUS_UNSUCCESSFUL;
4662 r = get_user_tokens_from_file(f, &num_tokens, &tokens);
4668 DEBUG(0, ("Could not read users from file\n"));
4669 return NT_STATUS_UNSUCCESSFUL;
4672 for (i=0; i<num_tokens; i++)
4673 collect_alias_memberships(&tokens[i].token);
4675 init_enum_hnd(&hnd, 0);
4677 share_list.num_shares = 0;
4678 share_list.shares = NULL;
4680 ret = cli_RNetShareEnum(cli, collect_share, &share_list);
4683 DEBUG(0, ("Error returning browse list: %s\n",
4688 for (i = 0; i < share_list.num_shares; i++) {
4689 char *netname = share_list.shares[i];
4691 if (netname[strlen(netname)-1] == '$')
4694 d_printf("%s\n", netname);
4696 show_userlist(pipe_hnd, mem_ctx, netname,
4697 num_tokens, tokens);
4700 for (i=0; i<num_tokens; i++) {
4701 free_user_token(&tokens[i].token);
4704 SAFE_FREE(share_list.shares);
4706 return NT_STATUS_OK;
4709 static int rpc_share_allowedusers(int argc, const char **argv)
4713 result = run_rpc_command(NULL, PI_SAMR, 0,
4714 rpc_aliaslist_internals,
4719 result = run_rpc_command(NULL, PI_LSARPC, 0,
4725 return run_rpc_command(NULL, PI_SRVSVC, 0,
4726 rpc_share_allowedusers_internals,
4730 int net_usersidlist(int argc, const char **argv)
4733 struct user_token *tokens = NULL;
4737 net_usersidlist_usage(argc, argv);
4741 if (!get_user_tokens(&num_tokens, &tokens)) {
4742 DEBUG(0, ("Could not get the user/sid list\n"));
4746 for (i=0; i<num_tokens; i++) {
4747 dump_user_token(&tokens[i]);
4748 free_user_token(&tokens[i].token);
4755 int net_usersidlist_usage(int argc, const char **argv)
4757 d_printf("net usersidlist\n"
4758 "\tprints out a list of all users the running winbind knows\n"
4759 "\tabout, together with all their SIDs. This is used as\n"
4760 "\tinput to the 'net rpc share allowedusers' command.\n\n");
4762 net_common_flags_usage(argc, argv);
4767 * 'net rpc share' entrypoint.
4768 * @param argc Standard main() style argc
4769 * @param argv Standard main() style argv. Initial components are already
4773 int net_rpc_share(int argc, const char **argv)
4775 struct functable func[] = {
4776 {"add", rpc_share_add},
4777 {"delete", rpc_share_delete},
4778 {"allowedusers", rpc_share_allowedusers},
4779 {"migrate", rpc_share_migrate},
4780 {"list", rpc_share_list},
4785 return run_rpc_command(NULL, PI_SRVSVC, 0,
4786 rpc_share_list_internals,
4789 return net_run_function(argc, argv, func, rpc_share_usage);
4792 static NTSTATUS rpc_sh_share_list(TALLOC_CTX *mem_ctx,
4793 struct rpc_sh_ctx *ctx,
4794 struct rpc_pipe_client *pipe_hnd,
4795 int argc, const char **argv)
4797 return rpc_share_list_internals(ctx->domain_sid, ctx->domain_name,
4798 ctx->cli, pipe_hnd, mem_ctx,
4802 static NTSTATUS rpc_sh_share_add(TALLOC_CTX *mem_ctx,
4803 struct rpc_sh_ctx *ctx,
4804 struct rpc_pipe_client *pipe_hnd,
4805 int argc, const char **argv)
4809 if ((argc < 2) || (argc > 3)) {
4810 d_fprintf(stderr, "usage: %s <share> <path> [comment]\n",
4812 return NT_STATUS_INVALID_PARAMETER;
4815 result = rpccli_srvsvc_net_share_add(
4816 pipe_hnd, mem_ctx, argv[0], STYPE_DISKTREE,
4817 (argc == 3) ? argv[2] : "",
4818 0, 0, 0, argv[1], NULL, 2, NULL);
4820 return werror_to_ntstatus(result);
4823 static NTSTATUS rpc_sh_share_delete(TALLOC_CTX *mem_ctx,
4824 struct rpc_sh_ctx *ctx,
4825 struct rpc_pipe_client *pipe_hnd,
4826 int argc, const char **argv)
4831 d_fprintf(stderr, "usage: %s <share>\n", ctx->whoami);
4832 return NT_STATUS_INVALID_PARAMETER;
4835 result = rpccli_srvsvc_net_share_del(pipe_hnd, mem_ctx, argv[0]);
4836 return werror_to_ntstatus(result);
4839 static NTSTATUS rpc_sh_share_info(TALLOC_CTX *mem_ctx,
4840 struct rpc_sh_ctx *ctx,
4841 struct rpc_pipe_client *pipe_hnd,
4842 int argc, const char **argv)
4844 SRV_SHARE_INFO info;
4845 SRV_SHARE_INFO_2 *info2 = &info.share.info2;
4849 d_fprintf(stderr, "usage: %s <share>\n", ctx->whoami);
4850 return NT_STATUS_INVALID_PARAMETER;
4853 result = rpccli_srvsvc_net_share_get_info(
4854 pipe_hnd, mem_ctx, argv[0], 2, &info);
4855 if (!W_ERROR_IS_OK(result)) {
4859 d_printf("Name: %s\n",
4860 rpcstr_pull_unistr2_talloc(mem_ctx,
4861 &info2->info_2_str.uni_netname));
4862 d_printf("Comment: %s\n",
4863 rpcstr_pull_unistr2_talloc(mem_ctx,
4864 &info2->info_2_str.uni_remark));
4866 d_printf("Path: %s\n",
4867 rpcstr_pull_unistr2_talloc(mem_ctx,
4868 &info2->info_2_str.uni_path));
4869 d_printf("Password: %s\n",
4870 rpcstr_pull_unistr2_talloc(mem_ctx,
4871 &info2->info_2_str.uni_passwd));
4874 return werror_to_ntstatus(result);
4877 struct rpc_sh_cmd *net_rpc_share_cmds(TALLOC_CTX *mem_ctx,
4878 struct rpc_sh_ctx *ctx)
4880 static struct rpc_sh_cmd cmds[] = {
4882 { "list", NULL, PI_SRVSVC, rpc_sh_share_list,
4883 "List available shares" },
4885 { "add", NULL, PI_SRVSVC, rpc_sh_share_add,
4888 { "delete", NULL, PI_SRVSVC, rpc_sh_share_delete,
4891 { "info", NULL, PI_SRVSVC, rpc_sh_share_info,
4892 "Get information about a share" },
4894 { NULL, NULL, 0, NULL, NULL }
4900 /****************************************************************************/
4902 static int rpc_file_usage(int argc, const char **argv)
4904 return net_help_file(argc, argv);
4908 * Close a file on a remote RPC server
4910 * All parameters are provided by the run_rpc_command function, except for
4911 * argc, argv which are passes through.
4913 * @param domain_sid The domain sid acquired from the remote server
4914 * @param cli A cli_state connected to the server.
4915 * @param mem_ctx Talloc context, destoyed on completion of the function.
4916 * @param argc Standard main() style argc
4917 * @param argv Standard main() style argv. Initial components are already
4920 * @return Normal NTSTATUS return.
4922 static NTSTATUS rpc_file_close_internals(const DOM_SID *domain_sid,
4923 const char *domain_name,
4924 struct cli_state *cli,
4925 struct rpc_pipe_client *pipe_hnd,
4926 TALLOC_CTX *mem_ctx,
4930 return rpccli_srvsvc_NetFileClose(pipe_hnd, mem_ctx,
4931 pipe_hnd->cli->desthost,
4932 atoi(argv[0]), NULL);
4936 * Close a file on a remote RPC server
4938 * @param argc Standard main() style argc
4939 * @param argv Standard main() style argv. Initial components are already
4942 * @return A shell status integer (0 for success)
4944 static int rpc_file_close(int argc, const char **argv)
4947 DEBUG(1, ("No fileid given on close\n"));
4948 return(rpc_file_usage(argc, argv));
4951 return run_rpc_command(NULL, PI_SRVSVC, 0,
4952 rpc_file_close_internals,
4957 * Formatted print of open file info
4959 * @param info3 FILE_INFO_3 contents
4960 * @param str3 strings for FILE_INFO_3
4963 static void display_file_info_3( FILE_INFO_3 *info3 )
4965 fstring user = "", path = "";
4967 rpcstr_pull_unistr2_fstring(user, info3->user);
4968 rpcstr_pull_unistr2_fstring(path, info3->path);
4970 d_printf("%-7.1d %-20.20s 0x%-4.2x %-6.1d %s\n",
4971 info3->id, user, info3->perms, info3->num_locks, path);
4975 * List open files on a remote RPC server
4977 * All parameters are provided by the run_rpc_command function, except for
4978 * argc, argv which are passes through.
4980 * @param domain_sid The domain sid acquired from the remote server
4981 * @param cli A cli_state connected to the server.
4982 * @param mem_ctx Talloc context, destoyed on completion of the function.
4983 * @param argc Standard main() style argc
4984 * @param argv Standard main() style argv. Initial components are already
4987 * @return Normal NTSTATUS return.
4990 static NTSTATUS rpc_file_list_internals(const DOM_SID *domain_sid,
4991 const char *domain_name,
4992 struct cli_state *cli,
4993 struct rpc_pipe_client *pipe_hnd,
4994 TALLOC_CTX *mem_ctx,
4998 SRV_FILE_INFO_CTR ctr;
5001 uint32 preferred_len = 0xffffffff, i;
5002 const char *username=NULL;
5004 init_enum_hnd(&hnd, 0);
5006 /* if argc > 0, must be user command */
5008 username = smb_xstrdup(argv[0]);
5010 result = rpccli_srvsvc_net_file_enum(pipe_hnd,
5011 mem_ctx, 3, username, &ctr, preferred_len, &hnd);
5013 if (!W_ERROR_IS_OK(result))
5016 /* Display results */
5019 "\nEnumerating open files on remote server:\n\n"\
5020 "\nFileId Opened by Perms Locks Path"\
5021 "\n------ --------- ----- ----- ---- \n");
5022 for (i = 0; i < ctr.num_entries; i++)
5023 display_file_info_3(&ctr.file.info3[i]);
5025 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
5029 * List files for a user on a remote RPC server
5031 * @param argc Standard main() style argc
5032 * @param argv Standard main() style argv. Initial components are already
5035 * @return A shell status integer (0 for success)
5038 static int rpc_file_user(int argc, const char **argv)
5041 DEBUG(1, ("No username given\n"));
5042 return(rpc_file_usage(argc, argv));
5045 return run_rpc_command(NULL, PI_SRVSVC, 0,
5046 rpc_file_list_internals,
5051 * 'net rpc file' entrypoint.
5052 * @param argc Standard main() style argc
5053 * @param argv Standard main() style argv. Initial components are already
5057 int net_rpc_file(int argc, const char **argv)
5059 struct functable func[] = {
5060 {"close", rpc_file_close},
5061 {"user", rpc_file_user},
5063 {"info", rpc_file_info},
5069 return run_rpc_command(NULL, PI_SRVSVC, 0,
5070 rpc_file_list_internals,
5073 return net_run_function(argc, argv, func, rpc_file_usage);
5077 * ABORT the shutdown of a remote RPC Server over, initshutdown pipe
5079 * All parameters are provided by the run_rpc_command function, except for
5080 * argc, argv which are passed through.
5082 * @param domain_sid The domain sid aquired from the remote server
5083 * @param cli A cli_state connected to the server.
5084 * @param mem_ctx Talloc context, destoyed on compleation of the function.
5085 * @param argc Standard main() style argc
5086 * @param argv Standard main() style argv. Initial components are already
5089 * @return Normal NTSTATUS return.
5092 static NTSTATUS rpc_shutdown_abort_internals(const DOM_SID *domain_sid,
5093 const char *domain_name,
5094 struct cli_state *cli,
5095 struct rpc_pipe_client *pipe_hnd,
5096 TALLOC_CTX *mem_ctx,
5100 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
5102 result = rpccli_initshutdown_Abort(pipe_hnd, mem_ctx, NULL, NULL);
5104 if (NT_STATUS_IS_OK(result)) {
5105 d_printf("\nShutdown successfully aborted\n");
5106 DEBUG(5,("cmd_shutdown_abort: query succeeded\n"));
5108 DEBUG(5,("cmd_shutdown_abort: query failed\n"));
5114 * ABORT the shutdown of a remote RPC Server, over winreg pipe
5116 * All parameters are provided by the run_rpc_command function, except for
5117 * argc, argv which are passed through.
5119 * @param domain_sid The domain sid aquired from the remote server
5120 * @param cli A cli_state connected to the server.
5121 * @param mem_ctx Talloc context, destoyed on compleation of the function.
5122 * @param argc Standard main() style argc
5123 * @param argv Standard main() style argv. Initial components are already
5126 * @return Normal NTSTATUS return.
5129 static NTSTATUS rpc_reg_shutdown_abort_internals(const DOM_SID *domain_sid,
5130 const char *domain_name,
5131 struct cli_state *cli,
5132 struct rpc_pipe_client *pipe_hnd,
5133 TALLOC_CTX *mem_ctx,
5137 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
5139 result = rpccli_winreg_AbortSystemShutdown(pipe_hnd, mem_ctx, NULL, NULL);
5141 if (NT_STATUS_IS_OK(result)) {
5142 d_printf("\nShutdown successfully aborted\n");
5143 DEBUG(5,("cmd_reg_abort_shutdown: query succeeded\n"));
5145 DEBUG(5,("cmd_reg_abort_shutdown: query failed\n"));
5151 * ABORT the Shut down of a remote RPC server
5153 * @param argc Standard main() style argc
5154 * @param argv Standard main() style argv. Initial components are already
5157 * @return A shell status integer (0 for success)
5160 static int rpc_shutdown_abort(int argc, const char **argv)
5162 int rc = run_rpc_command(NULL, PI_INITSHUTDOWN, 0,
5163 rpc_shutdown_abort_internals,
5169 DEBUG(1, ("initshutdown pipe didn't work, trying winreg pipe\n"));
5171 return run_rpc_command(NULL, PI_WINREG, 0,
5172 rpc_reg_shutdown_abort_internals,
5177 * Shut down a remote RPC Server via initshutdown pipe
5179 * All parameters are provided by the run_rpc_command function, except for
5180 * argc, argv which are passes through.
5182 * @param domain_sid The domain sid aquired from the remote server
5183 * @param cli A cli_state connected to the server.
5184 * @param mem_ctx Talloc context, destoyed on compleation of the function.
5185 * @param argc Standard main() style argc
5186 * @param argc Standard main() style argv. Initial components are already
5189 * @return Normal NTSTATUS return.
5192 NTSTATUS rpc_init_shutdown_internals(const DOM_SID *domain_sid,
5193 const char *domain_name,
5194 struct cli_state *cli,
5195 struct rpc_pipe_client *pipe_hnd,
5196 TALLOC_CTX *mem_ctx,
5200 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
5201 const char *msg = "This machine will be shutdown shortly";
5202 uint32 timeout = 20;
5203 struct initshutdown_String msg_string;
5204 struct initshutdown_String_sub s;
5210 timeout = opt_timeout;
5214 msg_string.name = &s;
5216 /* create an entry */
5217 result = rpccli_initshutdown_Init(pipe_hnd, mem_ctx, NULL,
5218 &msg_string, timeout, opt_force, opt_reboot, NULL);
5220 if (NT_STATUS_IS_OK(result)) {
5221 d_printf("\nShutdown of remote machine succeeded\n");
5222 DEBUG(5,("Shutdown of remote machine succeeded\n"));
5224 DEBUG(1,("Shutdown of remote machine failed!\n"));
5230 * Shut down a remote RPC Server via winreg pipe
5232 * All parameters are provided by the run_rpc_command function, except for
5233 * argc, argv which are passes through.
5235 * @param domain_sid The domain sid aquired from the remote server
5236 * @param cli A cli_state connected to the server.
5237 * @param mem_ctx Talloc context, destoyed on compleation of the function.
5238 * @param argc Standard main() style argc
5239 * @param argc Standard main() style argv. Initial components are already
5242 * @return Normal NTSTATUS return.
5245 NTSTATUS rpc_reg_shutdown_internals(const DOM_SID *domain_sid,
5246 const char *domain_name,
5247 struct cli_state *cli,
5248 struct rpc_pipe_client *pipe_hnd,
5249 TALLOC_CTX *mem_ctx,
5253 const char *msg = "This machine will be shutdown shortly";
5254 uint32 timeout = 20;
5255 struct initshutdown_String msg_string;
5256 struct initshutdown_String_sub s;
5264 msg_string.name = &s;
5267 timeout = opt_timeout;
5270 /* create an entry */
5271 result = rpccli_winreg_InitiateSystemShutdown(pipe_hnd, mem_ctx, NULL,
5272 &msg_string, timeout, opt_force, opt_reboot, &werr);
5274 if (NT_STATUS_IS_OK(result)) {
5275 d_printf("\nShutdown of remote machine succeeded\n");
5277 d_fprintf(stderr, "\nShutdown of remote machine failed\n");
5278 if ( W_ERROR_EQUAL(werr, WERR_MACHINE_LOCKED) )
5279 d_fprintf(stderr, "\nMachine locked, use -f switch to force\n");
5281 d_fprintf(stderr, "\nresult was: %s\n", dos_errstr(werr));
5288 * Shut down a remote RPC server
5290 * @param argc Standard main() style argc
5291 * @param argc Standard main() style argv. Initial components are already
5294 * @return A shell status integer (0 for success)
5297 static int rpc_shutdown(int argc, const char **argv)
5299 int rc = run_rpc_command(NULL, PI_INITSHUTDOWN, 0,
5300 rpc_init_shutdown_internals,
5304 DEBUG(1, ("initshutdown pipe failed, trying winreg pipe\n"));
5305 rc = run_rpc_command(NULL, PI_WINREG, 0,
5306 rpc_reg_shutdown_internals, argc, argv);
5312 /***************************************************************************
5313 NT Domain trusts code (i.e. 'net rpc trustdom' functionality)
5315 ***************************************************************************/
5318 * Add interdomain trust account to the RPC server.
5319 * All parameters (except for argc and argv) are passed by run_rpc_command
5322 * @param domain_sid The domain sid acquired from the server
5323 * @param cli A cli_state connected to the server.
5324 * @param mem_ctx Talloc context, destoyed on completion of the function.
5325 * @param argc Standard main() style argc
5326 * @param argc Standard main() style argv. Initial components are already
5329 * @return normal NTSTATUS return code
5332 static NTSTATUS rpc_trustdom_add_internals(const DOM_SID *domain_sid,
5333 const char *domain_name,
5334 struct cli_state *cli,
5335 struct rpc_pipe_client *pipe_hnd,
5336 TALLOC_CTX *mem_ctx,
5340 POLICY_HND connect_pol, domain_pol, user_pol;
5341 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
5344 uint32 unknown, user_rid;
5347 d_printf("Usage: net rpc trustdom add <domain_name> <pw>\n");
5348 return NT_STATUS_INVALID_PARAMETER;
5352 * Make valid trusting domain account (ie. uppercased and with '$' appended)
5355 if (asprintf(&acct_name, "%s$", argv[0]) < 0) {
5356 return NT_STATUS_NO_MEMORY;
5359 strupper_m(acct_name);
5361 /* Get samr policy handle */
5362 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
5364 if (!NT_STATUS_IS_OK(result)) {
5368 /* Get domain policy handle */
5369 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
5370 MAXIMUM_ALLOWED_ACCESS,
5371 domain_sid, &domain_pol);
5372 if (!NT_STATUS_IS_OK(result)) {
5376 /* Create trusting domain's account */
5377 acb_info = ACB_NORMAL;
5378 unknown = 0xe00500b0; /* No idea what this is - a permission mask?
5379 mimir: yes, most probably it is */
5381 result = rpccli_samr_create_dom_user(pipe_hnd, mem_ctx, &domain_pol,
5382 acct_name, acb_info, unknown,
5383 &user_pol, &user_rid);
5384 if (!NT_STATUS_IS_OK(result)) {
5389 SAM_USERINFO_CTR ctr;
5390 SAM_USER_INFO_23 p23;
5396 encode_pw_buffer(pwbuf, argv[1], STR_UNICODE);
5400 ZERO_STRUCT(notime);
5404 memset(hrs.hours, 0xFF, sizeof(hrs.hours));
5405 acb_info = ACB_DOMTRUST;
5407 init_sam_user_info23A(&p23, ¬ime, ¬ime, ¬ime,
5408 ¬ime, ¬ime, ¬ime,
5409 nostr, nostr, nostr, nostr, nostr,
5410 nostr, nostr, nostr, nostr, nostr,
5411 0, 0, acb_info, ACCT_FLAGS, 168, &hrs,
5412 0, 0, (char *)pwbuf);
5413 ctr.switch_value = 23;
5414 ctr.info.id23 = &p23;
5415 p23.passmustchange = 0;
5417 result = rpccli_samr_set_userinfo(pipe_hnd, mem_ctx, &user_pol, 23,
5418 &cli->user_session_key, &ctr);
5420 if (!NT_STATUS_IS_OK(result)) {
5421 DEBUG(0,("Could not set trust account password: %s\n",
5422 nt_errstr(result)));
5428 SAFE_FREE(acct_name);
5433 * Create interdomain trust account for a remote domain.
5435 * @param argc standard argc
5436 * @param argv standard argv without initial components
5438 * @return Integer status (0 means success)
5441 static int rpc_trustdom_add(int argc, const char **argv)
5444 return run_rpc_command(NULL, PI_SAMR, 0, rpc_trustdom_add_internals,
5447 d_printf("Usage: net rpc trustdom add <domain>\n");
5454 * Remove interdomain trust account from the RPC server.
5455 * All parameters (except for argc and argv) are passed by run_rpc_command
5458 * @param domain_sid The domain sid acquired from the server
5459 * @param cli A cli_state connected to the server.
5460 * @param mem_ctx Talloc context, destoyed on completion of the function.
5461 * @param argc Standard main() style argc
5462 * @param argc Standard main() style argv. Initial components are already
5465 * @return normal NTSTATUS return code
5468 static NTSTATUS rpc_trustdom_del_internals(const DOM_SID *domain_sid,
5469 const char *domain_name,
5470 struct cli_state *cli,
5471 struct rpc_pipe_client *pipe_hnd,
5472 TALLOC_CTX *mem_ctx,
5476 POLICY_HND connect_pol, domain_pol, user_pol;
5477 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
5480 DOM_SID trust_acct_sid;
5481 uint32 *user_rids, num_rids, *name_types;
5482 uint32 flags = 0x000003e8; /* Unknown */
5485 d_printf("Usage: net rpc trustdom del <domain_name>\n");
5486 return NT_STATUS_INVALID_PARAMETER;
5490 * Make valid trusting domain account (ie. uppercased and with '$' appended)
5492 acct_name = talloc_asprintf(mem_ctx, "%s$", argv[0]);
5494 if (acct_name == NULL)
5495 return NT_STATUS_NO_MEMORY;
5497 strupper_m(acct_name);
5499 if ((names = TALLOC_ARRAY(mem_ctx, const char *, 1)) == NULL) {
5500 return NT_STATUS_NO_MEMORY;
5502 names[0] = acct_name;
5505 /* Get samr policy handle */
5506 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
5508 if (!NT_STATUS_IS_OK(result)) {
5512 /* Get domain policy handle */
5513 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
5514 MAXIMUM_ALLOWED_ACCESS,
5515 domain_sid, &domain_pol);
5516 if (!NT_STATUS_IS_OK(result)) {
5520 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, flags, 1,
5522 &user_rids, &name_types);
5524 if (!NT_STATUS_IS_OK(result)) {
5528 result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
5529 MAXIMUM_ALLOWED_ACCESS,
5530 user_rids[0], &user_pol);
5532 if (!NT_STATUS_IS_OK(result)) {
5536 /* append the rid to the domain sid */
5537 sid_copy(&trust_acct_sid, domain_sid);
5538 if (!sid_append_rid(&trust_acct_sid, user_rids[0])) {
5542 /* remove the sid */
5544 result = rpccli_samr_remove_sid_foreign_domain(pipe_hnd, mem_ctx, &user_pol,
5547 if (!NT_STATUS_IS_OK(result)) {
5553 result = rpccli_samr_delete_dom_user(pipe_hnd, mem_ctx, &user_pol);
5555 if (!NT_STATUS_IS_OK(result)) {
5559 if (!NT_STATUS_IS_OK(result)) {
5560 DEBUG(0,("Could not set trust account password: %s\n",
5561 nt_errstr(result)));
5570 * Delete interdomain trust account for a remote domain.
5572 * @param argc standard argc
5573 * @param argv standard argv without initial components
5575 * @return Integer status (0 means success)
5578 static int rpc_trustdom_del(int argc, const char **argv)
5581 return run_rpc_command(NULL, PI_SAMR, 0, rpc_trustdom_del_internals,
5584 d_printf("Usage: net rpc trustdom del <domain>\n");
5591 * Establish trust relationship to a trusting domain.
5592 * Interdomain account must already be created on remote PDC.
5594 * @param argc standard argc
5595 * @param argv standard argv without initial components
5597 * @return Integer status (0 means success)
5600 static int rpc_trustdom_establish(int argc, const char **argv)
5602 struct cli_state *cli = NULL;
5603 struct sockaddr_storage server_ss;
5604 struct rpc_pipe_client *pipe_hnd = NULL;
5605 POLICY_HND connect_hnd;
5606 TALLOC_CTX *mem_ctx;
5608 DOM_SID *domain_sid;
5611 const char* domain_name_pol;
5617 * Connect to \\server\ipc$ as 'our domain' account with password
5621 d_printf("Usage: net rpc trustdom establish <domain_name>\n");
5625 domain_name = smb_xstrdup(argv[0]);
5626 strupper_m(domain_name);
5628 /* account name used at first is our domain's name with '$' */
5629 asprintf(&acct_name, "%s$", lp_workgroup());
5630 strupper_m(acct_name);
5633 * opt_workgroup will be used by connection functions further,
5634 * hence it should be set to remote domain name instead of ours
5636 if (opt_workgroup) {
5637 opt_workgroup = smb_xstrdup(domain_name);
5640 opt_user_name = acct_name;
5642 /* find the domain controller */
5643 if (!net_find_pdc(&server_ss, pdc_name, domain_name)) {
5644 DEBUG(0, ("Couldn't find domain controller for domain %s\n", domain_name));
5648 /* connect to ipc$ as username/password */
5649 nt_status = connect_to_ipc(&cli, &server_ss, pdc_name);
5650 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT)) {
5652 /* Is it trusting domain account for sure ? */
5653 DEBUG(0, ("Couldn't verify trusting domain account. Error was %s\n",
5654 nt_errstr(nt_status)));
5658 /* store who we connected to */
5660 saf_store( domain_name, pdc_name );
5663 * Connect to \\server\ipc$ again (this time anonymously)
5666 nt_status = connect_to_ipc_anonymous(&cli, &server_ss, (char*)pdc_name);
5668 if (NT_STATUS_IS_ERR(nt_status)) {
5669 DEBUG(0, ("Couldn't connect to domain %s controller. Error was %s.\n",
5670 domain_name, nt_errstr(nt_status)));
5675 * Use NetServerEnum2 to make sure we're talking to a proper server
5678 if (!cli_get_pdc_name(cli, domain_name, &dc_name)) {
5679 DEBUG(0, ("NetServerEnum2 error: Couldn't find primary domain controller\
5680 for domain %s\n", domain_name));
5686 if (!(mem_ctx = talloc_init("establishing trust relationship to "
5687 "domain %s", domain_name))) {
5688 DEBUG(0, ("talloc_init() failed\n"));
5694 * Call LsaOpenPolicy and LsaQueryInfo
5697 pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_LSARPC, &nt_status);
5699 DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n", nt_errstr(nt_status) ));
5701 talloc_destroy(mem_ctx);
5705 nt_status = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, True, SEC_RIGHTS_QUERY_VALUE,
5707 if (NT_STATUS_IS_ERR(nt_status)) {
5708 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
5709 nt_errstr(nt_status)));
5711 talloc_destroy(mem_ctx);
5715 /* Querying info level 5 */
5717 nt_status = rpccli_lsa_query_info_policy(pipe_hnd, mem_ctx, &connect_hnd,
5719 &domain_name_pol, &domain_sid);
5720 if (NT_STATUS_IS_ERR(nt_status)) {
5721 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
5722 nt_errstr(nt_status)));
5724 talloc_destroy(mem_ctx);
5728 /* There should be actually query info level 3 (following nt serv behaviour),
5729 but I still don't know if it's _really_ necessary */
5732 * Store the password in secrets db
5735 if (!pdb_set_trusteddom_pw(domain_name, opt_password, domain_sid)) {
5736 DEBUG(0, ("Storing password for trusted domain failed.\n"));
5738 talloc_destroy(mem_ctx);
5743 * Close the pipes and clean up
5746 nt_status = rpccli_lsa_Close(pipe_hnd, mem_ctx, &connect_hnd);
5747 if (NT_STATUS_IS_ERR(nt_status)) {
5748 DEBUG(0, ("Couldn't close LSA pipe. Error was %s\n",
5749 nt_errstr(nt_status)));
5751 talloc_destroy(mem_ctx);
5757 talloc_destroy(mem_ctx);
5759 d_printf("Trust to domain %s established\n", domain_name);
5764 * Revoke trust relationship to the remote domain
5766 * @param argc standard argc
5767 * @param argv standard argv without initial components
5769 * @return Integer status (0 means success)
5772 static int rpc_trustdom_revoke(int argc, const char **argv)
5777 if (argc < 1) return -1;
5779 /* generate upper cased domain name */
5780 domain_name = smb_xstrdup(argv[0]);
5781 strupper_m(domain_name);
5783 /* delete password of the trust */
5784 if (!pdb_del_trusteddom_pw(domain_name)) {
5785 DEBUG(0, ("Failed to revoke relationship to the trusted domain %s\n",
5792 SAFE_FREE(domain_name);
5797 * Usage for 'net rpc trustdom' command
5799 * @param argc standard argc
5800 * @param argv standard argv without inital components
5802 * @return Integer status returned to shell
5805 static int rpc_trustdom_usage(int argc, const char **argv)
5807 d_printf(" net rpc trustdom add \t\t add trusting domain's account\n");
5808 d_printf(" net rpc trustdom del \t\t delete trusting domain's account\n");
5809 d_printf(" net rpc trustdom establish \t establish relationship to trusted domain\n");
5810 d_printf(" net rpc trustdom revoke \t abandon relationship to trusted domain\n");
5811 d_printf(" net rpc trustdom list \t show current interdomain trust relationships\n");
5812 d_printf(" net rpc trustdom vampire \t vampire interdomain trust relationships from remote server\n");
5817 static NTSTATUS rpc_query_domain_sid(const DOM_SID *domain_sid,
5818 const char *domain_name,
5819 struct cli_state *cli,
5820 struct rpc_pipe_client *pipe_hnd,
5821 TALLOC_CTX *mem_ctx,
5826 sid_to_fstring(str_sid, domain_sid);
5827 d_printf("%s\n", str_sid);
5828 return NT_STATUS_OK;
5831 static void print_trusted_domain(DOM_SID *dom_sid, const char *trusted_dom_name)
5833 fstring ascii_sid, padding;
5834 int pad_len, col_len = 20;
5836 /* convert sid into ascii string */
5837 sid_to_fstring(ascii_sid, dom_sid);
5839 /* calculate padding space for d_printf to look nicer */
5840 pad_len = col_len - strlen(trusted_dom_name);
5841 padding[pad_len] = 0;
5842 do padding[--pad_len] = ' '; while (pad_len);
5844 d_printf("%s%s%s\n", trusted_dom_name, padding, ascii_sid);
5847 static NTSTATUS vampire_trusted_domain(struct rpc_pipe_client *pipe_hnd,
5848 TALLOC_CTX *mem_ctx,
5851 const char *trusted_dom_name)
5854 union lsa_TrustedDomainInfo info;
5855 char *cleartextpwd = NULL;
5858 nt_status = rpccli_lsa_QueryTrustedDomainInfoBySid(pipe_hnd, mem_ctx,
5861 LSA_TRUSTED_DOMAIN_INFO_PASSWORD,
5863 if (NT_STATUS_IS_ERR(nt_status)) {
5864 DEBUG(0,("Could not query trusted domain info. Error was %s\n",
5865 nt_errstr(nt_status)));
5869 data = data_blob(NULL, info.password.password->length);
5872 info.password.password->data,
5873 info.password.password->length);
5874 data.length = info.password.password->length;
5876 cleartextpwd = decrypt_trustdom_secret(pipe_hnd->cli->pwd.password,
5879 if (cleartextpwd == NULL) {
5880 DEBUG(0,("retrieved NULL password\n"));
5881 nt_status = NT_STATUS_UNSUCCESSFUL;
5885 if (!pdb_set_trusteddom_pw(trusted_dom_name, cleartextpwd, &dom_sid)) {
5886 DEBUG(0, ("Storing password for trusted domain failed.\n"));
5887 nt_status = NT_STATUS_UNSUCCESSFUL;
5891 #ifdef DEBUG_PASSWORD
5892 DEBUG(100,("sucessfully vampired trusted domain [%s], sid: [%s], "
5893 "password: [%s]\n", trusted_dom_name,
5894 sid_string_dbg(&dom_sid), cleartextpwd));
5898 SAFE_FREE(cleartextpwd);
5899 data_blob_free(&data);
5904 static int rpc_trustdom_vampire(int argc, const char **argv)
5906 /* common variables */
5907 TALLOC_CTX* mem_ctx;
5908 struct cli_state *cli = NULL;
5909 struct rpc_pipe_client *pipe_hnd = NULL;
5911 const char *domain_name = NULL;
5912 DOM_SID *queried_dom_sid;
5913 POLICY_HND connect_hnd;
5915 /* trusted domains listing variables */
5916 unsigned int num_domains, enum_ctx = 0;
5918 DOM_SID *domain_sids;
5919 char **trusted_dom_names;
5924 * Listing trusted domains (stored in secrets.tdb, if local)
5927 mem_ctx = talloc_init("trust relationships vampire");
5930 * set domain and pdc name to local samba server (default)
5931 * or to remote one given in command line
5934 if (StrCaseCmp(opt_workgroup, lp_workgroup())) {
5935 domain_name = opt_workgroup;
5936 opt_target_workgroup = opt_workgroup;
5938 fstrcpy(pdc_name, global_myname());
5939 domain_name = talloc_strdup(mem_ctx, lp_workgroup());
5940 opt_target_workgroup = domain_name;
5943 /* open \PIPE\lsarpc and open policy handle */
5944 nt_status = net_make_ipc_connection(NET_FLAGS_PDC, &cli);
5945 if (!NT_STATUS_IS_OK(nt_status)) {
5946 DEBUG(0, ("Couldn't connect to domain controller: %s\n",
5947 nt_errstr(nt_status)));
5948 talloc_destroy(mem_ctx);
5952 pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_LSARPC, &nt_status);
5954 DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n",
5955 nt_errstr(nt_status) ));
5957 talloc_destroy(mem_ctx);
5961 nt_status = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, False, SEC_RIGHTS_QUERY_VALUE,
5963 if (NT_STATUS_IS_ERR(nt_status)) {
5964 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
5965 nt_errstr(nt_status)));
5967 talloc_destroy(mem_ctx);
5971 /* query info level 5 to obtain sid of a domain being queried */
5972 nt_status = rpccli_lsa_query_info_policy(
5973 pipe_hnd, mem_ctx, &connect_hnd, 5 /* info level */,
5974 &dummy, &queried_dom_sid);
5976 if (NT_STATUS_IS_ERR(nt_status)) {
5977 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
5978 nt_errstr(nt_status)));
5980 talloc_destroy(mem_ctx);
5985 * Keep calling LsaEnumTrustdom over opened pipe until
5986 * the end of enumeration is reached
5989 d_printf("Vampire trusted domains:\n\n");
5992 nt_status = rpccli_lsa_enum_trust_dom(pipe_hnd, mem_ctx, &connect_hnd, &enum_ctx,
5994 &trusted_dom_names, &domain_sids);
5996 if (NT_STATUS_IS_ERR(nt_status)) {
5997 DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
5998 nt_errstr(nt_status)));
6000 talloc_destroy(mem_ctx);
6004 for (i = 0; i < num_domains; i++) {
6006 print_trusted_domain(&(domain_sids[i]), trusted_dom_names[i]);
6008 nt_status = vampire_trusted_domain(pipe_hnd, mem_ctx, &connect_hnd,
6009 domain_sids[i], trusted_dom_names[i]);
6010 if (!NT_STATUS_IS_OK(nt_status)) {
6012 talloc_destroy(mem_ctx);
6018 * in case of no trusted domains say something rather
6019 * than just display blank line
6021 if (!num_domains) d_printf("none\n");
6023 } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
6025 /* close this connection before doing next one */
6026 nt_status = rpccli_lsa_Close(pipe_hnd, mem_ctx, &connect_hnd);
6027 if (NT_STATUS_IS_ERR(nt_status)) {
6028 DEBUG(0, ("Couldn't properly close lsa policy handle. Error was %s\n",
6029 nt_errstr(nt_status)));
6031 talloc_destroy(mem_ctx);
6035 /* close lsarpc pipe and connection to IPC$ */
6038 talloc_destroy(mem_ctx);
6042 static int rpc_trustdom_list(int argc, const char **argv)
6044 /* common variables */
6045 TALLOC_CTX* mem_ctx;
6046 struct cli_state *cli = NULL, *remote_cli = NULL;
6047 struct rpc_pipe_client *pipe_hnd = NULL;
6049 const char *domain_name = NULL;
6050 DOM_SID *queried_dom_sid;
6052 int ascii_dom_name_len;
6053 POLICY_HND connect_hnd;
6055 /* trusted domains listing variables */
6056 unsigned int num_domains, enum_ctx = 0;
6057 int i, pad_len, col_len = 20;
6058 DOM_SID *domain_sids;
6059 char **trusted_dom_names;
6063 /* trusting domains listing variables */
6064 POLICY_HND domain_hnd;
6065 char **trusting_dom_names;
6066 uint32 *trusting_dom_rids;
6069 * Listing trusted domains (stored in secrets.tdb, if local)
6072 mem_ctx = talloc_init("trust relationships listing");
6075 * set domain and pdc name to local samba server (default)
6076 * or to remote one given in command line
6079 if (StrCaseCmp(opt_workgroup, lp_workgroup())) {
6080 domain_name = opt_workgroup;
6081 opt_target_workgroup = opt_workgroup;
6083 fstrcpy(pdc_name, global_myname());
6084 domain_name = talloc_strdup(mem_ctx, lp_workgroup());
6085 opt_target_workgroup = domain_name;
6088 /* open \PIPE\lsarpc and open policy handle */
6089 nt_status = net_make_ipc_connection(NET_FLAGS_PDC, &cli);
6090 if (!NT_STATUS_IS_OK(nt_status)) {
6091 DEBUG(0, ("Couldn't connect to domain controller: %s\n",
6092 nt_errstr(nt_status)));
6093 talloc_destroy(mem_ctx);
6097 pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_LSARPC, &nt_status);
6099 DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n",
6100 nt_errstr(nt_status) ));
6102 talloc_destroy(mem_ctx);
6106 nt_status = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, False, SEC_RIGHTS_QUERY_VALUE,
6108 if (NT_STATUS_IS_ERR(nt_status)) {
6109 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
6110 nt_errstr(nt_status)));
6112 talloc_destroy(mem_ctx);
6116 /* query info level 5 to obtain sid of a domain being queried */
6117 nt_status = rpccli_lsa_query_info_policy(
6118 pipe_hnd, mem_ctx, &connect_hnd, 5 /* info level */,
6119 &dummy, &queried_dom_sid);
6121 if (NT_STATUS_IS_ERR(nt_status)) {
6122 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
6123 nt_errstr(nt_status)));
6125 talloc_destroy(mem_ctx);
6130 * Keep calling LsaEnumTrustdom over opened pipe until
6131 * the end of enumeration is reached
6134 d_printf("Trusted domains list:\n\n");
6137 nt_status = rpccli_lsa_enum_trust_dom(pipe_hnd, mem_ctx, &connect_hnd, &enum_ctx,
6139 &trusted_dom_names, &domain_sids);
6141 if (NT_STATUS_IS_ERR(nt_status)) {
6142 DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
6143 nt_errstr(nt_status)));
6145 talloc_destroy(mem_ctx);
6149 for (i = 0; i < num_domains; i++) {
6150 print_trusted_domain(&(domain_sids[i]), trusted_dom_names[i]);
6154 * in case of no trusted domains say something rather
6155 * than just display blank line
6157 if (!num_domains) d_printf("none\n");
6159 } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
6161 /* close this connection before doing next one */
6162 nt_status = rpccli_lsa_Close(pipe_hnd, mem_ctx, &connect_hnd);
6163 if (NT_STATUS_IS_ERR(nt_status)) {
6164 DEBUG(0, ("Couldn't properly close lsa policy handle. Error was %s\n",
6165 nt_errstr(nt_status)));
6167 talloc_destroy(mem_ctx);
6171 cli_rpc_pipe_close(pipe_hnd);
6174 * Listing trusting domains (stored in passdb backend, if local)
6177 d_printf("\nTrusting domains list:\n\n");
6180 * Open \PIPE\samr and get needed policy handles
6182 pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SAMR, &nt_status);
6184 DEBUG(0, ("Could not initialise samr pipe. Error was %s\n", nt_errstr(nt_status)));
6186 talloc_destroy(mem_ctx);
6191 nt_status = rpccli_samr_connect(pipe_hnd, mem_ctx, SA_RIGHT_SAM_OPEN_DOMAIN,
6193 if (!NT_STATUS_IS_OK(nt_status)) {
6194 DEBUG(0, ("Couldn't open SAMR policy handle. Error was %s\n",
6195 nt_errstr(nt_status)));
6197 talloc_destroy(mem_ctx);
6201 /* SamrOpenDomain - we have to open domain policy handle in order to be
6202 able to enumerate accounts*/
6203 nt_status = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_hnd,
6204 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
6205 queried_dom_sid, &domain_hnd);
6206 if (!NT_STATUS_IS_OK(nt_status)) {
6207 DEBUG(0, ("Couldn't open domain object. Error was %s\n",
6208 nt_errstr(nt_status)));
6210 talloc_destroy(mem_ctx);
6215 * perform actual enumeration
6218 enum_ctx = 0; /* reset enumeration context from last enumeration */
6221 nt_status = rpccli_samr_enum_dom_users(pipe_hnd, mem_ctx, &domain_hnd,
6222 &enum_ctx, ACB_DOMTRUST, 0xffff,
6223 &trusting_dom_names, &trusting_dom_rids,
6225 if (NT_STATUS_IS_ERR(nt_status)) {
6226 DEBUG(0, ("Couldn't enumerate accounts. Error was: %s\n",
6227 nt_errstr(nt_status)));
6229 talloc_destroy(mem_ctx);
6233 for (i = 0; i < num_domains; i++) {
6236 * get each single domain's sid (do we _really_ need this ?):
6237 * 1) connect to domain's pdc
6238 * 2) query the pdc for domain's sid
6241 /* get rid of '$' tail */
6242 ascii_dom_name_len = strlen(trusting_dom_names[i]);
6243 if (ascii_dom_name_len && ascii_dom_name_len < FSTRING_LEN)
6244 trusting_dom_names[i][ascii_dom_name_len - 1] = '\0';
6246 /* calculate padding space for d_printf to look nicer */
6247 pad_len = col_len - strlen(trusting_dom_names[i]);
6248 padding[pad_len] = 0;
6249 do padding[--pad_len] = ' '; while (pad_len);
6251 /* set opt_* variables to remote domain */
6252 strupper_m(trusting_dom_names[i]);
6253 opt_workgroup = talloc_strdup(mem_ctx, trusting_dom_names[i]);
6254 opt_target_workgroup = opt_workgroup;
6256 d_printf("%s%s", trusting_dom_names[i], padding);
6258 /* connect to remote domain controller */
6259 nt_status = net_make_ipc_connection(
6260 NET_FLAGS_PDC | NET_FLAGS_ANONYMOUS,
6262 if (NT_STATUS_IS_OK(nt_status)) {
6263 /* query for domain's sid */
6264 if (run_rpc_command(remote_cli, PI_LSARPC, 0, rpc_query_domain_sid, argc, argv))
6265 d_fprintf(stderr, "couldn't get domain's sid\n");
6267 cli_shutdown(remote_cli);
6270 d_fprintf(stderr, "domain controller is not "
6272 nt_errstr(nt_status));
6276 if (!num_domains) d_printf("none\n");
6278 } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
6280 /* close opened samr and domain policy handles */
6281 nt_status = rpccli_samr_close(pipe_hnd, mem_ctx, &domain_hnd);
6282 if (!NT_STATUS_IS_OK(nt_status)) {
6283 DEBUG(0, ("Couldn't properly close domain policy handle for domain %s\n", domain_name));
6286 nt_status = rpccli_samr_close(pipe_hnd, mem_ctx, &connect_hnd);
6287 if (!NT_STATUS_IS_OK(nt_status)) {
6288 DEBUG(0, ("Couldn't properly close samr policy handle for domain %s\n", domain_name));
6291 /* close samr pipe and connection to IPC$ */
6294 talloc_destroy(mem_ctx);
6299 * Entrypoint for 'net rpc trustdom' code
6301 * @param argc standard argc
6302 * @param argv standard argv without initial components
6304 * @return Integer status (0 means success)
6307 static int rpc_trustdom(int argc, const char **argv)
6309 struct functable func[] = {
6310 {"add", rpc_trustdom_add},
6311 {"del", rpc_trustdom_del},
6312 {"establish", rpc_trustdom_establish},
6313 {"revoke", rpc_trustdom_revoke},
6314 {"help", rpc_trustdom_usage},
6315 {"list", rpc_trustdom_list},
6316 {"vampire", rpc_trustdom_vampire},
6321 rpc_trustdom_usage(argc, argv);
6325 return (net_run_function(argc, argv, func, rpc_user_usage));
6329 * Check if a server will take rpc commands
6330 * @param flags Type of server to connect to (PDC, DMB, localhost)
6331 * if the host is not explicitly specified
6332 * @return bool (true means rpc supported)
6334 bool net_rpc_check(unsigned flags)
6336 struct cli_state *cli;
6338 struct sockaddr_storage server_ss;
6339 char *server_name = NULL;
6342 /* flags (i.e. server type) may depend on command */
6343 if (!net_find_server(NULL, flags, &server_ss, &server_name))
6346 if ((cli = cli_initialise()) == NULL) {
6350 status = cli_connect(cli, server_name, &server_ss);
6351 if (!NT_STATUS_IS_OK(status))
6353 if (!attempt_netbios_session_request(&cli, global_myname(),
6354 server_name, &server_ss))
6356 if (!cli_negprot(cli))
6358 if (cli->protocol < PROTOCOL_NT1)
6367 /* dump sam database via samsync rpc calls */
6368 static int rpc_samdump(int argc, const char **argv) {
6369 return run_rpc_command(NULL, PI_NETLOGON, NET_FLAGS_ANONYMOUS, rpc_samdump_internals,
6373 /* syncronise sam database via samsync rpc calls */
6374 static int rpc_vampire(int argc, const char **argv) {
6375 return run_rpc_command(NULL, PI_NETLOGON, NET_FLAGS_ANONYMOUS, rpc_vampire_internals,
6380 * Migrate everything from a print-server
6382 * @param argc Standard main() style argc
6383 * @param argv Standard main() style argv. Initial components are already
6386 * @return A shell status integer (0 for success)
6388 * The order is important !
6389 * To successfully add drivers the print-queues have to exist !
6390 * Applying ACLs should be the last step, because you're easily locked out
6393 static int rpc_printer_migrate_all(int argc, const char **argv)
6398 printf("no server to migrate\n");
6402 ret = run_rpc_command(NULL, PI_SPOOLSS, 0, rpc_printer_migrate_printers_internals, argc, argv);
6406 ret = run_rpc_command(NULL, PI_SPOOLSS, 0, rpc_printer_migrate_drivers_internals, argc, argv);
6410 ret = run_rpc_command(NULL, PI_SPOOLSS, 0, rpc_printer_migrate_forms_internals, argc, argv);
6414 ret = run_rpc_command(NULL, PI_SPOOLSS, 0, rpc_printer_migrate_settings_internals, argc, argv);
6418 return run_rpc_command(NULL, PI_SPOOLSS, 0, rpc_printer_migrate_security_internals, argc, argv);
6423 * Migrate print-drivers from a print-server
6425 * @param argc Standard main() style argc
6426 * @param argv Standard main() style argv. Initial components are already
6429 * @return A shell status integer (0 for success)
6431 static int rpc_printer_migrate_drivers(int argc, const char **argv)
6434 printf("no server to migrate\n");
6438 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6439 rpc_printer_migrate_drivers_internals,
6444 * Migrate print-forms from a print-server
6446 * @param argc Standard main() style argc
6447 * @param argv Standard main() style argv. Initial components are already
6450 * @return A shell status integer (0 for success)
6452 static int rpc_printer_migrate_forms(int argc, const char **argv)
6455 printf("no server to migrate\n");
6459 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6460 rpc_printer_migrate_forms_internals,
6465 * Migrate printers from a print-server
6467 * @param argc Standard main() style argc
6468 * @param argv Standard main() style argv. Initial components are already
6471 * @return A shell status integer (0 for success)
6473 static int rpc_printer_migrate_printers(int argc, const char **argv)
6476 printf("no server to migrate\n");
6480 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6481 rpc_printer_migrate_printers_internals,
6486 * Migrate printer-ACLs from a print-server
6488 * @param argc Standard main() style argc
6489 * @param argv Standard main() style argv. Initial components are already
6492 * @return A shell status integer (0 for success)
6494 static int rpc_printer_migrate_security(int argc, const char **argv)
6497 printf("no server to migrate\n");
6501 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6502 rpc_printer_migrate_security_internals,
6507 * Migrate printer-settings from a print-server
6509 * @param argc Standard main() style argc
6510 * @param argv Standard main() style argv. Initial components are already
6513 * @return A shell status integer (0 for success)
6515 static int rpc_printer_migrate_settings(int argc, const char **argv)
6518 printf("no server to migrate\n");
6522 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6523 rpc_printer_migrate_settings_internals,
6528 * 'net rpc printer' entrypoint.
6529 * @param argc Standard main() style argc
6530 * @param argv Standard main() style argv. Initial components are already
6534 int rpc_printer_migrate(int argc, const char **argv)
6537 /* ouch: when addriver and setdriver are called from within
6538 rpc_printer_migrate_drivers_internals, the printer-queue already
6541 struct functable func[] = {
6542 {"all", rpc_printer_migrate_all},
6543 {"drivers", rpc_printer_migrate_drivers},
6544 {"forms", rpc_printer_migrate_forms},
6545 {"help", rpc_printer_usage},
6546 {"printers", rpc_printer_migrate_printers},
6547 {"security", rpc_printer_migrate_security},
6548 {"settings", rpc_printer_migrate_settings},
6552 return net_run_function(argc, argv, func, rpc_printer_usage);
6557 * List printers on a remote RPC server
6559 * @param argc Standard main() style argc
6560 * @param argv Standard main() style argv. Initial components are already
6563 * @return A shell status integer (0 for success)
6565 static int rpc_printer_list(int argc, const char **argv)
6568 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6569 rpc_printer_list_internals,
6574 * List printer-drivers on a remote RPC server
6576 * @param argc Standard main() style argc
6577 * @param argv Standard main() style argv. Initial components are already
6580 * @return A shell status integer (0 for success)
6582 static int rpc_printer_driver_list(int argc, const char **argv)
6585 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6586 rpc_printer_driver_list_internals,
6591 * Publish printer in ADS via MSRPC
6593 * @param argc Standard main() style argc
6594 * @param argv Standard main() style argv. Initial components are already
6597 * @return A shell status integer (0 for success)
6599 static int rpc_printer_publish_publish(int argc, const char **argv)
6602 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6603 rpc_printer_publish_publish_internals,
6608 * Update printer in ADS via MSRPC
6610 * @param argc Standard main() style argc
6611 * @param argv Standard main() style argv. Initial components are already
6614 * @return A shell status integer (0 for success)
6616 static int rpc_printer_publish_update(int argc, const char **argv)
6619 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6620 rpc_printer_publish_update_internals,
6625 * UnPublish printer in ADS via MSRPC
6627 * @param argc Standard main() style argc
6628 * @param argv Standard main() style argv. Initial components are already
6631 * @return A shell status integer (0 for success)
6633 static int rpc_printer_publish_unpublish(int argc, const char **argv)
6636 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6637 rpc_printer_publish_unpublish_internals,
6642 * List published printers via MSRPC
6644 * @param argc Standard main() style argc
6645 * @param argv Standard main() style argv. Initial components are already
6648 * @return A shell status integer (0 for success)
6650 static int rpc_printer_publish_list(int argc, const char **argv)
6653 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6654 rpc_printer_publish_list_internals,
6660 * Publish printer in ADS
6662 * @param argc Standard main() style argc
6663 * @param argv Standard main() style argv. Initial components are already
6666 * @return A shell status integer (0 for success)
6668 static int rpc_printer_publish(int argc, const char **argv)
6671 struct functable func[] = {
6672 {"publish", rpc_printer_publish_publish},
6673 {"update", rpc_printer_publish_update},
6674 {"unpublish", rpc_printer_publish_unpublish},
6675 {"list", rpc_printer_publish_list},
6676 {"help", rpc_printer_usage},
6681 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6682 rpc_printer_publish_list_internals,
6685 return net_run_function(argc, argv, func, rpc_printer_usage);
6691 * Display rpc printer help page.
6692 * @param argc Standard main() style argc
6693 * @param argv Standard main() style argv. Initial components are already
6696 int rpc_printer_usage(int argc, const char **argv)
6698 return net_help_printer(argc, argv);
6702 * 'net rpc printer' entrypoint.
6703 * @param argc Standard main() style argc
6704 * @param argv Standard main() style argv. Initial components are already
6707 int net_rpc_printer(int argc, const char **argv)
6709 struct functable func[] = {
6710 {"list", rpc_printer_list},
6711 {"migrate", rpc_printer_migrate},
6712 {"driver", rpc_printer_driver_list},
6713 {"publish", rpc_printer_publish},
6718 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6719 rpc_printer_list_internals,
6722 return net_run_function(argc, argv, func, rpc_printer_usage);
6725 /****************************************************************************/
6729 * Basic usage function for 'net rpc'
6730 * @param argc Standard main() style argc
6731 * @param argv Standard main() style argv. Initial components are already
6735 int net_rpc_usage(int argc, const char **argv)
6737 d_printf(" net rpc info \t\t\tshow basic info about a domain \n");
6738 d_printf(" net rpc join \t\t\tto join a domain \n");
6739 d_printf(" net rpc oldjoin \t\tto join a domain created in server manager\n");
6740 d_printf(" net rpc testjoin \t\ttests that a join is valid\n");
6741 d_printf(" net rpc user \t\t\tto add, delete and list users\n");
6742 d_printf(" net rpc password <username> [<password>] -Uadmin_username%%admin_pass\n");
6743 d_printf(" net rpc group \t\tto list groups\n");
6744 d_printf(" net rpc share \t\tto add, delete, list and migrate shares\n");
6745 d_printf(" net rpc printer \t\tto list and migrate printers\n");
6746 d_printf(" net rpc file \t\t\tto list open files\n");
6747 d_printf(" net rpc changetrustpw \tto change the trust account password\n");
6748 d_printf(" net rpc getsid \t\tfetch the domain sid into the local secrets.tdb\n");
6749 d_printf(" net rpc vampire \t\tsyncronise an NT PDC's users and groups into the local passdb\n");
6750 d_printf(" net rpc samdump \t\tdisplay an NT PDC's users, groups and other data\n");
6751 d_printf(" net rpc trustdom \t\tto create trusting domain's account or establish trust\n");
6752 d_printf(" net rpc abortshutdown \tto abort the shutdown of a remote server\n");
6753 d_printf(" net rpc shutdown \t\tto shutdown a remote server\n");
6754 d_printf(" net rpc rights\t\tto manage privileges assigned to SIDs\n");
6755 d_printf(" net rpc registry\t\tto manage registry hives\n");
6756 d_printf(" net rpc service\t\tto start, stop and query services\n");
6757 d_printf(" net rpc audit\t\t\tto modify global auditing settings\n");
6758 d_printf(" net rpc shell\t\t\tto open an interactive shell for remote server/account management\n");
6760 d_printf("'net rpc shutdown' also accepts the following miscellaneous options:\n"); /* misc options */
6761 d_printf("\t-r or --reboot\trequest remote server reboot on shutdown\n");
6762 d_printf("\t-f or --force\trequest the remote server force its shutdown\n");
6763 d_printf("\t-t or --timeout=<timeout>\tnumber of seconds before shutdown\n");
6764 d_printf("\t-C or --comment=<message>\ttext message to display on impending shutdown\n");
6770 * Help function for 'net rpc'. Calls command specific help if requested
6771 * or displays usage of net rpc
6772 * @param argc Standard main() style argc
6773 * @param argv Standard main() style argv. Initial components are already
6777 int net_rpc_help(int argc, const char **argv)
6779 struct functable func[] = {
6780 {"join", rpc_join_usage},
6781 {"user", rpc_user_usage},
6782 {"group", rpc_group_usage},
6783 {"share", rpc_share_usage},
6784 /*{"changetrustpw", rpc_changetrustpw_usage}, */
6785 {"trustdom", rpc_trustdom_usage},
6786 /*{"abortshutdown", rpc_shutdown_abort_usage},*/
6787 /*{"shutdown", rpc_shutdown_usage}, */
6788 {"vampire", rpc_vampire_usage},
6793 net_rpc_usage(argc, argv);
6797 return (net_run_function(argc, argv, func, rpc_user_usage));
6801 * 'net rpc' entrypoint.
6802 * @param argc Standard main() style argc
6803 * @param argv Standard main() style argv. Initial components are already
6807 int net_rpc(int argc, const char **argv)
6809 struct functable func[] = {
6810 {"audit", net_rpc_audit},
6811 {"info", net_rpc_info},
6812 {"join", net_rpc_join},
6813 {"oldjoin", net_rpc_oldjoin},
6814 {"testjoin", net_rpc_testjoin},
6815 {"user", net_rpc_user},
6816 {"password", rpc_user_password},
6817 {"group", net_rpc_group},
6818 {"share", net_rpc_share},
6819 {"file", net_rpc_file},
6820 {"printer", net_rpc_printer},
6821 {"changetrustpw", net_rpc_changetrustpw},
6822 {"trustdom", rpc_trustdom},
6823 {"abortshutdown", rpc_shutdown_abort},
6824 {"shutdown", rpc_shutdown},
6825 {"samdump", rpc_samdump},
6826 {"vampire", rpc_vampire},
6827 {"getsid", net_rpc_getsid},
6828 {"rights", net_rpc_rights},
6829 {"service", net_rpc_service},
6830 {"registry", net_rpc_registry},
6831 {"shell", net_rpc_shell},
6832 {"help", net_rpc_help},
6835 return net_run_function(argc, argv, func, net_rpc_usage);