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_OpenDomain(pipe_hnd, mem_ctx,
459 MAXIMUM_ALLOWED_ACCESS,
460 CONST_DISCARD(struct dom_sid2 *, domain_sid),
462 if (!NT_STATUS_IS_OK(result)) {
463 d_fprintf(stderr, "Could not open domain: %s\n", nt_errstr(result));
468 result = rpccli_samr_query_dom_info(pipe_hnd, mem_ctx, &domain_pol,
470 if (NT_STATUS_IS_OK(result)) {
471 TALLOC_CTX *ctx = talloc_init("rpc_info_internals");
472 d_printf("Domain Name: %s\n", unistr2_to_ascii_talloc(ctx, &ctr.info.inf2.uni_domain));
473 d_printf("Domain SID: %s\n", sid_str);
474 d_printf("Sequence number: %llu\n", (unsigned long long)ctr.info.inf2.seq_num);
475 d_printf("Num users: %u\n", ctr.info.inf2.num_domain_usrs);
476 d_printf("Num domain groups: %u\n", ctr.info.inf2.num_domain_grps);
477 d_printf("Num local groups: %u\n", ctr.info.inf2.num_local_grps);
486 * 'net rpc info' entrypoint.
487 * @param argc Standard main() style argc
488 * @param argc Standard main() style argv. Initial components are already
492 int net_rpc_info(int argc, const char **argv)
494 return run_rpc_command(NULL, PI_SAMR, NET_FLAGS_PDC,
500 * Fetch domain SID into the local secrets.tdb
502 * All parameters are provided by the run_rpc_command function, except for
503 * argc, argv which are passes through.
505 * @param domain_sid The domain sid acquired from the remote server
506 * @param cli A cli_state connected to the server.
507 * @param mem_ctx Talloc context, destoyed on completion of the function.
508 * @param argc Standard main() style argc
509 * @param argv Standard main() style argv. Initial components are already
512 * @return Normal NTSTATUS return.
515 static NTSTATUS rpc_getsid_internals(const DOM_SID *domain_sid,
516 const char *domain_name,
517 struct cli_state *cli,
518 struct rpc_pipe_client *pipe_hnd,
525 sid_to_fstring(sid_str, domain_sid);
526 d_printf("Storing SID %s for Domain %s in secrets.tdb\n",
527 sid_str, domain_name);
529 if (!secrets_store_domain_sid(domain_name, domain_sid)) {
530 DEBUG(0,("Can't store domain SID\n"));
531 return NT_STATUS_UNSUCCESSFUL;
538 * 'net rpc getsid' entrypoint.
539 * @param argc Standard main() style argc
540 * @param argc Standard main() style argv. Initial components are already
544 int net_rpc_getsid(int argc, const char **argv)
546 return run_rpc_command(NULL, PI_SAMR, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC,
547 rpc_getsid_internals,
551 /****************************************************************************/
554 * Basic usage function for 'net rpc user'
555 * @param argc Standard main() style argc.
556 * @param argv Standard main() style argv. Initial components are already
560 static int rpc_user_usage(int argc, const char **argv)
562 return net_help_user(argc, argv);
566 * Add a new user to a remote RPC server
568 * All parameters are provided by the run_rpc_command function, except for
569 * argc, argv which are passes through.
571 * @param domain_sid The domain sid acquired from the remote server
572 * @param cli A cli_state connected to the server.
573 * @param mem_ctx Talloc context, destoyed on completion of the function.
574 * @param argc Standard main() style argc
575 * @param argv Standard main() style argv. Initial components are already
578 * @return Normal NTSTATUS return.
581 static NTSTATUS rpc_user_add_internals(const DOM_SID *domain_sid,
582 const char *domain_name,
583 struct cli_state *cli,
584 struct rpc_pipe_client *pipe_hnd,
586 int argc, const char **argv)
589 POLICY_HND connect_pol, domain_pol, user_pol;
590 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
591 const char *acct_name;
593 uint32 acct_flags, user_rid;
596 d_printf("User must be specified\n");
597 rpc_user_usage(argc, argv);
603 /* Get sam policy handle */
605 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
607 if (!NT_STATUS_IS_OK(result)) {
611 /* Get domain policy handle */
613 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
615 MAXIMUM_ALLOWED_ACCESS,
616 CONST_DISCARD(struct dom_sid2 *, domain_sid),
618 if (!NT_STATUS_IS_OK(result)) {
622 /* Create domain user */
624 acb_info = ACB_NORMAL;
625 acct_flags = SEC_GENERIC_READ | SEC_GENERIC_WRITE | SEC_GENERIC_EXECUTE |
626 SEC_STD_WRITE_DAC | SEC_STD_DELETE |
627 SAMR_USER_ACCESS_SET_PASSWORD |
628 SAMR_USER_ACCESS_GET_ATTRIBUTES |
629 SAMR_USER_ACCESS_SET_ATTRIBUTES;
631 result = rpccli_samr_create_dom_user(pipe_hnd, mem_ctx, &domain_pol,
632 acct_name, acb_info, acct_flags,
633 &user_pol, &user_rid);
634 if (!NT_STATUS_IS_OK(result)) {
640 uint32 *user_rids, num_rids, *name_types;
641 uint32 flags = 0x000003e8; /* Unknown */
642 SAM_USERINFO_CTR ctr;
643 SAM_USER_INFO_24 p24;
646 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol,
647 flags, 1, &acct_name,
648 &num_rids, &user_rids,
651 if (!NT_STATUS_IS_OK(result)) {
655 result = rpccli_samr_OpenUser(pipe_hnd, mem_ctx,
657 MAXIMUM_ALLOWED_ACCESS,
661 if (!NT_STATUS_IS_OK(result)) {
665 /* Set password on account */
670 encode_pw_buffer(pwbuf, argv[1], STR_UNICODE);
672 init_sam_user_info24(&p24, (char *)pwbuf,24);
674 ctr.switch_value = 24;
675 ctr.info.id24 = &p24;
677 result = rpccli_samr_set_userinfo(pipe_hnd, mem_ctx, &user_pol, 24,
678 &cli->user_session_key, &ctr);
680 if (!NT_STATUS_IS_OK(result)) {
681 d_fprintf(stderr, "Failed to set password for user %s - %s\n",
682 acct_name, nt_errstr(result));
684 result = rpccli_samr_DeleteUser(pipe_hnd, mem_ctx,
687 if (!NT_STATUS_IS_OK(result)) {
688 d_fprintf(stderr, "Failed to delete user %s - %s\n",
689 acct_name, nt_errstr(result));
696 if (!NT_STATUS_IS_OK(result)) {
697 d_fprintf(stderr, "Failed to add user '%s' with %s.\n",
698 acct_name, nt_errstr(result));
700 d_printf("Added user '%s'.\n", acct_name);
706 * Add a new user to a remote RPC server
708 * @param argc Standard main() style argc
709 * @param argv Standard main() style argv. Initial components are already
712 * @return A shell status integer (0 for success)
715 static int rpc_user_add(int argc, const char **argv)
717 return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_add_internals,
722 * Delete a user from a remote RPC server
724 * All parameters are provided by the run_rpc_command function, except for
725 * argc, argv which are passes through.
727 * @param domain_sid The domain sid acquired from the remote server
728 * @param cli A cli_state connected to the server.
729 * @param mem_ctx Talloc context, destoyed on completion of the function.
730 * @param argc Standard main() style argc
731 * @param argv Standard main() style argv. Initial components are already
734 * @return Normal NTSTATUS return.
737 static NTSTATUS rpc_user_del_internals(const DOM_SID *domain_sid,
738 const char *domain_name,
739 struct cli_state *cli,
740 struct rpc_pipe_client *pipe_hnd,
745 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
746 POLICY_HND connect_pol, domain_pol, user_pol;
747 const char *acct_name;
750 d_printf("User must be specified\n");
751 rpc_user_usage(argc, argv);
757 /* Get sam policy and domain handles */
759 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
762 if (!NT_STATUS_IS_OK(result)) {
766 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
768 MAXIMUM_ALLOWED_ACCESS,
769 CONST_DISCARD(struct dom_sid2 *, domain_sid),
772 if (!NT_STATUS_IS_OK(result)) {
776 /* Get handle on user */
779 uint32 *user_rids, num_rids, *name_types;
780 uint32 flags = 0x000003e8; /* Unknown */
782 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol,
783 flags, 1, &acct_name,
784 &num_rids, &user_rids,
787 if (!NT_STATUS_IS_OK(result)) {
791 result = rpccli_samr_OpenUser(pipe_hnd, mem_ctx,
793 MAXIMUM_ALLOWED_ACCESS,
797 if (!NT_STATUS_IS_OK(result)) {
804 result = rpccli_samr_DeleteUser(pipe_hnd, mem_ctx,
807 if (!NT_STATUS_IS_OK(result)) {
812 if (!NT_STATUS_IS_OK(result)) {
813 d_fprintf(stderr, "Failed to delete user '%s' with %s.\n",
814 acct_name, nt_errstr(result));
816 d_printf("Deleted user '%s'.\n", acct_name);
823 * Rename a user on a remote RPC server
825 * All parameters are provided by the run_rpc_command function, except for
826 * argc, argv which are passes through.
828 * @param domain_sid The domain sid acquired from the remote server
829 * @param cli A cli_state connected to the server.
830 * @param mem_ctx Talloc context, destoyed on completion of the function.
831 * @param argc Standard main() style argc
832 * @param argv Standard main() style argv. Initial components are already
835 * @return Normal NTSTATUS return.
838 static NTSTATUS rpc_user_rename_internals(const DOM_SID *domain_sid,
839 const char *domain_name,
840 struct cli_state *cli,
841 struct rpc_pipe_client *pipe_hnd,
846 POLICY_HND connect_pol, domain_pol, user_pol;
847 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
848 uint32 info_level = 7;
849 const char *old_name, *new_name;
851 uint32 flags = 0x000003e8; /* Unknown */
852 uint32 num_rids, *name_types;
853 uint32 num_names = 1;
855 SAM_USERINFO_CTR *user_ctr;
856 SAM_USERINFO_CTR ctr;
857 SAM_USER_INFO_7 info7;
860 d_printf("Old and new username must be specified\n");
861 rpc_user_usage(argc, argv);
869 ZERO_STRUCT(user_ctr);
871 /* Get sam policy handle */
873 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
875 if (!NT_STATUS_IS_OK(result)) {
879 /* Get domain policy handle */
881 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
883 MAXIMUM_ALLOWED_ACCESS,
884 CONST_DISCARD(struct dom_sid2 *, domain_sid),
886 if (!NT_STATUS_IS_OK(result)) {
890 if ((names = TALLOC_ARRAY(mem_ctx, const char *, num_names)) == NULL) {
891 result = NT_STATUS_NO_MEMORY;
895 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol,
896 flags, num_names, names,
897 &num_rids, &user_rid, &name_types);
898 if (!NT_STATUS_IS_OK(result)) {
902 /* Open domain user */
903 result = rpccli_samr_OpenUser(pipe_hnd, mem_ctx,
905 MAXIMUM_ALLOWED_ACCESS,
909 if (!NT_STATUS_IS_OK(result)) {
913 /* Query user info */
914 result = rpccli_samr_query_userinfo(pipe_hnd, mem_ctx, &user_pol,
915 info_level, &user_ctr);
917 if (!NT_STATUS_IS_OK(result)) {
921 ctr.switch_value = info_level;
922 ctr.info.id7 = &info7;
924 init_sam_user_info7(&info7, new_name);
927 result = rpccli_samr_set_userinfo(pipe_hnd, mem_ctx, &user_pol,
928 info_level, &cli->user_session_key, &ctr);
930 if (!NT_STATUS_IS_OK(result)) {
935 if (!NT_STATUS_IS_OK(result)) {
936 d_fprintf(stderr, "Failed to rename user from %s to %s - %s\n", old_name, new_name,
939 d_printf("Renamed user from %s to %s\n", old_name, new_name);
945 * Rename a user on a remote RPC server
947 * @param argc Standard main() style argc
948 * @param argv Standard main() style argv. Initial components are already
951 * @return A shell status integer (0 for success)
954 static int rpc_user_rename(int argc, const char **argv)
956 return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_rename_internals,
961 * Delete a user from a remote RPC server
963 * @param argc Standard main() style argc
964 * @param argv Standard main() style argv. Initial components are already
967 * @return A shell status integer (0 for success)
970 static int rpc_user_delete(int argc, const char **argv)
972 return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_del_internals,
977 * Set a password for a user on a remote RPC server
979 * All parameters are provided by the run_rpc_command function, except for
980 * argc, argv which are passes through.
982 * @param domain_sid The domain sid acquired from the remote server
983 * @param cli A cli_state connected to the server.
984 * @param mem_ctx Talloc context, destoyed on completion of the function.
985 * @param argc Standard main() style argc
986 * @param argv Standard main() style argv. Initial components are already
989 * @return Normal NTSTATUS return.
992 static NTSTATUS rpc_user_password_internals(const DOM_SID *domain_sid,
993 const char *domain_name,
994 struct cli_state *cli,
995 struct rpc_pipe_client *pipe_hnd,
1000 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1001 POLICY_HND connect_pol, domain_pol, user_pol;
1002 SAM_USERINFO_CTR ctr;
1003 SAM_USER_INFO_24 p24;
1006 const char *new_password;
1007 char *prompt = NULL;
1010 d_printf("User must be specified\n");
1011 rpc_user_usage(argc, argv);
1012 return NT_STATUS_OK;
1018 new_password = argv[1];
1020 asprintf(&prompt, "Enter new password for %s:", user);
1021 new_password = getpass(prompt);
1025 /* Get sam policy and domain handles */
1027 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1030 if (!NT_STATUS_IS_OK(result)) {
1034 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
1036 MAXIMUM_ALLOWED_ACCESS,
1037 CONST_DISCARD(struct dom_sid2 *, domain_sid),
1040 if (!NT_STATUS_IS_OK(result)) {
1044 /* Get handle on user */
1047 uint32 *user_rids, num_rids, *name_types;
1048 uint32 flags = 0x000003e8; /* Unknown */
1050 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol,
1052 &num_rids, &user_rids,
1055 if (!NT_STATUS_IS_OK(result)) {
1059 result = rpccli_samr_OpenUser(pipe_hnd, mem_ctx,
1061 MAXIMUM_ALLOWED_ACCESS,
1065 if (!NT_STATUS_IS_OK(result)) {
1070 /* Set password on account */
1075 encode_pw_buffer(pwbuf, new_password, STR_UNICODE);
1077 init_sam_user_info24(&p24, (char *)pwbuf,24);
1079 ctr.switch_value = 24;
1080 ctr.info.id24 = &p24;
1082 result = rpccli_samr_set_userinfo(pipe_hnd, mem_ctx, &user_pol, 24,
1083 &cli->user_session_key, &ctr);
1085 if (!NT_STATUS_IS_OK(result)) {
1089 /* Display results */
1097 * Set a user's password on a remote RPC server
1099 * @param argc Standard main() style argc
1100 * @param argv Standard main() style argv. Initial components are already
1103 * @return A shell status integer (0 for success)
1106 static int rpc_user_password(int argc, const char **argv)
1108 return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_password_internals,
1113 * List user's groups on a remote RPC server
1115 * All parameters are provided by the run_rpc_command function, except for
1116 * argc, argv which are passes through.
1118 * @param domain_sid The domain sid acquired from the remote server
1119 * @param cli A cli_state connected to the server.
1120 * @param mem_ctx Talloc context, destoyed on completion of the function.
1121 * @param argc Standard main() style argc
1122 * @param argv Standard main() style argv. Initial components are already
1125 * @return Normal NTSTATUS return.
1128 static NTSTATUS rpc_user_info_internals(const DOM_SID *domain_sid,
1129 const char *domain_name,
1130 struct cli_state *cli,
1131 struct rpc_pipe_client *pipe_hnd,
1132 TALLOC_CTX *mem_ctx,
1136 POLICY_HND connect_pol, domain_pol, user_pol;
1137 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1138 uint32 *rids, num_rids, *name_types, num_names;
1139 uint32 flags = 0x000003e8; /* Unknown */
1145 d_printf("User must be specified\n");
1146 rpc_user_usage(argc, argv);
1147 return NT_STATUS_OK;
1149 /* Get sam policy handle */
1151 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1153 if (!NT_STATUS_IS_OK(result)) goto done;
1155 /* Get domain policy handle */
1157 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
1159 MAXIMUM_ALLOWED_ACCESS,
1160 CONST_DISCARD(struct dom_sid2 *, domain_sid),
1162 if (!NT_STATUS_IS_OK(result)) goto done;
1164 /* Get handle on user */
1166 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol,
1168 &num_rids, &rids, &name_types);
1170 if (!NT_STATUS_IS_OK(result)) goto done;
1172 result = rpccli_samr_OpenUser(pipe_hnd, mem_ctx,
1174 MAXIMUM_ALLOWED_ACCESS,
1177 if (!NT_STATUS_IS_OK(result)) goto done;
1179 result = rpccli_samr_query_usergroups(pipe_hnd, mem_ctx, &user_pol,
1180 &num_rids, &user_gids);
1182 if (!NT_STATUS_IS_OK(result)) goto done;
1187 if ((rids = TALLOC_ARRAY(mem_ctx, uint32, num_rids)) == NULL) {
1188 result = NT_STATUS_NO_MEMORY;
1192 for (i = 0; i < num_rids; i++)
1193 rids[i] = user_gids[i].g_rid;
1195 result = rpccli_samr_lookup_rids(pipe_hnd, mem_ctx, &domain_pol,
1197 &num_names, &names, &name_types);
1199 if (!NT_STATUS_IS_OK(result)) {
1203 /* Display results */
1205 for (i = 0; i < num_names; i++)
1206 printf("%s\n", names[i]);
1213 * List a user's groups from a remote RPC server
1215 * @param argc Standard main() style argc
1216 * @param argv Standard main() style argv. Initial components are already
1219 * @return A shell status integer (0 for success)
1222 static int rpc_user_info(int argc, const char **argv)
1224 return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_info_internals,
1229 * List users on a remote RPC server
1231 * All parameters are provided by the run_rpc_command function, except for
1232 * argc, argv which are passes through.
1234 * @param domain_sid The domain sid acquired from the remote server
1235 * @param cli A cli_state connected to the server.
1236 * @param mem_ctx Talloc context, destoyed on completion of the function.
1237 * @param argc Standard main() style argc
1238 * @param argv Standard main() style argv. Initial components are already
1241 * @return Normal NTSTATUS return.
1244 static NTSTATUS rpc_user_list_internals(const DOM_SID *domain_sid,
1245 const char *domain_name,
1246 struct cli_state *cli,
1247 struct rpc_pipe_client *pipe_hnd,
1248 TALLOC_CTX *mem_ctx,
1252 POLICY_HND connect_pol, domain_pol;
1253 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1254 uint32 start_idx=0, num_entries, i, loop_count = 0;
1255 SAM_DISPINFO_CTR ctr;
1256 SAM_DISPINFO_1 info1;
1258 /* Get sam policy handle */
1260 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1262 if (!NT_STATUS_IS_OK(result)) {
1266 /* Get domain policy handle */
1268 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
1270 MAXIMUM_ALLOWED_ACCESS,
1271 CONST_DISCARD(struct dom_sid2 *, domain_sid),
1273 if (!NT_STATUS_IS_OK(result)) {
1277 /* Query domain users */
1280 ctr.sam.info1 = &info1;
1281 if (opt_long_list_entries)
1282 d_printf("\nUser name Comment"\
1283 "\n-----------------------------\n");
1286 uint32 max_entries, max_size;
1288 get_query_dispinfo_params(
1289 loop_count, &max_entries, &max_size);
1291 result = rpccli_samr_query_dispinfo(pipe_hnd, mem_ctx, &domain_pol,
1292 &start_idx, 1, &num_entries,
1293 max_entries, max_size, &ctr);
1296 for (i = 0; i < num_entries; i++) {
1297 unistr2_to_ascii(user, &(&ctr.sam.info1->str[i])->uni_acct_name, sizeof(user));
1298 if (opt_long_list_entries)
1299 unistr2_to_ascii(desc, &(&ctr.sam.info1->str[i])->uni_acct_desc, sizeof(desc));
1301 if (opt_long_list_entries)
1302 printf("%-21.21s %s\n", user, desc);
1304 printf("%s\n", user);
1306 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
1313 * 'net rpc user' entrypoint.
1314 * @param argc Standard main() style argc
1315 * @param argc Standard main() style argv. Initial components are already
1319 int net_rpc_user(int argc, const char **argv)
1321 struct functable func[] = {
1322 {"add", rpc_user_add},
1323 {"info", rpc_user_info},
1324 {"delete", rpc_user_delete},
1325 {"password", rpc_user_password},
1326 {"rename", rpc_user_rename},
1331 return run_rpc_command(NULL,PI_SAMR, 0,
1332 rpc_user_list_internals,
1336 return net_run_function(argc, argv, func, rpc_user_usage);
1339 static NTSTATUS rpc_sh_user_list(TALLOC_CTX *mem_ctx,
1340 struct rpc_sh_ctx *ctx,
1341 struct rpc_pipe_client *pipe_hnd,
1342 int argc, const char **argv)
1344 return rpc_user_list_internals(ctx->domain_sid, ctx->domain_name,
1345 ctx->cli, pipe_hnd, mem_ctx,
1349 static NTSTATUS rpc_sh_user_info(TALLOC_CTX *mem_ctx,
1350 struct rpc_sh_ctx *ctx,
1351 struct rpc_pipe_client *pipe_hnd,
1352 int argc, const char **argv)
1354 return rpc_user_info_internals(ctx->domain_sid, ctx->domain_name,
1355 ctx->cli, pipe_hnd, mem_ctx,
1359 static NTSTATUS rpc_sh_handle_user(TALLOC_CTX *mem_ctx,
1360 struct rpc_sh_ctx *ctx,
1361 struct rpc_pipe_client *pipe_hnd,
1362 int argc, const char **argv,
1364 TALLOC_CTX *mem_ctx,
1365 struct rpc_sh_ctx *ctx,
1366 struct rpc_pipe_client *pipe_hnd,
1367 const POLICY_HND *user_hnd,
1368 int argc, const char **argv))
1371 POLICY_HND connect_pol, domain_pol, user_pol;
1372 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1375 enum lsa_SidType type;
1378 d_fprintf(stderr, "usage: %s <username>\n", ctx->whoami);
1379 return NT_STATUS_INVALID_PARAMETER;
1382 ZERO_STRUCT(connect_pol);
1383 ZERO_STRUCT(domain_pol);
1384 ZERO_STRUCT(user_pol);
1386 result = net_rpc_lookup_name(mem_ctx, pipe_hnd->cli, argv[0],
1387 NULL, NULL, &sid, &type);
1388 if (!NT_STATUS_IS_OK(result)) {
1389 d_fprintf(stderr, "Could not lookup %s: %s\n", argv[0],
1394 if (type != SID_NAME_USER) {
1395 d_fprintf(stderr, "%s is a %s, not a user\n", argv[0],
1396 sid_type_lookup(type));
1397 result = NT_STATUS_NO_SUCH_USER;
1401 if (!sid_peek_check_rid(ctx->domain_sid, &sid, &rid)) {
1402 d_fprintf(stderr, "%s is not in our domain\n", argv[0]);
1403 result = NT_STATUS_NO_SUCH_USER;
1407 result = rpccli_samr_connect(pipe_hnd, mem_ctx,
1408 MAXIMUM_ALLOWED_ACCESS, &connect_pol);
1409 if (!NT_STATUS_IS_OK(result)) {
1413 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
1415 MAXIMUM_ALLOWED_ACCESS,
1418 if (!NT_STATUS_IS_OK(result)) {
1422 result = rpccli_samr_OpenUser(pipe_hnd, mem_ctx,
1424 MAXIMUM_ALLOWED_ACCESS,
1427 if (!NT_STATUS_IS_OK(result)) {
1431 result = fn(mem_ctx, ctx, pipe_hnd, &user_pol, argc-1, argv+1);
1434 if (is_valid_policy_hnd(&user_pol)) {
1435 rpccli_samr_Close(pipe_hnd, mem_ctx, &user_pol);
1437 if (is_valid_policy_hnd(&domain_pol)) {
1438 rpccli_samr_Close(pipe_hnd, mem_ctx, &domain_pol);
1440 if (is_valid_policy_hnd(&connect_pol)) {
1441 rpccli_samr_Close(pipe_hnd, mem_ctx, &connect_pol);
1446 static NTSTATUS rpc_sh_user_show_internals(TALLOC_CTX *mem_ctx,
1447 struct rpc_sh_ctx *ctx,
1448 struct rpc_pipe_client *pipe_hnd,
1449 const POLICY_HND *user_hnd,
1450 int argc, const char **argv)
1453 SAM_USERINFO_CTR *ctr;
1454 SAM_USER_INFO_21 *info;
1457 d_fprintf(stderr, "usage: %s show <username>\n", ctx->whoami);
1458 return NT_STATUS_INVALID_PARAMETER;
1461 result = rpccli_samr_query_userinfo(pipe_hnd, mem_ctx, user_hnd,
1463 if (!NT_STATUS_IS_OK(result)) {
1467 info = ctr->info.id21;
1469 d_printf("user rid: %d, group rid: %d\n", info->user_rid,
1475 static NTSTATUS rpc_sh_user_show(TALLOC_CTX *mem_ctx,
1476 struct rpc_sh_ctx *ctx,
1477 struct rpc_pipe_client *pipe_hnd,
1478 int argc, const char **argv)
1480 return rpc_sh_handle_user(mem_ctx, ctx, pipe_hnd, argc, argv,
1481 rpc_sh_user_show_internals);
1484 #define FETCHSTR(name, rec) \
1485 do { if (strequal(ctx->thiscmd, name)) { \
1486 oldval = rpcstr_pull_unistr2_talloc(mem_ctx, &usr->uni_##rec); } \
1489 #define SETSTR(name, rec, flag) \
1490 do { if (strequal(ctx->thiscmd, name)) { \
1491 init_unistr2(&usr->uni_##rec, argv[0], UNI_STR_TERMINATE); \
1492 init_uni_hdr(&usr->hdr_##rec, &usr->uni_##rec); \
1493 usr->fields_present |= ACCT_##flag; } \
1496 static NTSTATUS rpc_sh_user_str_edit_internals(TALLOC_CTX *mem_ctx,
1497 struct rpc_sh_ctx *ctx,
1498 struct rpc_pipe_client *pipe_hnd,
1499 const POLICY_HND *user_hnd,
1500 int argc, const char **argv)
1503 SAM_USERINFO_CTR *ctr;
1504 SAM_USER_INFO_21 *usr;
1505 const char *username;
1506 const char *oldval = "";
1509 d_fprintf(stderr, "usage: %s <username> [new value|NULL]\n",
1511 return NT_STATUS_INVALID_PARAMETER;
1514 result = rpccli_samr_query_userinfo(pipe_hnd, mem_ctx, user_hnd,
1516 if (!NT_STATUS_IS_OK(result)) {
1520 usr = ctr->info.id21;
1522 username = rpcstr_pull_unistr2_talloc(mem_ctx, &usr->uni_user_name);
1524 FETCHSTR("fullname", full_name);
1525 FETCHSTR("homedir", home_dir);
1526 FETCHSTR("homedrive", dir_drive);
1527 FETCHSTR("logonscript", logon_script);
1528 FETCHSTR("profilepath", profile_path);
1529 FETCHSTR("description", acct_desc);
1532 d_printf("%s's %s: [%s]\n", username, ctx->thiscmd, oldval);
1538 if (strcmp(argv[0], "NULL") == 0) {
1542 SETSTR("fullname", full_name, FULL_NAME);
1543 SETSTR("homedir", home_dir, HOME_DIR);
1544 SETSTR("homedrive", dir_drive, HOME_DRIVE);
1545 SETSTR("logonscript", logon_script, LOGON_SCRIPT);
1546 SETSTR("profilepath", profile_path, PROFILE);
1547 SETSTR("description", acct_desc, DESCRIPTION);
1549 result = rpccli_samr_set_userinfo2(
1550 pipe_hnd, mem_ctx, user_hnd, 21,
1551 &pipe_hnd->cli->user_session_key, ctr);
1553 d_printf("Set %s's %s from [%s] to [%s]\n", username,
1554 ctx->thiscmd, oldval, argv[0]);
1561 #define HANDLEFLG(name, rec) \
1562 do { if (strequal(ctx->thiscmd, name)) { \
1563 oldval = (oldflags & ACB_##rec) ? "yes" : "no"; \
1565 newflags = oldflags | ACB_##rec; \
1567 newflags = oldflags & ~ACB_##rec; \
1570 static NTSTATUS rpc_sh_user_str_edit(TALLOC_CTX *mem_ctx,
1571 struct rpc_sh_ctx *ctx,
1572 struct rpc_pipe_client *pipe_hnd,
1573 int argc, const char **argv)
1575 return rpc_sh_handle_user(mem_ctx, ctx, pipe_hnd, argc, argv,
1576 rpc_sh_user_str_edit_internals);
1579 static NTSTATUS rpc_sh_user_flag_edit_internals(TALLOC_CTX *mem_ctx,
1580 struct rpc_sh_ctx *ctx,
1581 struct rpc_pipe_client *pipe_hnd,
1582 const POLICY_HND *user_hnd,
1583 int argc, const char **argv)
1586 SAM_USERINFO_CTR *ctr;
1587 SAM_USER_INFO_21 *usr;
1588 const char *username;
1589 const char *oldval = "unknown";
1590 uint32 oldflags, newflags;
1594 ((argc == 1) && !strequal(argv[0], "yes") &&
1595 !strequal(argv[0], "no"))) {
1596 d_fprintf(stderr, "usage: %s <username> [yes|no]\n",
1598 return NT_STATUS_INVALID_PARAMETER;
1601 newval = strequal(argv[0], "yes");
1603 result = rpccli_samr_query_userinfo(pipe_hnd, mem_ctx, user_hnd,
1605 if (!NT_STATUS_IS_OK(result)) {
1609 usr = ctr->info.id21;
1611 username = rpcstr_pull_unistr2_talloc(mem_ctx, &usr->uni_user_name);
1612 oldflags = usr->acb_info;
1613 newflags = usr->acb_info;
1615 HANDLEFLG("disabled", DISABLED);
1616 HANDLEFLG("pwnotreq", PWNOTREQ);
1617 HANDLEFLG("autolock", AUTOLOCK);
1618 HANDLEFLG("pwnoexp", PWNOEXP);
1621 d_printf("%s's %s flag: %s\n", username, ctx->thiscmd, oldval);
1627 usr->acb_info = newflags;
1628 usr->fields_present = ACCT_FLAGS;
1630 result = rpccli_samr_set_userinfo2(
1631 pipe_hnd, mem_ctx, user_hnd, 21,
1632 &pipe_hnd->cli->user_session_key, ctr);
1634 if (NT_STATUS_IS_OK(result)) {
1635 d_printf("Set %s's %s flag from [%s] to [%s]\n", username,
1636 ctx->thiscmd, oldval, argv[0]);
1644 static NTSTATUS rpc_sh_user_flag_edit(TALLOC_CTX *mem_ctx,
1645 struct rpc_sh_ctx *ctx,
1646 struct rpc_pipe_client *pipe_hnd,
1647 int argc, const char **argv)
1649 return rpc_sh_handle_user(mem_ctx, ctx, pipe_hnd, argc, argv,
1650 rpc_sh_user_flag_edit_internals);
1653 struct rpc_sh_cmd *net_rpc_user_edit_cmds(TALLOC_CTX *mem_ctx,
1654 struct rpc_sh_ctx *ctx)
1656 static struct rpc_sh_cmd cmds[] = {
1658 { "fullname", NULL, PI_SAMR, rpc_sh_user_str_edit,
1659 "Show/Set a user's full name" },
1661 { "homedir", NULL, PI_SAMR, rpc_sh_user_str_edit,
1662 "Show/Set a user's home directory" },
1664 { "homedrive", NULL, PI_SAMR, rpc_sh_user_str_edit,
1665 "Show/Set a user's home drive" },
1667 { "logonscript", NULL, PI_SAMR, rpc_sh_user_str_edit,
1668 "Show/Set a user's logon script" },
1670 { "profilepath", NULL, PI_SAMR, rpc_sh_user_str_edit,
1671 "Show/Set a user's profile path" },
1673 { "description", NULL, PI_SAMR, rpc_sh_user_str_edit,
1674 "Show/Set a user's description" },
1676 { "disabled", NULL, PI_SAMR, rpc_sh_user_flag_edit,
1677 "Show/Set whether a user is disabled" },
1679 { "autolock", NULL, PI_SAMR, rpc_sh_user_flag_edit,
1680 "Show/Set whether a user locked out" },
1682 { "pwnotreq", NULL, PI_SAMR, rpc_sh_user_flag_edit,
1683 "Show/Set whether a user does not need a password" },
1685 { "pwnoexp", NULL, PI_SAMR, rpc_sh_user_flag_edit,
1686 "Show/Set whether a user's password does not expire" },
1688 { NULL, NULL, 0, NULL, NULL }
1694 struct rpc_sh_cmd *net_rpc_user_cmds(TALLOC_CTX *mem_ctx,
1695 struct rpc_sh_ctx *ctx)
1697 static struct rpc_sh_cmd cmds[] = {
1699 { "list", NULL, PI_SAMR, rpc_sh_user_list,
1700 "List available users" },
1702 { "info", NULL, PI_SAMR, rpc_sh_user_info,
1703 "List the domain groups a user is member of" },
1705 { "show", NULL, PI_SAMR, rpc_sh_user_show,
1706 "Show info about a user" },
1708 { "edit", net_rpc_user_edit_cmds, 0, NULL,
1709 "Show/Modify a user's fields" },
1711 { NULL, NULL, 0, NULL, NULL }
1717 /****************************************************************************/
1720 * Basic usage function for 'net rpc group'
1721 * @param argc Standard main() style argc.
1722 * @param argv Standard main() style argv. Initial components are already
1726 static int rpc_group_usage(int argc, const char **argv)
1728 return net_help_group(argc, argv);
1732 * Delete group on a remote RPC server
1734 * All parameters are provided by the run_rpc_command function, except for
1735 * argc, argv which are passes through.
1737 * @param domain_sid The domain sid acquired from the remote server
1738 * @param cli A cli_state connected to the server.
1739 * @param mem_ctx Talloc context, destoyed on completion of the function.
1740 * @param argc Standard main() style argc
1741 * @param argv Standard main() style argv. Initial components are already
1744 * @return Normal NTSTATUS return.
1747 static NTSTATUS rpc_group_delete_internals(const DOM_SID *domain_sid,
1748 const char *domain_name,
1749 struct cli_state *cli,
1750 struct rpc_pipe_client *pipe_hnd,
1751 TALLOC_CTX *mem_ctx,
1755 POLICY_HND connect_pol, domain_pol, group_pol, user_pol;
1756 bool group_is_primary = False;
1757 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1759 uint32 *group_rids, num_rids, *name_types, num_members,
1760 *group_attrs, group_rid;
1761 uint32 flags = 0x000003e8; /* Unknown */
1764 /* DOM_GID *user_gids; */
1765 SAM_USERINFO_CTR *user_ctr;
1769 d_printf("specify group\n");
1770 rpc_group_usage(argc,argv);
1771 return NT_STATUS_OK; /* ok? */
1774 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1777 if (!NT_STATUS_IS_OK(result)) {
1778 d_fprintf(stderr, "Request samr_connect failed\n");
1782 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
1784 MAXIMUM_ALLOWED_ACCESS,
1785 CONST_DISCARD(struct dom_sid2 *, domain_sid),
1788 if (!NT_STATUS_IS_OK(result)) {
1789 d_fprintf(stderr, "Request open_domain failed\n");
1793 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol,
1795 &num_rids, &group_rids,
1798 if (!NT_STATUS_IS_OK(result)) {
1799 d_fprintf(stderr, "Lookup of '%s' failed\n",argv[0]);
1803 switch (name_types[0])
1805 case SID_NAME_DOM_GRP:
1806 result = rpccli_samr_OpenGroup(pipe_hnd, mem_ctx,
1808 MAXIMUM_ALLOWED_ACCESS,
1811 if (!NT_STATUS_IS_OK(result)) {
1812 d_fprintf(stderr, "Request open_group failed");
1816 group_rid = group_rids[0];
1818 result = rpccli_samr_query_groupmem(pipe_hnd, mem_ctx, &group_pol,
1819 &num_members, &group_rids,
1822 if (!NT_STATUS_IS_OK(result)) {
1823 d_fprintf(stderr, "Unable to query group members of %s",argv[0]);
1828 d_printf("Domain Group %s (rid: %d) has %d members\n",
1829 argv[0],group_rid,num_members);
1832 /* Check if group is anyone's primary group */
1833 for (i = 0; i < num_members; i++)
1835 result = rpccli_samr_OpenUser(pipe_hnd, mem_ctx,
1837 MAXIMUM_ALLOWED_ACCESS,
1841 if (!NT_STATUS_IS_OK(result)) {
1842 d_fprintf(stderr, "Unable to open group member %d\n",group_rids[i]);
1846 ZERO_STRUCT(user_ctr);
1848 result = rpccli_samr_query_userinfo(pipe_hnd, mem_ctx, &user_pol,
1851 if (!NT_STATUS_IS_OK(result)) {
1852 d_fprintf(stderr, "Unable to lookup userinfo for group member %d\n",group_rids[i]);
1856 if (user_ctr->info.id21->group_rid == group_rid) {
1857 unistr2_to_ascii(temp, &(user_ctr->info.id21)->uni_user_name,
1860 d_printf("Group is primary group of %s\n",temp);
1861 group_is_primary = True;
1864 rpccli_samr_Close(pipe_hnd, mem_ctx, &user_pol);
1867 if (group_is_primary) {
1868 d_fprintf(stderr, "Unable to delete group because some "
1869 "of it's members have it as primary group\n");
1870 result = NT_STATUS_MEMBERS_PRIMARY_GROUP;
1874 /* remove all group members */
1875 for (i = 0; i < num_members; i++)
1878 d_printf("Remove group member %d...",group_rids[i]);
1879 result = rpccli_samr_del_groupmem(pipe_hnd, mem_ctx, &group_pol, group_rids[i]);
1881 if (NT_STATUS_IS_OK(result)) {
1886 d_printf("failed\n");
1891 result = rpccli_samr_DeleteDomainGroup(pipe_hnd, mem_ctx,
1895 /* removing a local group is easier... */
1896 case SID_NAME_ALIAS:
1897 result = rpccli_samr_OpenAlias(pipe_hnd, mem_ctx,
1899 MAXIMUM_ALLOWED_ACCESS,
1903 if (!NT_STATUS_IS_OK(result)) {
1904 d_fprintf(stderr, "Request open_alias failed\n");
1908 result = rpccli_samr_DeleteDomAlias(pipe_hnd, mem_ctx,
1912 d_fprintf(stderr, "%s is of type %s. This command is only for deleting local or global groups\n",
1913 argv[0],sid_type_lookup(name_types[0]));
1914 result = NT_STATUS_UNSUCCESSFUL;
1919 if (NT_STATUS_IS_OK(result)) {
1921 d_printf("Deleted %s '%s'\n",sid_type_lookup(name_types[0]),argv[0]);
1923 d_fprintf(stderr, "Deleting of %s failed: %s\n",argv[0],
1924 get_friendly_nt_error_msg(result));
1932 static int rpc_group_delete(int argc, const char **argv)
1934 return run_rpc_command(NULL, PI_SAMR, 0, rpc_group_delete_internals,
1938 static void init_lsa_String(struct lsa_String *name, const char *s)
1943 static NTSTATUS rpc_group_add_internals(const DOM_SID *domain_sid,
1944 const char *domain_name,
1945 struct cli_state *cli,
1946 struct rpc_pipe_client *pipe_hnd,
1947 TALLOC_CTX *mem_ctx,
1951 POLICY_HND connect_pol, domain_pol, group_pol;
1952 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1953 GROUP_INFO_CTR group_info;
1954 struct lsa_String grp_name;
1958 d_printf("Group name must be specified\n");
1959 rpc_group_usage(argc, argv);
1960 return NT_STATUS_OK;
1963 init_lsa_String(&grp_name, argv[0]);
1965 /* Get sam policy handle */
1967 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1969 if (!NT_STATUS_IS_OK(result)) goto done;
1971 /* Get domain policy handle */
1973 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
1975 MAXIMUM_ALLOWED_ACCESS,
1976 CONST_DISCARD(struct dom_sid2 *, domain_sid),
1978 if (!NT_STATUS_IS_OK(result)) goto done;
1980 /* Create the group */
1982 result = rpccli_samr_CreateDomainGroup(pipe_hnd, mem_ctx,
1985 MAXIMUM_ALLOWED_ACCESS,
1988 if (!NT_STATUS_IS_OK(result)) goto done;
1990 if (strlen(opt_comment) == 0) goto done;
1992 /* We've got a comment to set */
1994 group_info.switch_value1 = 4;
1995 init_samr_group_info4(&group_info.group.info4, opt_comment);
1997 result = rpccli_samr_set_groupinfo(pipe_hnd, mem_ctx, &group_pol, &group_info);
1998 if (!NT_STATUS_IS_OK(result)) goto done;
2001 if (NT_STATUS_IS_OK(result))
2002 DEBUG(5, ("add group succeeded\n"));
2004 d_fprintf(stderr, "add group failed: %s\n", nt_errstr(result));
2009 static NTSTATUS rpc_alias_add_internals(const DOM_SID *domain_sid,
2010 const char *domain_name,
2011 struct cli_state *cli,
2012 struct rpc_pipe_client *pipe_hnd,
2013 TALLOC_CTX *mem_ctx,
2017 POLICY_HND connect_pol, domain_pol, alias_pol;
2018 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2019 ALIAS_INFO_CTR alias_info;
2020 struct lsa_String alias_name;
2024 d_printf("Alias name must be specified\n");
2025 rpc_group_usage(argc, argv);
2026 return NT_STATUS_OK;
2029 init_lsa_String(&alias_name, argv[0]);
2031 /* Get sam policy handle */
2033 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
2035 if (!NT_STATUS_IS_OK(result)) goto done;
2037 /* Get domain policy handle */
2039 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
2041 MAXIMUM_ALLOWED_ACCESS,
2042 CONST_DISCARD(struct dom_sid2 *, domain_sid),
2044 if (!NT_STATUS_IS_OK(result)) goto done;
2046 /* Create the group */
2048 result = rpccli_samr_CreateDomAlias(pipe_hnd, mem_ctx,
2051 MAXIMUM_ALLOWED_ACCESS,
2054 if (!NT_STATUS_IS_OK(result)) goto done;
2056 if (strlen(opt_comment) == 0) goto done;
2058 /* We've got a comment to set */
2060 alias_info.level = 3;
2061 init_samr_alias_info3(&alias_info.alias.info3, opt_comment);
2063 result = rpccli_samr_set_aliasinfo(pipe_hnd, mem_ctx, &alias_pol, &alias_info);
2064 if (!NT_STATUS_IS_OK(result)) goto done;
2067 if (NT_STATUS_IS_OK(result))
2068 DEBUG(5, ("add alias succeeded\n"));
2070 d_fprintf(stderr, "add alias failed: %s\n", nt_errstr(result));
2075 static int rpc_group_add(int argc, const char **argv)
2078 return run_rpc_command(NULL, PI_SAMR, 0,
2079 rpc_alias_add_internals,
2082 return run_rpc_command(NULL, PI_SAMR, 0,
2083 rpc_group_add_internals,
2087 static NTSTATUS get_sid_from_name(struct cli_state *cli,
2088 TALLOC_CTX *mem_ctx,
2091 enum lsa_SidType *type)
2093 DOM_SID *sids = NULL;
2094 enum lsa_SidType *types = NULL;
2095 struct rpc_pipe_client *pipe_hnd;
2097 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2099 pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_LSARPC, &result);
2104 result = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, False,
2105 SEC_RIGHTS_MAXIMUM_ALLOWED, &lsa_pol);
2107 if (!NT_STATUS_IS_OK(result)) {
2111 result = rpccli_lsa_lookup_names(pipe_hnd, mem_ctx, &lsa_pol, 1,
2112 &name, NULL, 1, &sids, &types);
2114 if (NT_STATUS_IS_OK(result)) {
2115 sid_copy(sid, &sids[0]);
2119 rpccli_lsa_Close(pipe_hnd, mem_ctx, &lsa_pol);
2123 cli_rpc_pipe_close(pipe_hnd);
2126 if (!NT_STATUS_IS_OK(result) && (StrnCaseCmp(name, "S-", 2) == 0)) {
2128 /* Try as S-1-5-whatever */
2132 if (string_to_sid(&tmp_sid, name)) {
2133 sid_copy(sid, &tmp_sid);
2134 *type = SID_NAME_UNKNOWN;
2135 result = NT_STATUS_OK;
2142 static NTSTATUS rpc_add_groupmem(struct rpc_pipe_client *pipe_hnd,
2143 TALLOC_CTX *mem_ctx,
2144 const DOM_SID *group_sid,
2147 POLICY_HND connect_pol, domain_pol;
2150 POLICY_HND group_pol;
2153 uint32 *rids = NULL;
2154 uint32 *rid_types = NULL;
2158 sid_copy(&sid, group_sid);
2160 if (!sid_split_rid(&sid, &group_rid)) {
2161 return NT_STATUS_UNSUCCESSFUL;
2164 /* Get sam policy handle */
2165 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
2167 if (!NT_STATUS_IS_OK(result)) {
2171 /* Get domain policy handle */
2172 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
2174 MAXIMUM_ALLOWED_ACCESS,
2177 if (!NT_STATUS_IS_OK(result)) {
2181 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, 1000,
2183 &num_rids, &rids, &rid_types);
2185 if (!NT_STATUS_IS_OK(result)) {
2186 d_fprintf(stderr, "Could not lookup up group member %s\n", member);
2190 result = rpccli_samr_OpenGroup(pipe_hnd, mem_ctx,
2192 MAXIMUM_ALLOWED_ACCESS,
2196 if (!NT_STATUS_IS_OK(result)) {
2200 result = rpccli_samr_add_groupmem(pipe_hnd, mem_ctx, &group_pol, rids[0]);
2203 rpccli_samr_Close(pipe_hnd, mem_ctx, &connect_pol);
2207 static NTSTATUS rpc_add_aliasmem(struct rpc_pipe_client *pipe_hnd,
2208 TALLOC_CTX *mem_ctx,
2209 const DOM_SID *alias_sid,
2212 POLICY_HND connect_pol, domain_pol;
2215 POLICY_HND alias_pol;
2218 enum lsa_SidType member_type;
2222 sid_copy(&sid, alias_sid);
2224 if (!sid_split_rid(&sid, &alias_rid)) {
2225 return NT_STATUS_UNSUCCESSFUL;
2228 result = get_sid_from_name(pipe_hnd->cli, mem_ctx, member,
2229 &member_sid, &member_type);
2231 if (!NT_STATUS_IS_OK(result)) {
2232 d_fprintf(stderr, "Could not lookup up group member %s\n", member);
2236 /* Get sam policy handle */
2237 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
2239 if (!NT_STATUS_IS_OK(result)) {
2243 /* Get domain policy handle */
2244 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
2246 MAXIMUM_ALLOWED_ACCESS,
2249 if (!NT_STATUS_IS_OK(result)) {
2253 result = rpccli_samr_OpenAlias(pipe_hnd, mem_ctx,
2255 MAXIMUM_ALLOWED_ACCESS,
2259 if (!NT_STATUS_IS_OK(result)) {
2263 result = rpccli_samr_add_aliasmem(pipe_hnd, mem_ctx, &alias_pol, &member_sid);
2265 if (!NT_STATUS_IS_OK(result)) {
2270 rpccli_samr_Close(pipe_hnd, mem_ctx, &connect_pol);
2274 static NTSTATUS rpc_group_addmem_internals(const DOM_SID *domain_sid,
2275 const char *domain_name,
2276 struct cli_state *cli,
2277 struct rpc_pipe_client *pipe_hnd,
2278 TALLOC_CTX *mem_ctx,
2283 enum lsa_SidType group_type;
2286 d_printf("Usage: 'net rpc group addmem <group> <member>\n");
2287 return NT_STATUS_UNSUCCESSFUL;
2290 if (!NT_STATUS_IS_OK(get_sid_from_name(cli, mem_ctx, argv[0],
2291 &group_sid, &group_type))) {
2292 d_fprintf(stderr, "Could not lookup group name %s\n", argv[0]);
2293 return NT_STATUS_UNSUCCESSFUL;
2296 if (group_type == SID_NAME_DOM_GRP) {
2297 NTSTATUS result = rpc_add_groupmem(pipe_hnd, mem_ctx,
2298 &group_sid, argv[1]);
2300 if (!NT_STATUS_IS_OK(result)) {
2301 d_fprintf(stderr, "Could not add %s to %s: %s\n",
2302 argv[1], argv[0], nt_errstr(result));
2307 if (group_type == SID_NAME_ALIAS) {
2308 NTSTATUS result = rpc_add_aliasmem(pipe_hnd, mem_ctx,
2309 &group_sid, argv[1]);
2311 if (!NT_STATUS_IS_OK(result)) {
2312 d_fprintf(stderr, "Could not add %s to %s: %s\n",
2313 argv[1], argv[0], nt_errstr(result));
2318 d_fprintf(stderr, "Can only add members to global or local groups "
2319 "which %s is not\n", argv[0]);
2321 return NT_STATUS_UNSUCCESSFUL;
2324 static int rpc_group_addmem(int argc, const char **argv)
2326 return run_rpc_command(NULL, PI_SAMR, 0,
2327 rpc_group_addmem_internals,
2331 static NTSTATUS rpc_del_groupmem(struct rpc_pipe_client *pipe_hnd,
2332 TALLOC_CTX *mem_ctx,
2333 const DOM_SID *group_sid,
2336 POLICY_HND connect_pol, domain_pol;
2339 POLICY_HND group_pol;
2342 uint32 *rids = NULL;
2343 uint32 *rid_types = NULL;
2347 sid_copy(&sid, group_sid);
2349 if (!sid_split_rid(&sid, &group_rid))
2350 return NT_STATUS_UNSUCCESSFUL;
2352 /* Get sam policy handle */
2353 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
2355 if (!NT_STATUS_IS_OK(result))
2358 /* Get domain policy handle */
2359 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
2361 MAXIMUM_ALLOWED_ACCESS,
2364 if (!NT_STATUS_IS_OK(result))
2367 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, 1000,
2369 &num_rids, &rids, &rid_types);
2371 if (!NT_STATUS_IS_OK(result)) {
2372 d_fprintf(stderr, "Could not lookup up group member %s\n", member);
2376 result = rpccli_samr_OpenGroup(pipe_hnd, mem_ctx,
2378 MAXIMUM_ALLOWED_ACCESS,
2382 if (!NT_STATUS_IS_OK(result))
2385 result = rpccli_samr_del_groupmem(pipe_hnd, mem_ctx, &group_pol, rids[0]);
2388 rpccli_samr_Close(pipe_hnd, mem_ctx, &connect_pol);
2392 static NTSTATUS rpc_del_aliasmem(struct rpc_pipe_client *pipe_hnd,
2393 TALLOC_CTX *mem_ctx,
2394 const DOM_SID *alias_sid,
2397 POLICY_HND connect_pol, domain_pol;
2400 POLICY_HND alias_pol;
2403 enum lsa_SidType member_type;
2407 sid_copy(&sid, alias_sid);
2409 if (!sid_split_rid(&sid, &alias_rid))
2410 return NT_STATUS_UNSUCCESSFUL;
2412 result = get_sid_from_name(pipe_hnd->cli, mem_ctx, member,
2413 &member_sid, &member_type);
2415 if (!NT_STATUS_IS_OK(result)) {
2416 d_fprintf(stderr, "Could not lookup up group member %s\n", member);
2420 /* Get sam policy handle */
2421 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
2423 if (!NT_STATUS_IS_OK(result)) {
2427 /* Get domain policy handle */
2428 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
2430 MAXIMUM_ALLOWED_ACCESS,
2433 if (!NT_STATUS_IS_OK(result)) {
2437 result = rpccli_samr_OpenAlias(pipe_hnd, mem_ctx,
2439 MAXIMUM_ALLOWED_ACCESS,
2443 if (!NT_STATUS_IS_OK(result))
2446 result = rpccli_samr_del_aliasmem(pipe_hnd, mem_ctx, &alias_pol, &member_sid);
2448 if (!NT_STATUS_IS_OK(result))
2452 rpccli_samr_Close(pipe_hnd, mem_ctx, &connect_pol);
2456 static NTSTATUS rpc_group_delmem_internals(const DOM_SID *domain_sid,
2457 const char *domain_name,
2458 struct cli_state *cli,
2459 struct rpc_pipe_client *pipe_hnd,
2460 TALLOC_CTX *mem_ctx,
2465 enum lsa_SidType group_type;
2468 d_printf("Usage: 'net rpc group delmem <group> <member>\n");
2469 return NT_STATUS_UNSUCCESSFUL;
2472 if (!NT_STATUS_IS_OK(get_sid_from_name(cli, mem_ctx, argv[0],
2473 &group_sid, &group_type))) {
2474 d_fprintf(stderr, "Could not lookup group name %s\n", argv[0]);
2475 return NT_STATUS_UNSUCCESSFUL;
2478 if (group_type == SID_NAME_DOM_GRP) {
2479 NTSTATUS result = rpc_del_groupmem(pipe_hnd, mem_ctx,
2480 &group_sid, argv[1]);
2482 if (!NT_STATUS_IS_OK(result)) {
2483 d_fprintf(stderr, "Could not del %s from %s: %s\n",
2484 argv[1], argv[0], nt_errstr(result));
2489 if (group_type == SID_NAME_ALIAS) {
2490 NTSTATUS result = rpc_del_aliasmem(pipe_hnd, mem_ctx,
2491 &group_sid, argv[1]);
2493 if (!NT_STATUS_IS_OK(result)) {
2494 d_fprintf(stderr, "Could not del %s from %s: %s\n",
2495 argv[1], argv[0], nt_errstr(result));
2500 d_fprintf(stderr, "Can only delete members from global or local groups "
2501 "which %s is not\n", argv[0]);
2503 return NT_STATUS_UNSUCCESSFUL;
2506 static int rpc_group_delmem(int argc, const char **argv)
2508 return run_rpc_command(NULL, PI_SAMR, 0,
2509 rpc_group_delmem_internals,
2514 * List groups on a remote RPC server
2516 * All parameters are provided by the run_rpc_command function, except for
2517 * argc, argv which are passes through.
2519 * @param domain_sid The domain sid acquired from the remote server
2520 * @param cli A cli_state connected to the server.
2521 * @param mem_ctx Talloc context, destoyed on completion of the function.
2522 * @param argc Standard main() style argc
2523 * @param argv Standard main() style argv. Initial components are already
2526 * @return Normal NTSTATUS return.
2529 static NTSTATUS rpc_group_list_internals(const DOM_SID *domain_sid,
2530 const char *domain_name,
2531 struct cli_state *cli,
2532 struct rpc_pipe_client *pipe_hnd,
2533 TALLOC_CTX *mem_ctx,
2537 POLICY_HND connect_pol, domain_pol;
2538 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2539 uint32 start_idx=0, max_entries=250, num_entries, i, loop_count = 0;
2540 struct acct_info *groups;
2541 bool global = False;
2543 bool builtin = False;
2551 for (i=0; i<argc; i++) {
2552 if (strequal(argv[i], "global"))
2555 if (strequal(argv[i], "local"))
2558 if (strequal(argv[i], "builtin"))
2562 /* Get sam policy handle */
2564 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
2566 if (!NT_STATUS_IS_OK(result)) {
2570 /* Get domain policy handle */
2572 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
2574 MAXIMUM_ALLOWED_ACCESS,
2575 CONST_DISCARD(struct dom_sid2 *, domain_sid),
2577 if (!NT_STATUS_IS_OK(result)) {
2581 /* Query domain groups */
2582 if (opt_long_list_entries)
2583 d_printf("\nGroup name Comment"\
2584 "\n-----------------------------\n");
2586 SAM_DISPINFO_CTR ctr;
2587 SAM_DISPINFO_3 info3;
2592 ctr.sam.info3 = &info3;
2596 get_query_dispinfo_params(
2597 loop_count, &max_entries, &max_size);
2599 result = rpccli_samr_query_dispinfo(pipe_hnd, mem_ctx, &domain_pol,
2600 &start_idx, 3, &num_entries,
2601 max_entries, max_size, &ctr);
2603 if (!NT_STATUS_IS_OK(result) &&
2604 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
2607 for (i = 0; i < num_entries; i++) {
2609 fstring group, desc;
2611 unistr2_to_ascii(group, &(&ctr.sam.info3->str[i])->uni_grp_name, sizeof(group));
2612 unistr2_to_ascii(desc, &(&ctr.sam.info3->str[i])->uni_grp_desc, sizeof(desc));
2614 if (opt_long_list_entries)
2615 printf("%-21.21s %-50.50s\n",
2618 printf("%s\n", group);
2620 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
2621 /* query domain aliases */
2626 /* The max_size field in cli_samr_enum_als_groups is more like
2627 * an account_control field with indiviual bits what to
2628 * retrieve. Set this to 0xffff as NT4 usrmgr.exe does to get
2629 * everything. I'm too lazy (sorry) to get this through to
2630 * rpc_parse/ etc. Volker */
2632 result = rpccli_samr_enum_als_groups(pipe_hnd, mem_ctx, &domain_pol,
2634 &groups, &num_entries);
2636 if (!NT_STATUS_IS_OK(result) &&
2637 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
2640 for (i = 0; i < num_entries; i++) {
2642 char *description = NULL;
2644 if (opt_long_list_entries) {
2646 POLICY_HND alias_pol;
2649 if ((NT_STATUS_IS_OK(rpccli_samr_OpenAlias(pipe_hnd, mem_ctx,
2654 (NT_STATUS_IS_OK(rpccli_samr_query_alias_info(pipe_hnd, mem_ctx,
2657 (NT_STATUS_IS_OK(rpccli_samr_Close(pipe_hnd, mem_ctx,
2659 description = unistr2_to_ascii_talloc(mem_ctx,
2660 ctr.alias.info3.description.string);
2664 if (description != NULL) {
2665 printf("%-21.21s %-50.50s\n",
2666 groups[i].acct_name,
2669 printf("%s\n", groups[i].acct_name);
2672 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
2673 rpccli_samr_Close(pipe_hnd, mem_ctx, &domain_pol);
2674 /* Get builtin policy handle */
2676 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
2678 MAXIMUM_ALLOWED_ACCESS,
2679 CONST_DISCARD(struct dom_sid2 *, &global_sid_Builtin),
2681 if (!NT_STATUS_IS_OK(result)) {
2684 /* query builtin aliases */
2687 if (!builtin) break;
2689 result = rpccli_samr_enum_als_groups(pipe_hnd, mem_ctx, &domain_pol,
2690 &start_idx, max_entries,
2691 &groups, &num_entries);
2693 if (!NT_STATUS_IS_OK(result) &&
2694 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
2697 for (i = 0; i < num_entries; i++) {
2699 char *description = NULL;
2701 if (opt_long_list_entries) {
2703 POLICY_HND alias_pol;
2706 if ((NT_STATUS_IS_OK(rpccli_samr_OpenAlias(pipe_hnd, mem_ctx,
2711 (NT_STATUS_IS_OK(rpccli_samr_query_alias_info(pipe_hnd, mem_ctx,
2714 (NT_STATUS_IS_OK(rpccli_samr_Close(pipe_hnd, mem_ctx,
2716 description = unistr2_to_ascii_talloc(mem_ctx,
2717 ctr.alias.info3.description.string);
2721 if (description != NULL) {
2722 printf("%-21.21s %-50.50s\n",
2723 groups[i].acct_name,
2726 printf("%s\n", groups[i].acct_name);
2729 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
2735 static int rpc_group_list(int argc, const char **argv)
2737 return run_rpc_command(NULL, PI_SAMR, 0,
2738 rpc_group_list_internals,
2742 static NTSTATUS rpc_list_group_members(struct rpc_pipe_client *pipe_hnd,
2743 TALLOC_CTX *mem_ctx,
2744 const char *domain_name,
2745 const DOM_SID *domain_sid,
2746 POLICY_HND *domain_pol,
2750 POLICY_HND group_pol;
2751 uint32 num_members, *group_rids, *group_attrs;
2758 sid_to_fstring(sid_str, domain_sid);
2760 result = rpccli_samr_OpenGroup(pipe_hnd, mem_ctx,
2762 MAXIMUM_ALLOWED_ACCESS,
2766 if (!NT_STATUS_IS_OK(result))
2769 result = rpccli_samr_query_groupmem(pipe_hnd, mem_ctx, &group_pol,
2770 &num_members, &group_rids,
2773 if (!NT_STATUS_IS_OK(result))
2776 while (num_members > 0) {
2777 int this_time = 512;
2779 if (num_members < this_time)
2780 this_time = num_members;
2782 result = rpccli_samr_lookup_rids(pipe_hnd, mem_ctx, domain_pol,
2783 this_time, group_rids,
2784 &num_names, &names, &name_types);
2786 if (!NT_STATUS_IS_OK(result))
2789 /* We only have users as members, but make the output
2790 the same as the output of alias members */
2792 for (i = 0; i < this_time; i++) {
2794 if (opt_long_list_entries) {
2795 printf("%s-%d %s\\%s %d\n", sid_str,
2796 group_rids[i], domain_name, names[i],
2799 printf("%s\\%s\n", domain_name, names[i]);
2803 num_members -= this_time;
2807 return NT_STATUS_OK;
2810 static NTSTATUS rpc_list_alias_members(struct rpc_pipe_client *pipe_hnd,
2811 TALLOC_CTX *mem_ctx,
2812 POLICY_HND *domain_pol,
2816 struct rpc_pipe_client *lsa_pipe;
2817 POLICY_HND alias_pol, lsa_pol;
2819 DOM_SID *alias_sids;
2822 enum lsa_SidType *types;
2825 result = rpccli_samr_OpenAlias(pipe_hnd, mem_ctx,
2827 MAXIMUM_ALLOWED_ACCESS,
2831 if (!NT_STATUS_IS_OK(result))
2834 result = rpccli_samr_query_aliasmem(pipe_hnd, mem_ctx, &alias_pol,
2835 &num_members, &alias_sids);
2837 if (!NT_STATUS_IS_OK(result)) {
2838 d_fprintf(stderr, "Couldn't list alias members\n");
2842 if (num_members == 0) {
2843 return NT_STATUS_OK;
2846 lsa_pipe = cli_rpc_pipe_open_noauth(pipe_hnd->cli, PI_LSARPC, &result);
2848 d_fprintf(stderr, "Couldn't open LSA pipe. Error was %s\n",
2849 nt_errstr(result) );
2853 result = rpccli_lsa_open_policy(lsa_pipe, mem_ctx, True,
2854 SEC_RIGHTS_MAXIMUM_ALLOWED, &lsa_pol);
2856 if (!NT_STATUS_IS_OK(result)) {
2857 d_fprintf(stderr, "Couldn't open LSA policy handle\n");
2858 cli_rpc_pipe_close(lsa_pipe);
2862 result = rpccli_lsa_lookup_sids(lsa_pipe, mem_ctx, &lsa_pol, num_members,
2864 &domains, &names, &types);
2866 if (!NT_STATUS_IS_OK(result) &&
2867 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
2868 d_fprintf(stderr, "Couldn't lookup SIDs\n");
2869 cli_rpc_pipe_close(lsa_pipe);
2873 for (i = 0; i < num_members; i++) {
2875 sid_to_fstring(sid_str, &alias_sids[i]);
2877 if (opt_long_list_entries) {
2878 printf("%s %s\\%s %d\n", sid_str,
2879 domains[i] ? domains[i] : "*unknown*",
2880 names[i] ? names[i] : "*unknown*", types[i]);
2883 printf("%s\\%s\n", domains[i], names[i]);
2885 printf("%s\n", sid_str);
2889 cli_rpc_pipe_close(lsa_pipe);
2890 return NT_STATUS_OK;
2893 static NTSTATUS rpc_group_members_internals(const DOM_SID *domain_sid,
2894 const char *domain_name,
2895 struct cli_state *cli,
2896 struct rpc_pipe_client *pipe_hnd,
2897 TALLOC_CTX *mem_ctx,
2902 POLICY_HND connect_pol, domain_pol;
2903 uint32 num_rids, *rids, *rid_types;
2905 /* Get sam policy handle */
2907 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
2910 if (!NT_STATUS_IS_OK(result))
2913 /* Get domain policy handle */
2915 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
2917 MAXIMUM_ALLOWED_ACCESS,
2918 CONST_DISCARD(struct dom_sid2 *, domain_sid),
2921 if (!NT_STATUS_IS_OK(result))
2924 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, 1000,
2925 1, argv, &num_rids, &rids, &rid_types);
2927 if (!NT_STATUS_IS_OK(result)) {
2929 /* Ok, did not find it in the global sam, try with builtin */
2931 DOM_SID sid_Builtin;
2933 rpccli_samr_Close(pipe_hnd, mem_ctx, &domain_pol);
2935 string_to_sid(&sid_Builtin, "S-1-5-32");
2937 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
2939 MAXIMUM_ALLOWED_ACCESS,
2943 if (!NT_STATUS_IS_OK(result)) {
2944 d_fprintf(stderr, "Couldn't find group %s\n", argv[0]);
2948 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, 1000,
2952 if (!NT_STATUS_IS_OK(result)) {
2953 d_fprintf(stderr, "Couldn't find group %s\n", argv[0]);
2958 if (num_rids != 1) {
2959 d_fprintf(stderr, "Couldn't find group %s\n", argv[0]);
2963 if (rid_types[0] == SID_NAME_DOM_GRP) {
2964 return rpc_list_group_members(pipe_hnd, mem_ctx, domain_name,
2965 domain_sid, &domain_pol,
2969 if (rid_types[0] == SID_NAME_ALIAS) {
2970 return rpc_list_alias_members(pipe_hnd, mem_ctx, &domain_pol,
2974 return NT_STATUS_NO_SUCH_GROUP;
2977 static int rpc_group_members(int argc, const char **argv)
2980 return rpc_group_usage(argc, argv);
2983 return run_rpc_command(NULL, PI_SAMR, 0,
2984 rpc_group_members_internals,
2988 static NTSTATUS rpc_group_rename_internals(const DOM_SID *domain_sid,
2989 const char *domain_name,
2990 struct cli_state *cli,
2991 struct rpc_pipe_client *pipe_hnd,
2992 TALLOC_CTX *mem_ctx,
2997 POLICY_HND connect_pol, domain_pol, group_pol;
2998 uint32 num_rids, *rids, *rid_types;
3002 d_printf("Usage: 'net rpc group rename group newname'\n");
3003 return NT_STATUS_UNSUCCESSFUL;
3006 /* Get sam policy handle */
3008 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
3011 if (!NT_STATUS_IS_OK(result))
3014 /* Get domain policy handle */
3016 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
3018 MAXIMUM_ALLOWED_ACCESS,
3019 CONST_DISCARD(struct dom_sid2 *, domain_sid),
3022 if (!NT_STATUS_IS_OK(result))
3025 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, 1000,
3026 1, argv, &num_rids, &rids, &rid_types);
3028 if (num_rids != 1) {
3029 d_fprintf(stderr, "Couldn't find group %s\n", argv[0]);
3033 if (rid_types[0] != SID_NAME_DOM_GRP) {
3034 d_fprintf(stderr, "Can only rename domain groups\n");
3035 return NT_STATUS_UNSUCCESSFUL;
3038 result = rpccli_samr_OpenGroup(pipe_hnd, mem_ctx,
3040 MAXIMUM_ALLOWED_ACCESS,
3044 if (!NT_STATUS_IS_OK(result))
3049 ctr.switch_value1 = 2;
3050 init_samr_group_info2(&ctr.group.info2, argv[1]);
3052 result = rpccli_samr_set_groupinfo(pipe_hnd, mem_ctx, &group_pol, &ctr);
3054 if (!NT_STATUS_IS_OK(result))
3057 return NT_STATUS_NO_SUCH_GROUP;
3060 static int rpc_group_rename(int argc, const char **argv)
3063 return rpc_group_usage(argc, argv);
3066 return run_rpc_command(NULL, PI_SAMR, 0,
3067 rpc_group_rename_internals,
3072 * 'net rpc group' entrypoint.
3073 * @param argc Standard main() style argc
3074 * @param argc Standard main() style argv. Initial components are already
3078 int net_rpc_group(int argc, const char **argv)
3080 struct functable func[] = {
3081 {"add", rpc_group_add},
3082 {"delete", rpc_group_delete},
3083 {"addmem", rpc_group_addmem},
3084 {"delmem", rpc_group_delmem},
3085 {"list", rpc_group_list},
3086 {"members", rpc_group_members},
3087 {"rename", rpc_group_rename},
3092 return run_rpc_command(NULL, PI_SAMR, 0,
3093 rpc_group_list_internals,
3097 return net_run_function(argc, argv, func, rpc_group_usage);
3100 /****************************************************************************/
3102 static int rpc_share_usage(int argc, const char **argv)
3104 return net_help_share(argc, argv);
3108 * Add a share on a remote RPC server
3110 * All parameters are provided by the run_rpc_command function, except for
3111 * argc, argv which are passes through.
3113 * @param domain_sid The domain sid acquired from the remote server
3114 * @param cli A cli_state connected to the server.
3115 * @param mem_ctx Talloc context, destoyed on completion of the function.
3116 * @param argc Standard main() style argc
3117 * @param argv Standard main() style argv. Initial components are already
3120 * @return Normal NTSTATUS return.
3122 static NTSTATUS rpc_share_add_internals(const DOM_SID *domain_sid,
3123 const char *domain_name,
3124 struct cli_state *cli,
3125 struct rpc_pipe_client *pipe_hnd,
3126 TALLOC_CTX *mem_ctx,int argc,
3132 uint32 type = STYPE_DISKTREE; /* only allow disk shares to be added */
3133 uint32 num_users=0, perms=0;
3134 char *password=NULL; /* don't allow a share password */
3137 if ((sharename = talloc_strdup(mem_ctx, argv[0])) == NULL) {
3138 return NT_STATUS_NO_MEMORY;
3141 path = strchr(sharename, '=');
3143 return NT_STATUS_UNSUCCESSFUL;
3146 result = rpccli_srvsvc_net_share_add(pipe_hnd, mem_ctx, sharename, type,
3147 opt_comment, perms, opt_maxusers,
3148 num_users, path, password,
3150 return werror_to_ntstatus(result);
3153 static int rpc_share_add(int argc, const char **argv)
3155 if ((argc < 1) || !strchr(argv[0], '=')) {
3156 DEBUG(1,("Sharename or path not specified on add\n"));
3157 return rpc_share_usage(argc, argv);
3159 return run_rpc_command(NULL, PI_SRVSVC, 0,
3160 rpc_share_add_internals,
3165 * Delete a share on a remote RPC server
3167 * All parameters are provided by the run_rpc_command function, except for
3168 * argc, argv which are passes through.
3170 * @param domain_sid The domain sid acquired from the remote server
3171 * @param cli A cli_state connected to the server.
3172 * @param mem_ctx Talloc context, destoyed on completion of the function.
3173 * @param argc Standard main() style argc
3174 * @param argv Standard main() style argv. Initial components are already
3177 * @return Normal NTSTATUS return.
3179 static NTSTATUS rpc_share_del_internals(const DOM_SID *domain_sid,
3180 const char *domain_name,
3181 struct cli_state *cli,
3182 struct rpc_pipe_client *pipe_hnd,
3183 TALLOC_CTX *mem_ctx,
3189 result = rpccli_srvsvc_net_share_del(pipe_hnd, mem_ctx, argv[0]);
3190 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
3194 * Delete a share on a remote RPC server
3196 * @param domain_sid The domain sid acquired from the remote server
3197 * @param argc Standard main() style argc
3198 * @param argv Standard main() style argv. Initial components are already
3201 * @return A shell status integer (0 for success)
3203 static int rpc_share_delete(int argc, const char **argv)
3206 DEBUG(1,("Sharename not specified on delete\n"));
3207 return rpc_share_usage(argc, argv);
3209 return run_rpc_command(NULL, PI_SRVSVC, 0,
3210 rpc_share_del_internals,
3215 * Formatted print of share info
3217 * @param info1 pointer to SRV_SHARE_INFO_1 to format
3220 static void display_share_info_1(SRV_SHARE_INFO_1 *info1)
3222 fstring netname = "", remark = "";
3224 rpcstr_pull_unistr2_fstring(netname, &info1->info_1_str.uni_netname);
3225 rpcstr_pull_unistr2_fstring(remark, &info1->info_1_str.uni_remark);
3227 if (opt_long_list_entries) {
3228 d_printf("%-12s %-8.8s %-50s\n",
3229 netname, share_type[info1->info_1.type & ~(STYPE_TEMPORARY|STYPE_HIDDEN)], remark);
3231 d_printf("%s\n", netname);
3236 static WERROR get_share_info(struct rpc_pipe_client *pipe_hnd,
3237 TALLOC_CTX *mem_ctx,
3241 SRV_SHARE_INFO_CTR *ctr)
3244 SRV_SHARE_INFO info;
3246 /* no specific share requested, enumerate all */
3250 uint32 preferred_len = 0xffffffff;
3252 init_enum_hnd(&hnd, 0);
3254 return rpccli_srvsvc_net_share_enum(pipe_hnd, mem_ctx, level, ctr,
3255 preferred_len, &hnd);
3258 /* request just one share */
3259 result = rpccli_srvsvc_net_share_get_info(pipe_hnd, mem_ctx, argv[0], level, &info);
3261 if (!W_ERROR_IS_OK(result))
3267 ctr->info_level = ctr->switch_value = level;
3268 ctr->ptr_share_info = ctr->ptr_entries = 1;
3269 ctr->num_entries = ctr->num_entries2 = 1;
3275 SRV_SHARE_INFO_1 *info1;
3277 ctr->share.info1 = TALLOC_ARRAY(mem_ctx, SRV_SHARE_INFO_1, 1);
3278 if (ctr->share.info1 == NULL) {
3279 result = WERR_NOMEM;
3282 info1 = ctr->share.info1;
3284 memset(ctr->share.info1, 0, sizeof(SRV_SHARE_INFO_1));
3286 /* Copy pointer crap */
3288 memcpy(&info1->info_1, &info.share.info1.info_1, sizeof(SH_INFO_1));
3290 /* Duplicate strings */
3292 s = unistr2_to_ascii_talloc(mem_ctx, &info.share.info1.info_1_str.uni_netname);
3294 init_unistr2(&info1->info_1_str.uni_netname, s, UNI_STR_TERMINATE);
3296 s = unistr2_to_ascii_talloc(mem_ctx, &info.share.info1.info_1_str.uni_remark);
3298 init_unistr2(&info1->info_1_str.uni_remark, s, UNI_STR_TERMINATE);
3303 SRV_SHARE_INFO_2 *info2;
3305 ctr->share.info2 = TALLOC_ARRAY(mem_ctx, SRV_SHARE_INFO_2, 1);
3306 if (ctr->share.info2 == NULL) {
3307 result = WERR_NOMEM;
3310 info2 = ctr->share.info2;
3312 memset(ctr->share.info2, 0, sizeof(SRV_SHARE_INFO_2));
3314 /* Copy pointer crap */
3316 memcpy(&info2->info_2, &info.share.info2.info_2, sizeof(SH_INFO_2));
3318 /* Duplicate strings */
3320 s = unistr2_to_ascii_talloc(mem_ctx, &info.share.info2.info_2_str.uni_netname);
3322 init_unistr2(&info2->info_2_str.uni_netname, s, UNI_STR_TERMINATE);
3324 s = unistr2_to_ascii_talloc(mem_ctx, &info.share.info2.info_2_str.uni_remark);
3326 init_unistr2(&info2->info_2_str.uni_remark, s, UNI_STR_TERMINATE);
3328 s = unistr2_to_ascii_talloc(mem_ctx, &info.share.info2.info_2_str.uni_path);
3330 init_unistr2(&info2->info_2_str.uni_path, s, UNI_STR_TERMINATE);
3332 s = unistr2_to_ascii_talloc(mem_ctx, &info.share.info2.info_2_str.uni_passwd);
3334 init_unistr2(&info2->info_2_str.uni_passwd, s, UNI_STR_TERMINATE);
3339 SRV_SHARE_INFO_502 *info502;
3341 ctr->share.info502 = TALLOC_ARRAY(mem_ctx, SRV_SHARE_INFO_502, 1);
3342 if (ctr->share.info502 == NULL) {
3343 result = WERR_NOMEM;
3346 info502 = ctr->share.info502;
3348 memset(ctr->share.info502, 0, sizeof(SRV_SHARE_INFO_502));
3350 /* Copy pointer crap */
3352 memcpy(&info502->info_502, &info.share.info502.info_502, sizeof(SH_INFO_502));
3354 /* Duplicate strings */
3356 s = unistr2_to_ascii_talloc(mem_ctx, &info.share.info502.info_502_str.uni_netname);
3358 init_unistr2(&info502->info_502_str.uni_netname, s, UNI_STR_TERMINATE);
3360 s = unistr2_to_ascii_talloc(mem_ctx, &info.share.info502.info_502_str.uni_remark);
3362 init_unistr2(&info502->info_502_str.uni_remark, s, UNI_STR_TERMINATE);
3364 s = unistr2_to_ascii_talloc(mem_ctx, &info.share.info502.info_502_str.uni_path);
3366 init_unistr2(&info502->info_502_str.uni_path, s, UNI_STR_TERMINATE);
3368 s = unistr2_to_ascii_talloc(mem_ctx, &info.share.info502.info_502_str.uni_passwd);
3370 init_unistr2(&info502->info_502_str.uni_passwd, s, UNI_STR_TERMINATE);
3372 info502->info_502_str.sd = dup_sec_desc(mem_ctx, info.share.info502.info_502_str.sd);
3383 * List shares on a remote RPC server
3385 * All parameters are provided by the run_rpc_command function, except for
3386 * argc, argv which are passes through.
3388 * @param domain_sid The domain sid acquired from the remote server
3389 * @param cli A cli_state connected to the server.
3390 * @param mem_ctx Talloc context, destoyed on completion of the function.
3391 * @param argc Standard main() style argc
3392 * @param argv Standard main() style argv. Initial components are already
3395 * @return Normal NTSTATUS return.
3398 static NTSTATUS rpc_share_list_internals(const DOM_SID *domain_sid,
3399 const char *domain_name,
3400 struct cli_state *cli,
3401 struct rpc_pipe_client *pipe_hnd,
3402 TALLOC_CTX *mem_ctx,
3406 SRV_SHARE_INFO_CTR ctr;
3408 uint32 i, level = 1;
3410 result = get_share_info(pipe_hnd, mem_ctx, level, argc, argv, &ctr);
3411 if (!W_ERROR_IS_OK(result))
3414 /* Display results */
3416 if (opt_long_list_entries) {
3418 "\nEnumerating shared resources (exports) on remote server:\n\n"\
3419 "\nShare name Type Description\n"\
3420 "---------- ---- -----------\n");
3422 for (i = 0; i < ctr.num_entries; i++)
3423 display_share_info_1(&ctr.share.info1[i]);
3425 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
3429 * 'net rpc share list' entrypoint.
3430 * @param argc Standard main() style argc
3431 * @param argv Standard main() style argv. Initial components are already
3434 static int rpc_share_list(int argc, const char **argv)
3436 return run_rpc_command(NULL, PI_SRVSVC, 0, rpc_share_list_internals, argc, argv);
3439 static bool check_share_availability(struct cli_state *cli, const char *netname)
3441 if (!cli_send_tconX(cli, netname, "A:", "", 0)) {
3442 d_printf("skipping [%s]: not a file share.\n", netname);
3452 static bool check_share_sanity(struct cli_state *cli, fstring netname, uint32 type)
3454 /* only support disk shares */
3455 if (! ( type == STYPE_DISKTREE || type == (STYPE_DISKTREE | STYPE_HIDDEN)) ) {
3456 printf("share [%s] is not a diskshare (type: %x)\n", netname, type);
3460 /* skip builtin shares */
3461 /* FIXME: should print$ be added too ? */
3462 if (strequal(netname,"IPC$") || strequal(netname,"ADMIN$") ||
3463 strequal(netname,"global"))
3466 if (opt_exclude && in_list(netname, opt_exclude, False)) {
3467 printf("excluding [%s]\n", netname);
3471 return check_share_availability(cli, netname);
3475 * Migrate shares from a remote RPC server to the local RPC srever
3477 * All parameters are provided by the run_rpc_command function, except for
3478 * argc, argv which are passes through.
3480 * @param domain_sid The domain sid acquired from the remote server
3481 * @param cli A cli_state connected to the server.
3482 * @param mem_ctx Talloc context, destoyed on completion of the function.
3483 * @param argc Standard main() style argc
3484 * @param argv Standard main() style argv. Initial components are already
3487 * @return Normal NTSTATUS return.
3490 static NTSTATUS rpc_share_migrate_shares_internals(const DOM_SID *domain_sid,
3491 const char *domain_name,
3492 struct cli_state *cli,
3493 struct rpc_pipe_client *pipe_hnd,
3494 TALLOC_CTX *mem_ctx,
3499 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
3500 SRV_SHARE_INFO_CTR ctr_src;
3501 uint32 type = STYPE_DISKTREE; /* only allow disk shares to be added */
3502 char *password = NULL; /* don't allow a share password */
3504 struct rpc_pipe_client *srvsvc_pipe = NULL;
3505 struct cli_state *cli_dst = NULL;
3506 uint32 level = 502; /* includes secdesc */
3508 result = get_share_info(pipe_hnd, mem_ctx, level, argc, argv, &ctr_src);
3509 if (!W_ERROR_IS_OK(result))
3512 /* connect destination PI_SRVSVC */
3513 nt_status = connect_dst_pipe(&cli_dst, &srvsvc_pipe, PI_SRVSVC);
3514 if (!NT_STATUS_IS_OK(nt_status))
3518 for (i = 0; i < ctr_src.num_entries; i++) {
3520 fstring netname = "", remark = "", path = "";
3521 /* reset error-code */
3522 nt_status = NT_STATUS_UNSUCCESSFUL;
3524 rpcstr_pull_unistr2_fstring(
3525 netname, &ctr_src.share.info502[i].info_502_str.uni_netname);
3526 rpcstr_pull_unistr2_fstring(
3527 remark, &ctr_src.share.info502[i].info_502_str.uni_remark);
3528 rpcstr_pull_unistr2_fstring(
3529 path, &ctr_src.share.info502[i].info_502_str.uni_path);
3531 if (!check_share_sanity(cli, netname, ctr_src.share.info502[i].info_502.type))
3534 /* finally add the share on the dst server */
3536 printf("migrating: [%s], path: %s, comment: %s, without share-ACLs\n",
3537 netname, path, remark);
3539 result = rpccli_srvsvc_net_share_add(srvsvc_pipe, mem_ctx, netname, type, remark,
3540 ctr_src.share.info502[i].info_502.perms,
3541 ctr_src.share.info502[i].info_502.max_uses,
3542 ctr_src.share.info502[i].info_502.num_uses,
3543 path, password, level,
3546 if (W_ERROR_V(result) == W_ERROR_V(WERR_ALREADY_EXISTS)) {
3547 printf(" [%s] does already exist\n", netname);
3551 if (!W_ERROR_IS_OK(result)) {
3552 printf("cannot add share: %s\n", dos_errstr(result));
3558 nt_status = NT_STATUS_OK;
3562 cli_shutdown(cli_dst);
3570 * Migrate shares from a rpc-server to another
3572 * @param argc Standard main() style argc
3573 * @param argv Standard main() style argv. Initial components are already
3576 * @return A shell status integer (0 for success)
3578 static int rpc_share_migrate_shares(int argc, const char **argv)
3582 printf("no server to migrate\n");
3586 return run_rpc_command(NULL, PI_SRVSVC, 0,
3587 rpc_share_migrate_shares_internals,
3594 * @param f file_info
3595 * @param mask current search mask
3596 * @param state arg-pointer
3599 static void copy_fn(const char *mnt, file_info *f, const char *mask, void *state)
3601 static NTSTATUS nt_status;
3602 static struct copy_clistate *local_state;
3603 static fstring filename, new_mask;
3607 local_state = (struct copy_clistate *)state;
3608 nt_status = NT_STATUS_UNSUCCESSFUL;
3610 if (strequal(f->name, ".") || strequal(f->name, ".."))
3613 DEBUG(3,("got mask: %s, name: %s\n", mask, f->name));
3616 if (f->mode & aDIR) {
3618 DEBUG(3,("got dir: %s\n", f->name));
3620 fstrcpy(dir, local_state->cwd);
3622 fstrcat(dir, f->name);
3624 switch (net_mode_share)
3626 case NET_MODE_SHARE_MIGRATE:
3627 /* create that directory */
3628 nt_status = net_copy_file(local_state->mem_ctx,
3629 local_state->cli_share_src,
3630 local_state->cli_share_dst,
3632 opt_acls? True : False,
3633 opt_attrs? True : False,
3634 opt_timestamps? True : False,
3638 d_fprintf(stderr, "Unsupported mode %d\n", net_mode_share);
3642 if (!NT_STATUS_IS_OK(nt_status))
3643 printf("could not handle dir %s: %s\n",
3644 dir, nt_errstr(nt_status));
3646 /* search below that directory */
3647 fstrcpy(new_mask, dir);
3648 fstrcat(new_mask, "\\*");
3650 old_dir = local_state->cwd;
3651 local_state->cwd = dir;
3652 if (!sync_files(local_state, new_mask))
3653 printf("could not handle files\n");
3654 local_state->cwd = old_dir;
3661 fstrcpy(filename, local_state->cwd);
3662 fstrcat(filename, "\\");
3663 fstrcat(filename, f->name);
3665 DEBUG(3,("got file: %s\n", filename));
3667 switch (net_mode_share)
3669 case NET_MODE_SHARE_MIGRATE:
3670 nt_status = net_copy_file(local_state->mem_ctx,
3671 local_state->cli_share_src,
3672 local_state->cli_share_dst,
3674 opt_acls? True : False,
3675 opt_attrs? True : False,
3676 opt_timestamps? True: False,
3680 d_fprintf(stderr, "Unsupported file mode %d\n", net_mode_share);
3684 if (!NT_STATUS_IS_OK(nt_status))
3685 printf("could not handle file %s: %s\n",
3686 filename, nt_errstr(nt_status));
3691 * sync files, can be called recursivly to list files
3692 * and then call copy_fn for each file
3694 * @param cp_clistate pointer to the copy_clistate we work with
3695 * @param mask the current search mask
3697 * @return Boolean result
3699 static bool sync_files(struct copy_clistate *cp_clistate, const char *mask)
3701 struct cli_state *targetcli;
3702 char *targetpath = NULL;
3704 DEBUG(3,("calling cli_list with mask: %s\n", mask));
3706 if ( !cli_resolve_path(talloc_tos(), "", cp_clistate->cli_share_src,
3707 mask, &targetcli, &targetpath ) ) {
3708 d_fprintf(stderr, "cli_resolve_path %s failed with error: %s\n",
3709 mask, cli_errstr(cp_clistate->cli_share_src));
3713 if (cli_list(targetcli, targetpath, cp_clistate->attribute, copy_fn, cp_clistate) == -1) {
3714 d_fprintf(stderr, "listing %s failed with error: %s\n",
3715 mask, cli_errstr(targetcli));
3724 * Set the top level directory permissions before we do any further copies.
3725 * Should set up ACL inheritance.
3728 bool copy_top_level_perms(struct copy_clistate *cp_clistate,
3729 const char *sharename)
3731 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
3733 switch (net_mode_share) {
3734 case NET_MODE_SHARE_MIGRATE:
3735 DEBUG(3,("calling net_copy_fileattr for '.' directory in share %s\n", sharename));
3736 nt_status = net_copy_fileattr(cp_clistate->mem_ctx,
3737 cp_clistate->cli_share_src,
3738 cp_clistate->cli_share_dst,
3740 opt_acls? True : False,
3741 opt_attrs? True : False,
3742 opt_timestamps? True: False,
3746 d_fprintf(stderr, "Unsupported mode %d\n", net_mode_share);
3750 if (!NT_STATUS_IS_OK(nt_status)) {
3751 printf("Could handle directory attributes for top level directory of share %s. Error %s\n",
3752 sharename, nt_errstr(nt_status));
3760 * Sync all files inside a remote share to another share (over smb)
3762 * All parameters are provided by the run_rpc_command function, except for
3763 * argc, argv which are passes through.
3765 * @param domain_sid The domain sid acquired from the remote server
3766 * @param cli A cli_state connected to the server.
3767 * @param mem_ctx Talloc context, destoyed on completion of the function.
3768 * @param argc Standard main() style argc
3769 * @param argv Standard main() style argv. Initial components are already
3772 * @return Normal NTSTATUS return.
3775 static NTSTATUS rpc_share_migrate_files_internals(const DOM_SID *domain_sid,
3776 const char *domain_name,
3777 struct cli_state *cli,
3778 struct rpc_pipe_client *pipe_hnd,
3779 TALLOC_CTX *mem_ctx,
3784 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
3785 SRV_SHARE_INFO_CTR ctr_src;
3788 struct copy_clistate cp_clistate;
3789 bool got_src_share = False;
3790 bool got_dst_share = False;
3791 const char *mask = "\\*";
3794 dst = SMB_STRDUP(opt_destination?opt_destination:"127.0.0.1");
3796 result = get_share_info(pipe_hnd, mem_ctx, level, argc, argv, &ctr_src);
3798 if (!W_ERROR_IS_OK(result))
3801 for (i = 0; i < ctr_src.num_entries; i++) {
3803 fstring netname = "";
3805 rpcstr_pull_unistr2_fstring(
3806 netname, &ctr_src.share.info502[i].info_502_str.uni_netname);
3808 if (!check_share_sanity(cli, netname, ctr_src.share.info502[i].info_502.type))
3811 /* one might not want to mirror whole discs :) */
3812 if (strequal(netname, "print$") || netname[1] == '$') {
3813 d_printf("skipping [%s]: builtin/hidden share\n", netname);
3817 switch (net_mode_share)
3819 case NET_MODE_SHARE_MIGRATE:
3823 d_fprintf(stderr, "Unsupported mode %d\n", net_mode_share);
3826 printf(" [%s] files and directories %s ACLs, %s DOS Attributes %s\n",
3828 opt_acls ? "including" : "without",
3829 opt_attrs ? "including" : "without",
3830 opt_timestamps ? "(preserving timestamps)" : "");
3832 cp_clistate.mem_ctx = mem_ctx;
3833 cp_clistate.cli_share_src = NULL;
3834 cp_clistate.cli_share_dst = NULL;
3835 cp_clistate.cwd = NULL;
3836 cp_clistate.attribute = aSYSTEM | aHIDDEN | aDIR;
3838 /* open share source */
3839 nt_status = connect_to_service(&cp_clistate.cli_share_src,
3840 &cli->dest_ss, cli->desthost,
3842 if (!NT_STATUS_IS_OK(nt_status))
3845 got_src_share = True;
3847 if (net_mode_share == NET_MODE_SHARE_MIGRATE) {
3848 /* open share destination */
3849 nt_status = connect_to_service(&cp_clistate.cli_share_dst,
3850 NULL, dst, netname, "A:");
3851 if (!NT_STATUS_IS_OK(nt_status))
3854 got_dst_share = True;
3857 if (!copy_top_level_perms(&cp_clistate, netname)) {
3858 d_fprintf(stderr, "Could not handle the top level directory permissions for the share: %s\n", netname);
3859 nt_status = NT_STATUS_UNSUCCESSFUL;
3863 if (!sync_files(&cp_clistate, mask)) {
3864 d_fprintf(stderr, "could not handle files for share: %s\n", netname);
3865 nt_status = NT_STATUS_UNSUCCESSFUL;
3870 nt_status = NT_STATUS_OK;
3875 cli_shutdown(cp_clistate.cli_share_src);
3878 cli_shutdown(cp_clistate.cli_share_dst);
3884 static int rpc_share_migrate_files(int argc, const char **argv)
3888 printf("no server to migrate\n");
3892 return run_rpc_command(NULL, PI_SRVSVC, 0,
3893 rpc_share_migrate_files_internals,
3898 * Migrate share-ACLs from a remote RPC server to the local RPC srever
3900 * All parameters are provided by the run_rpc_command function, except for
3901 * argc, argv which are passes through.
3903 * @param domain_sid The domain sid acquired from the remote server
3904 * @param cli A cli_state connected to the server.
3905 * @param mem_ctx Talloc context, destoyed on completion of the function.
3906 * @param argc Standard main() style argc
3907 * @param argv Standard main() style argv. Initial components are already
3910 * @return Normal NTSTATUS return.
3913 static NTSTATUS rpc_share_migrate_security_internals(const DOM_SID *domain_sid,
3914 const char *domain_name,
3915 struct cli_state *cli,
3916 struct rpc_pipe_client *pipe_hnd,
3917 TALLOC_CTX *mem_ctx,
3922 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
3923 SRV_SHARE_INFO_CTR ctr_src;
3924 SRV_SHARE_INFO info;
3926 struct rpc_pipe_client *srvsvc_pipe = NULL;
3927 struct cli_state *cli_dst = NULL;
3928 uint32 level = 502; /* includes secdesc */
3930 result = get_share_info(pipe_hnd, mem_ctx, level, argc, argv, &ctr_src);
3932 if (!W_ERROR_IS_OK(result))
3935 /* connect destination PI_SRVSVC */
3936 nt_status = connect_dst_pipe(&cli_dst, &srvsvc_pipe, PI_SRVSVC);
3937 if (!NT_STATUS_IS_OK(nt_status))
3941 for (i = 0; i < ctr_src.num_entries; i++) {
3943 fstring netname = "", remark = "", path = "";
3944 /* reset error-code */
3945 nt_status = NT_STATUS_UNSUCCESSFUL;
3947 rpcstr_pull_unistr2_fstring(
3948 netname, &ctr_src.share.info502[i].info_502_str.uni_netname);
3949 rpcstr_pull_unistr2_fstring(
3950 remark, &ctr_src.share.info502[i].info_502_str.uni_remark);
3951 rpcstr_pull_unistr2_fstring(
3952 path, &ctr_src.share.info502[i].info_502_str.uni_path);
3954 if (!check_share_sanity(cli, netname, ctr_src.share.info502[i].info_502.type))
3957 printf("migrating: [%s], path: %s, comment: %s, including share-ACLs\n",
3958 netname, path, remark);
3961 display_sec_desc(ctr_src.share.info502[i].info_502_str.sd);
3966 info.switch_value = level;
3967 info.ptr_share_ctr = 1;
3969 /* FIXME: shouldn't we be able to just set the security descriptor ? */
3970 info.share.info502 = ctr_src.share.info502[i];
3972 /* finally modify the share on the dst server */
3973 result = rpccli_srvsvc_net_share_set_info(srvsvc_pipe, mem_ctx, netname, level, &info);
3975 if (!W_ERROR_IS_OK(result)) {
3976 printf("cannot set share-acl: %s\n", dos_errstr(result));
3982 nt_status = NT_STATUS_OK;
3986 cli_shutdown(cli_dst);
3994 * Migrate share-acls from a rpc-server to another
3996 * @param argc Standard main() style argc
3997 * @param argv Standard main() style argv. Initial components are already
4000 * @return A shell status integer (0 for success)
4002 static int rpc_share_migrate_security(int argc, const char **argv)
4006 printf("no server to migrate\n");
4010 return run_rpc_command(NULL, PI_SRVSVC, 0,
4011 rpc_share_migrate_security_internals,
4016 * Migrate shares (including share-definitions, share-acls and files with acls/attrs)
4017 * from one server to another
4019 * @param argc Standard main() style argc
4020 * @param argv Standard main() style argv. Initial components are already
4023 * @return A shell status integer (0 for success)
4026 static int rpc_share_migrate_all(int argc, const char **argv)
4031 printf("no server to migrate\n");
4035 /* order is important. we don't want to be locked out by the share-acl
4036 * before copying files - gd */
4038 ret = run_rpc_command(NULL, PI_SRVSVC, 0, rpc_share_migrate_shares_internals, argc, argv);
4042 ret = run_rpc_command(NULL, PI_SRVSVC, 0, rpc_share_migrate_files_internals, argc, argv);
4046 return run_rpc_command(NULL, PI_SRVSVC, 0, rpc_share_migrate_security_internals, argc, argv);
4051 * 'net rpc share migrate' entrypoint.
4052 * @param argc Standard main() style argc
4053 * @param argv Standard main() style argv. Initial components are already
4056 static int rpc_share_migrate(int argc, const char **argv)
4059 struct functable func[] = {
4060 {"all", rpc_share_migrate_all},
4061 {"files", rpc_share_migrate_files},
4062 {"help", rpc_share_usage},
4063 {"security", rpc_share_migrate_security},
4064 {"shares", rpc_share_migrate_shares},
4068 net_mode_share = NET_MODE_SHARE_MIGRATE;
4070 return net_run_function(argc, argv, func, rpc_share_usage);
4079 static int num_server_aliases;
4080 static struct full_alias *server_aliases;
4083 * Add an alias to the static list.
4085 static void push_alias(TALLOC_CTX *mem_ctx, struct full_alias *alias)
4087 if (server_aliases == NULL)
4088 server_aliases = SMB_MALLOC_ARRAY(struct full_alias, 100);
4090 server_aliases[num_server_aliases] = *alias;
4091 num_server_aliases += 1;
4095 * For a specific domain on the server, fetch all the aliases
4096 * and their members. Add all of them to the server_aliases.
4099 static NTSTATUS rpc_fetch_domain_aliases(struct rpc_pipe_client *pipe_hnd,
4100 TALLOC_CTX *mem_ctx,
4101 POLICY_HND *connect_pol,
4102 const DOM_SID *domain_sid)
4104 uint32 start_idx, max_entries, num_entries, i;
4105 struct acct_info *groups;
4107 POLICY_HND domain_pol;
4109 /* Get domain policy handle */
4111 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
4113 MAXIMUM_ALLOWED_ACCESS,
4114 CONST_DISCARD(struct dom_sid2 *, domain_sid),
4116 if (!NT_STATUS_IS_OK(result))
4123 result = rpccli_samr_enum_als_groups(pipe_hnd, mem_ctx, &domain_pol,
4124 &start_idx, max_entries,
4125 &groups, &num_entries);
4127 for (i = 0; i < num_entries; i++) {
4129 POLICY_HND alias_pol;
4130 struct full_alias alias;
4134 result = rpccli_samr_OpenAlias(pipe_hnd, mem_ctx,
4136 MAXIMUM_ALLOWED_ACCESS,
4139 if (!NT_STATUS_IS_OK(result))
4142 result = rpccli_samr_query_aliasmem(pipe_hnd, mem_ctx,
4146 if (!NT_STATUS_IS_OK(result))
4149 result = rpccli_samr_Close(pipe_hnd, mem_ctx, &alias_pol);
4150 if (!NT_STATUS_IS_OK(result))
4153 alias.members = NULL;
4155 if (alias.num_members > 0) {
4156 alias.members = SMB_MALLOC_ARRAY(DOM_SID, alias.num_members);
4158 for (j = 0; j < alias.num_members; j++)
4159 sid_copy(&alias.members[j],
4163 sid_copy(&alias.sid, domain_sid);
4164 sid_append_rid(&alias.sid, groups[i].rid);
4166 push_alias(mem_ctx, &alias);
4168 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
4170 result = NT_STATUS_OK;
4173 rpccli_samr_Close(pipe_hnd, mem_ctx, &domain_pol);
4179 * Dump server_aliases as names for debugging purposes.
4182 static NTSTATUS rpc_aliaslist_dump(const DOM_SID *domain_sid,
4183 const char *domain_name,
4184 struct cli_state *cli,
4185 struct rpc_pipe_client *pipe_hnd,
4186 TALLOC_CTX *mem_ctx,
4194 result = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, True,
4195 SEC_RIGHTS_MAXIMUM_ALLOWED,
4197 if (!NT_STATUS_IS_OK(result))
4200 for (i=0; i<num_server_aliases; i++) {
4203 enum lsa_SidType *types;
4206 struct full_alias *alias = &server_aliases[i];
4208 result = rpccli_lsa_lookup_sids(pipe_hnd, mem_ctx, &lsa_pol, 1,
4210 &domains, &names, &types);
4211 if (!NT_STATUS_IS_OK(result))
4214 DEBUG(1, ("%s\\%s %d: ", domains[0], names[0], types[0]));
4216 if (alias->num_members == 0) {
4221 result = rpccli_lsa_lookup_sids(pipe_hnd, mem_ctx, &lsa_pol,
4224 &domains, &names, &types);
4226 if (!NT_STATUS_IS_OK(result) &&
4227 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
4230 for (j=0; j<alias->num_members; j++)
4231 DEBUG(1, ("%s\\%s (%d); ",
4232 domains[j] ? domains[j] : "*unknown*",
4233 names[j] ? names[j] : "*unknown*",types[j]));
4237 rpccli_lsa_Close(pipe_hnd, mem_ctx, &lsa_pol);
4239 return NT_STATUS_OK;
4243 * Fetch a list of all server aliases and their members into
4247 static NTSTATUS rpc_aliaslist_internals(const DOM_SID *domain_sid,
4248 const char *domain_name,
4249 struct cli_state *cli,
4250 struct rpc_pipe_client *pipe_hnd,
4251 TALLOC_CTX *mem_ctx,
4256 POLICY_HND connect_pol;
4258 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
4261 if (!NT_STATUS_IS_OK(result))
4264 result = rpc_fetch_domain_aliases(pipe_hnd, mem_ctx, &connect_pol,
4265 &global_sid_Builtin);
4267 if (!NT_STATUS_IS_OK(result))
4270 result = rpc_fetch_domain_aliases(pipe_hnd, mem_ctx, &connect_pol,
4273 rpccli_samr_Close(pipe_hnd, mem_ctx, &connect_pol);
4278 static void init_user_token(NT_USER_TOKEN *token, DOM_SID *user_sid)
4280 token->num_sids = 4;
4282 if (!(token->user_sids = SMB_MALLOC_ARRAY(DOM_SID, 4))) {
4283 d_fprintf(stderr, "malloc failed\n");
4284 token->num_sids = 0;
4288 token->user_sids[0] = *user_sid;
4289 sid_copy(&token->user_sids[1], &global_sid_World);
4290 sid_copy(&token->user_sids[2], &global_sid_Network);
4291 sid_copy(&token->user_sids[3], &global_sid_Authenticated_Users);
4294 static void free_user_token(NT_USER_TOKEN *token)
4296 SAFE_FREE(token->user_sids);
4299 static bool is_sid_in_token(NT_USER_TOKEN *token, DOM_SID *sid)
4303 for (i=0; i<token->num_sids; i++) {
4304 if (sid_compare(sid, &token->user_sids[i]) == 0)
4310 static void add_sid_to_token(NT_USER_TOKEN *token, DOM_SID *sid)
4312 if (is_sid_in_token(token, sid))
4315 token->user_sids = SMB_REALLOC_ARRAY(token->user_sids, DOM_SID, token->num_sids+1);
4316 if (!token->user_sids) {
4320 sid_copy(&token->user_sids[token->num_sids], sid);
4322 token->num_sids += 1;
4327 NT_USER_TOKEN token;
4330 static void dump_user_token(struct user_token *token)
4334 d_printf("%s\n", token->name);
4336 for (i=0; i<token->token.num_sids; i++) {
4337 d_printf(" %s\n", sid_string_tos(&token->token.user_sids[i]));
4341 static bool is_alias_member(DOM_SID *sid, struct full_alias *alias)
4345 for (i=0; i<alias->num_members; i++) {
4346 if (sid_compare(sid, &alias->members[i]) == 0)
4353 static void collect_sid_memberships(NT_USER_TOKEN *token, DOM_SID sid)
4357 for (i=0; i<num_server_aliases; i++) {
4358 if (is_alias_member(&sid, &server_aliases[i]))
4359 add_sid_to_token(token, &server_aliases[i].sid);
4364 * We got a user token with all the SIDs we can know about without asking the
4365 * server directly. These are the user and domain group sids. All of these can
4366 * be members of aliases. So scan the list of aliases for each of the SIDs and
4367 * add them to the token.
4370 static void collect_alias_memberships(NT_USER_TOKEN *token)
4372 int num_global_sids = token->num_sids;
4375 for (i=0; i<num_global_sids; i++) {
4376 collect_sid_memberships(token, token->user_sids[i]);
4380 static bool get_user_sids(const char *domain, const char *user, NT_USER_TOKEN *token)
4382 struct winbindd_request request;
4383 struct winbindd_response response;
4391 fstr_sprintf(full_name, "%s%c%s",
4392 domain, *lp_winbind_separator(), user);
4394 /* First let's find out the user sid */
4396 ZERO_STRUCT(request);
4397 ZERO_STRUCT(response);
4399 fstrcpy(request.data.name.dom_name, domain);
4400 fstrcpy(request.data.name.name, user);
4402 result = winbindd_request_response(WINBINDD_LOOKUPNAME, &request, &response);
4404 if (result != NSS_STATUS_SUCCESS) {
4405 DEBUG(1, ("winbind could not find %s\n", full_name));
4409 if (response.data.sid.type != SID_NAME_USER) {
4410 DEBUG(1, ("%s is not a user\n", full_name));
4414 string_to_sid(&user_sid, response.data.sid.sid);
4416 init_user_token(token, &user_sid);
4418 /* And now the groups winbind knows about */
4420 ZERO_STRUCT(response);
4422 fstrcpy(request.data.username, full_name);
4424 result = winbindd_request_response(WINBINDD_GETGROUPS, &request, &response);
4426 if (result != NSS_STATUS_SUCCESS) {
4427 DEBUG(1, ("winbind could not get groups of %s\n", full_name));
4431 for (i = 0; i < response.data.num_entries; i++) {
4432 gid_t gid = ((gid_t *)response.extra_data.data)[i];
4435 struct winbindd_request sidrequest;
4436 struct winbindd_response sidresponse;
4438 ZERO_STRUCT(sidrequest);
4439 ZERO_STRUCT(sidresponse);
4441 sidrequest.data.gid = gid;
4443 result = winbindd_request_response(WINBINDD_GID_TO_SID,
4444 &sidrequest, &sidresponse);
4446 if (result != NSS_STATUS_SUCCESS) {
4447 DEBUG(1, ("winbind could not find SID of gid %d\n",
4452 DEBUG(3, (" %s\n", sidresponse.data.sid.sid));
4454 string_to_sid(&sid, sidresponse.data.sid.sid);
4455 add_sid_to_token(token, &sid);
4458 SAFE_FREE(response.extra_data.data);
4464 * Get a list of all user tokens we want to look at
4467 static bool get_user_tokens(int *num_tokens, struct user_token **user_tokens)
4469 struct winbindd_request request;
4470 struct winbindd_response response;
4471 const char *extra_data;
4474 struct user_token *result;
4475 TALLOC_CTX *frame = NULL;
4477 if (lp_winbind_use_default_domain() &&
4478 (opt_target_workgroup == NULL)) {
4479 d_fprintf(stderr, "winbind use default domain = yes set, "
4480 "please specify a workgroup\n");
4484 /* Send request to winbind daemon */
4486 ZERO_STRUCT(request);
4487 ZERO_STRUCT(response);
4489 if (winbindd_request_response(WINBINDD_LIST_USERS, &request, &response) !=
4493 /* Look through extra data */
4495 if (!response.extra_data.data)
4498 extra_data = (const char *)response.extra_data.data;
4501 frame = talloc_stackframe();
4502 while(next_token_talloc(frame, &extra_data, &name, ",")) {
4506 result = SMB_MALLOC_ARRAY(struct user_token, *num_tokens);
4508 if (result == NULL) {
4509 DEBUG(1, ("Could not malloc sid array\n"));
4514 extra_data = (const char *)response.extra_data.data;
4517 while(next_token_talloc(frame, &extra_data, &name, ",")) {
4518 fstring domain, user;
4521 fstrcpy(result[i].name, name);
4523 p = strchr(name, *lp_winbind_separator());
4525 DEBUG(3, ("%s\n", name));
4528 fstrcpy(domain, opt_target_workgroup);
4529 fstrcpy(user, name);
4532 fstrcpy(domain, name);
4537 get_user_sids(domain, user, &(result[i].token));
4541 SAFE_FREE(response.extra_data.data);
4543 *user_tokens = result;
4548 static bool get_user_tokens_from_file(FILE *f,
4550 struct user_token **tokens)
4552 struct user_token *token = NULL;
4557 if (fgets(line, sizeof(line)-1, f) == NULL) {
4561 if (line[strlen(line)-1] == '\n')
4562 line[strlen(line)-1] = '\0';
4564 if (line[0] == ' ') {
4568 string_to_sid(&sid, &line[1]);
4570 if (token == NULL) {
4571 DEBUG(0, ("File does not begin with username"));
4575 add_sid_to_token(&token->token, &sid);
4579 /* And a new user... */
4582 *tokens = SMB_REALLOC_ARRAY(*tokens, struct user_token, *num_tokens);
4583 if (*tokens == NULL) {
4584 DEBUG(0, ("Could not realloc tokens\n"));
4588 token = &((*tokens)[*num_tokens-1]);
4590 fstrcpy(token->name, line);
4591 token->token.num_sids = 0;
4592 token->token.user_sids = NULL;
4601 * Show the list of all users that have access to a share
4604 static void show_userlist(struct rpc_pipe_client *pipe_hnd,
4605 TALLOC_CTX *mem_ctx,
4606 const char *netname,
4608 struct user_token *tokens)
4611 SEC_DESC *share_sd = NULL;
4612 SEC_DESC *root_sd = NULL;
4613 struct cli_state *cli = pipe_hnd->cli;
4615 SRV_SHARE_INFO info;
4619 result = rpccli_srvsvc_net_share_get_info(pipe_hnd, mem_ctx, netname,
4622 if (!W_ERROR_IS_OK(result)) {
4623 DEBUG(1, ("Coult not query secdesc for share %s\n",
4628 share_sd = info.share.info502.info_502_str.sd;
4629 if (share_sd == NULL) {
4630 DEBUG(1, ("Got no secdesc for share %s\n",
4636 if (!cli_send_tconX(cli, netname, "A:", "", 0)) {
4640 fnum = cli_nt_create(cli, "\\", READ_CONTROL_ACCESS);
4643 root_sd = cli_query_secdesc(cli, fnum, mem_ctx);
4646 for (i=0; i<num_tokens; i++) {
4650 if (share_sd != NULL) {
4651 if (!se_access_check(share_sd, &tokens[i].token,
4652 1, &acc_granted, &status)) {
4653 DEBUG(1, ("Could not check share_sd for "
4659 if (!NT_STATUS_IS_OK(status))
4663 if (root_sd == NULL) {
4664 d_printf(" %s\n", tokens[i].name);
4668 if (!se_access_check(root_sd, &tokens[i].token,
4669 1, &acc_granted, &status)) {
4670 DEBUG(1, ("Could not check root_sd for user %s\n",
4675 if (!NT_STATUS_IS_OK(status))
4678 d_printf(" %s\n", tokens[i].name);
4682 cli_close(cli, fnum);
4694 static void collect_share(const char *name, uint32 m,
4695 const char *comment, void *state)
4697 struct share_list *share_list = (struct share_list *)state;
4699 if (m != STYPE_DISKTREE)
4702 share_list->num_shares += 1;
4703 share_list->shares = SMB_REALLOC_ARRAY(share_list->shares, char *, share_list->num_shares);
4704 if (!share_list->shares) {
4705 share_list->num_shares = 0;
4708 share_list->shares[share_list->num_shares-1] = SMB_STRDUP(name);
4711 static void rpc_share_userlist_usage(void)
4717 * List shares on a remote RPC server, including the security descriptors
4719 * All parameters are provided by the run_rpc_command function, except for
4720 * argc, argv which are passes through.
4722 * @param domain_sid The domain sid acquired from the remote server
4723 * @param cli A cli_state connected to the server.
4724 * @param mem_ctx Talloc context, destoyed on completion of the function.
4725 * @param argc Standard main() style argc
4726 * @param argv Standard main() style argv. Initial components are already
4729 * @return Normal NTSTATUS return.
4732 static NTSTATUS rpc_share_allowedusers_internals(const DOM_SID *domain_sid,
4733 const char *domain_name,
4734 struct cli_state *cli,
4735 struct rpc_pipe_client *pipe_hnd,
4736 TALLOC_CTX *mem_ctx,
4746 struct user_token *tokens = NULL;
4749 struct share_list share_list;
4752 rpc_share_userlist_usage();
4753 return NT_STATUS_UNSUCCESSFUL;
4759 f = fopen(argv[0], "r");
4763 DEBUG(0, ("Could not open userlist: %s\n", strerror(errno)));
4764 return NT_STATUS_UNSUCCESSFUL;
4767 r = get_user_tokens_from_file(f, &num_tokens, &tokens);
4773 DEBUG(0, ("Could not read users from file\n"));
4774 return NT_STATUS_UNSUCCESSFUL;
4777 for (i=0; i<num_tokens; i++)
4778 collect_alias_memberships(&tokens[i].token);
4780 init_enum_hnd(&hnd, 0);
4782 share_list.num_shares = 0;
4783 share_list.shares = NULL;
4785 ret = cli_RNetShareEnum(cli, collect_share, &share_list);
4788 DEBUG(0, ("Error returning browse list: %s\n",
4793 for (i = 0; i < share_list.num_shares; i++) {
4794 char *netname = share_list.shares[i];
4796 if (netname[strlen(netname)-1] == '$')
4799 d_printf("%s\n", netname);
4801 show_userlist(pipe_hnd, mem_ctx, netname,
4802 num_tokens, tokens);
4805 for (i=0; i<num_tokens; i++) {
4806 free_user_token(&tokens[i].token);
4809 SAFE_FREE(share_list.shares);
4811 return NT_STATUS_OK;
4814 static int rpc_share_allowedusers(int argc, const char **argv)
4818 result = run_rpc_command(NULL, PI_SAMR, 0,
4819 rpc_aliaslist_internals,
4824 result = run_rpc_command(NULL, PI_LSARPC, 0,
4830 return run_rpc_command(NULL, PI_SRVSVC, 0,
4831 rpc_share_allowedusers_internals,
4835 int net_usersidlist(int argc, const char **argv)
4838 struct user_token *tokens = NULL;
4842 net_usersidlist_usage(argc, argv);
4846 if (!get_user_tokens(&num_tokens, &tokens)) {
4847 DEBUG(0, ("Could not get the user/sid list\n"));
4851 for (i=0; i<num_tokens; i++) {
4852 dump_user_token(&tokens[i]);
4853 free_user_token(&tokens[i].token);
4860 int net_usersidlist_usage(int argc, const char **argv)
4862 d_printf("net usersidlist\n"
4863 "\tprints out a list of all users the running winbind knows\n"
4864 "\tabout, together with all their SIDs. This is used as\n"
4865 "\tinput to the 'net rpc share allowedusers' command.\n\n");
4867 net_common_flags_usage(argc, argv);
4872 * 'net rpc share' entrypoint.
4873 * @param argc Standard main() style argc
4874 * @param argv Standard main() style argv. Initial components are already
4878 int net_rpc_share(int argc, const char **argv)
4880 struct functable func[] = {
4881 {"add", rpc_share_add},
4882 {"delete", rpc_share_delete},
4883 {"allowedusers", rpc_share_allowedusers},
4884 {"migrate", rpc_share_migrate},
4885 {"list", rpc_share_list},
4890 return run_rpc_command(NULL, PI_SRVSVC, 0,
4891 rpc_share_list_internals,
4894 return net_run_function(argc, argv, func, rpc_share_usage);
4897 static NTSTATUS rpc_sh_share_list(TALLOC_CTX *mem_ctx,
4898 struct rpc_sh_ctx *ctx,
4899 struct rpc_pipe_client *pipe_hnd,
4900 int argc, const char **argv)
4902 return rpc_share_list_internals(ctx->domain_sid, ctx->domain_name,
4903 ctx->cli, pipe_hnd, mem_ctx,
4907 static NTSTATUS rpc_sh_share_add(TALLOC_CTX *mem_ctx,
4908 struct rpc_sh_ctx *ctx,
4909 struct rpc_pipe_client *pipe_hnd,
4910 int argc, const char **argv)
4914 if ((argc < 2) || (argc > 3)) {
4915 d_fprintf(stderr, "usage: %s <share> <path> [comment]\n",
4917 return NT_STATUS_INVALID_PARAMETER;
4920 result = rpccli_srvsvc_net_share_add(
4921 pipe_hnd, mem_ctx, argv[0], STYPE_DISKTREE,
4922 (argc == 3) ? argv[2] : "",
4923 0, 0, 0, argv[1], NULL, 2, NULL);
4925 return werror_to_ntstatus(result);
4928 static NTSTATUS rpc_sh_share_delete(TALLOC_CTX *mem_ctx,
4929 struct rpc_sh_ctx *ctx,
4930 struct rpc_pipe_client *pipe_hnd,
4931 int argc, const char **argv)
4936 d_fprintf(stderr, "usage: %s <share>\n", ctx->whoami);
4937 return NT_STATUS_INVALID_PARAMETER;
4940 result = rpccli_srvsvc_net_share_del(pipe_hnd, mem_ctx, argv[0]);
4941 return werror_to_ntstatus(result);
4944 static NTSTATUS rpc_sh_share_info(TALLOC_CTX *mem_ctx,
4945 struct rpc_sh_ctx *ctx,
4946 struct rpc_pipe_client *pipe_hnd,
4947 int argc, const char **argv)
4949 SRV_SHARE_INFO info;
4950 SRV_SHARE_INFO_2 *info2 = &info.share.info2;
4954 d_fprintf(stderr, "usage: %s <share>\n", ctx->whoami);
4955 return NT_STATUS_INVALID_PARAMETER;
4958 result = rpccli_srvsvc_net_share_get_info(
4959 pipe_hnd, mem_ctx, argv[0], 2, &info);
4960 if (!W_ERROR_IS_OK(result)) {
4964 d_printf("Name: %s\n",
4965 rpcstr_pull_unistr2_talloc(mem_ctx,
4966 &info2->info_2_str.uni_netname));
4967 d_printf("Comment: %s\n",
4968 rpcstr_pull_unistr2_talloc(mem_ctx,
4969 &info2->info_2_str.uni_remark));
4971 d_printf("Path: %s\n",
4972 rpcstr_pull_unistr2_talloc(mem_ctx,
4973 &info2->info_2_str.uni_path));
4974 d_printf("Password: %s\n",
4975 rpcstr_pull_unistr2_talloc(mem_ctx,
4976 &info2->info_2_str.uni_passwd));
4979 return werror_to_ntstatus(result);
4982 struct rpc_sh_cmd *net_rpc_share_cmds(TALLOC_CTX *mem_ctx,
4983 struct rpc_sh_ctx *ctx)
4985 static struct rpc_sh_cmd cmds[] = {
4987 { "list", NULL, PI_SRVSVC, rpc_sh_share_list,
4988 "List available shares" },
4990 { "add", NULL, PI_SRVSVC, rpc_sh_share_add,
4993 { "delete", NULL, PI_SRVSVC, rpc_sh_share_delete,
4996 { "info", NULL, PI_SRVSVC, rpc_sh_share_info,
4997 "Get information about a share" },
4999 { NULL, NULL, 0, NULL, NULL }
5005 /****************************************************************************/
5007 static int rpc_file_usage(int argc, const char **argv)
5009 return net_help_file(argc, argv);
5013 * Close a file on a remote RPC server
5015 * All parameters are provided by the run_rpc_command function, except for
5016 * argc, argv which are passes through.
5018 * @param domain_sid The domain sid acquired from the remote server
5019 * @param cli A cli_state connected to the server.
5020 * @param mem_ctx Talloc context, destoyed on completion of the function.
5021 * @param argc Standard main() style argc
5022 * @param argv Standard main() style argv. Initial components are already
5025 * @return Normal NTSTATUS return.
5027 static NTSTATUS rpc_file_close_internals(const DOM_SID *domain_sid,
5028 const char *domain_name,
5029 struct cli_state *cli,
5030 struct rpc_pipe_client *pipe_hnd,
5031 TALLOC_CTX *mem_ctx,
5035 return rpccli_srvsvc_NetFileClose(pipe_hnd, mem_ctx,
5036 pipe_hnd->cli->desthost,
5037 atoi(argv[0]), NULL);
5041 * Close a file on a remote RPC server
5043 * @param argc Standard main() style argc
5044 * @param argv Standard main() style argv. Initial components are already
5047 * @return A shell status integer (0 for success)
5049 static int rpc_file_close(int argc, const char **argv)
5052 DEBUG(1, ("No fileid given on close\n"));
5053 return(rpc_file_usage(argc, argv));
5056 return run_rpc_command(NULL, PI_SRVSVC, 0,
5057 rpc_file_close_internals,
5062 * Formatted print of open file info
5064 * @param info3 FILE_INFO_3 contents
5065 * @param str3 strings for FILE_INFO_3
5068 static void display_file_info_3( FILE_INFO_3 *info3 )
5070 fstring user = "", path = "";
5072 rpcstr_pull_unistr2_fstring(user, info3->user);
5073 rpcstr_pull_unistr2_fstring(path, info3->path);
5075 d_printf("%-7.1d %-20.20s 0x%-4.2x %-6.1d %s\n",
5076 info3->id, user, info3->perms, info3->num_locks, path);
5080 * List open files on a remote RPC server
5082 * All parameters are provided by the run_rpc_command function, except for
5083 * argc, argv which are passes through.
5085 * @param domain_sid The domain sid acquired from the remote server
5086 * @param cli A cli_state connected to the server.
5087 * @param mem_ctx Talloc context, destoyed on completion of the function.
5088 * @param argc Standard main() style argc
5089 * @param argv Standard main() style argv. Initial components are already
5092 * @return Normal NTSTATUS return.
5095 static NTSTATUS rpc_file_list_internals(const DOM_SID *domain_sid,
5096 const char *domain_name,
5097 struct cli_state *cli,
5098 struct rpc_pipe_client *pipe_hnd,
5099 TALLOC_CTX *mem_ctx,
5103 SRV_FILE_INFO_CTR ctr;
5106 uint32 preferred_len = 0xffffffff, i;
5107 const char *username=NULL;
5109 init_enum_hnd(&hnd, 0);
5111 /* if argc > 0, must be user command */
5113 username = smb_xstrdup(argv[0]);
5115 result = rpccli_srvsvc_net_file_enum(pipe_hnd,
5116 mem_ctx, 3, username, &ctr, preferred_len, &hnd);
5118 if (!W_ERROR_IS_OK(result))
5121 /* Display results */
5124 "\nEnumerating open files on remote server:\n\n"\
5125 "\nFileId Opened by Perms Locks Path"\
5126 "\n------ --------- ----- ----- ---- \n");
5127 for (i = 0; i < ctr.num_entries; i++)
5128 display_file_info_3(&ctr.file.info3[i]);
5130 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
5134 * List files for a user on a remote RPC server
5136 * @param argc Standard main() style argc
5137 * @param argv Standard main() style argv. Initial components are already
5140 * @return A shell status integer (0 for success)
5143 static int rpc_file_user(int argc, const char **argv)
5146 DEBUG(1, ("No username given\n"));
5147 return(rpc_file_usage(argc, argv));
5150 return run_rpc_command(NULL, PI_SRVSVC, 0,
5151 rpc_file_list_internals,
5156 * 'net rpc file' entrypoint.
5157 * @param argc Standard main() style argc
5158 * @param argv Standard main() style argv. Initial components are already
5162 int net_rpc_file(int argc, const char **argv)
5164 struct functable func[] = {
5165 {"close", rpc_file_close},
5166 {"user", rpc_file_user},
5168 {"info", rpc_file_info},
5174 return run_rpc_command(NULL, PI_SRVSVC, 0,
5175 rpc_file_list_internals,
5178 return net_run_function(argc, argv, func, rpc_file_usage);
5182 * ABORT the shutdown of a remote RPC Server over, initshutdown pipe
5184 * All parameters are provided by the run_rpc_command function, except for
5185 * argc, argv which are passed through.
5187 * @param domain_sid The domain sid aquired from the remote server
5188 * @param cli A cli_state connected to the server.
5189 * @param mem_ctx Talloc context, destoyed on compleation of the function.
5190 * @param argc Standard main() style argc
5191 * @param argv Standard main() style argv. Initial components are already
5194 * @return Normal NTSTATUS return.
5197 static NTSTATUS rpc_shutdown_abort_internals(const DOM_SID *domain_sid,
5198 const char *domain_name,
5199 struct cli_state *cli,
5200 struct rpc_pipe_client *pipe_hnd,
5201 TALLOC_CTX *mem_ctx,
5205 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
5207 result = rpccli_initshutdown_Abort(pipe_hnd, mem_ctx, NULL, NULL);
5209 if (NT_STATUS_IS_OK(result)) {
5210 d_printf("\nShutdown successfully aborted\n");
5211 DEBUG(5,("cmd_shutdown_abort: query succeeded\n"));
5213 DEBUG(5,("cmd_shutdown_abort: query failed\n"));
5219 * ABORT the shutdown of a remote RPC Server, over winreg pipe
5221 * All parameters are provided by the run_rpc_command function, except for
5222 * argc, argv which are passed through.
5224 * @param domain_sid The domain sid aquired from the remote server
5225 * @param cli A cli_state connected to the server.
5226 * @param mem_ctx Talloc context, destoyed on compleation of the function.
5227 * @param argc Standard main() style argc
5228 * @param argv Standard main() style argv. Initial components are already
5231 * @return Normal NTSTATUS return.
5234 static NTSTATUS rpc_reg_shutdown_abort_internals(const DOM_SID *domain_sid,
5235 const char *domain_name,
5236 struct cli_state *cli,
5237 struct rpc_pipe_client *pipe_hnd,
5238 TALLOC_CTX *mem_ctx,
5242 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
5244 result = rpccli_winreg_AbortSystemShutdown(pipe_hnd, mem_ctx, NULL, NULL);
5246 if (NT_STATUS_IS_OK(result)) {
5247 d_printf("\nShutdown successfully aborted\n");
5248 DEBUG(5,("cmd_reg_abort_shutdown: query succeeded\n"));
5250 DEBUG(5,("cmd_reg_abort_shutdown: query failed\n"));
5256 * ABORT the Shut down of a remote RPC server
5258 * @param argc Standard main() style argc
5259 * @param argv Standard main() style argv. Initial components are already
5262 * @return A shell status integer (0 for success)
5265 static int rpc_shutdown_abort(int argc, const char **argv)
5267 int rc = run_rpc_command(NULL, PI_INITSHUTDOWN, 0,
5268 rpc_shutdown_abort_internals,
5274 DEBUG(1, ("initshutdown pipe didn't work, trying winreg pipe\n"));
5276 return run_rpc_command(NULL, PI_WINREG, 0,
5277 rpc_reg_shutdown_abort_internals,
5282 * Shut down a remote RPC Server via initshutdown pipe
5284 * All parameters are provided by the run_rpc_command function, except for
5285 * argc, argv which are passes through.
5287 * @param domain_sid The domain sid aquired from the remote server
5288 * @param cli A cli_state connected to the server.
5289 * @param mem_ctx Talloc context, destoyed on compleation of the function.
5290 * @param argc Standard main() style argc
5291 * @param argc Standard main() style argv. Initial components are already
5294 * @return Normal NTSTATUS return.
5297 NTSTATUS rpc_init_shutdown_internals(const DOM_SID *domain_sid,
5298 const char *domain_name,
5299 struct cli_state *cli,
5300 struct rpc_pipe_client *pipe_hnd,
5301 TALLOC_CTX *mem_ctx,
5305 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
5306 const char *msg = "This machine will be shutdown shortly";
5307 uint32 timeout = 20;
5308 struct initshutdown_String msg_string;
5309 struct initshutdown_String_sub s;
5315 timeout = opt_timeout;
5319 msg_string.name = &s;
5321 /* create an entry */
5322 result = rpccli_initshutdown_Init(pipe_hnd, mem_ctx, NULL,
5323 &msg_string, timeout, opt_force, opt_reboot, NULL);
5325 if (NT_STATUS_IS_OK(result)) {
5326 d_printf("\nShutdown of remote machine succeeded\n");
5327 DEBUG(5,("Shutdown of remote machine succeeded\n"));
5329 DEBUG(1,("Shutdown of remote machine failed!\n"));
5335 * Shut down a remote RPC Server via winreg pipe
5337 * All parameters are provided by the run_rpc_command function, except for
5338 * argc, argv which are passes through.
5340 * @param domain_sid The domain sid aquired from the remote server
5341 * @param cli A cli_state connected to the server.
5342 * @param mem_ctx Talloc context, destoyed on compleation of the function.
5343 * @param argc Standard main() style argc
5344 * @param argc Standard main() style argv. Initial components are already
5347 * @return Normal NTSTATUS return.
5350 NTSTATUS rpc_reg_shutdown_internals(const DOM_SID *domain_sid,
5351 const char *domain_name,
5352 struct cli_state *cli,
5353 struct rpc_pipe_client *pipe_hnd,
5354 TALLOC_CTX *mem_ctx,
5358 const char *msg = "This machine will be shutdown shortly";
5359 uint32 timeout = 20;
5360 struct initshutdown_String msg_string;
5361 struct initshutdown_String_sub s;
5369 msg_string.name = &s;
5372 timeout = opt_timeout;
5375 /* create an entry */
5376 result = rpccli_winreg_InitiateSystemShutdown(pipe_hnd, mem_ctx, NULL,
5377 &msg_string, timeout, opt_force, opt_reboot, &werr);
5379 if (NT_STATUS_IS_OK(result)) {
5380 d_printf("\nShutdown of remote machine succeeded\n");
5382 d_fprintf(stderr, "\nShutdown of remote machine failed\n");
5383 if ( W_ERROR_EQUAL(werr, WERR_MACHINE_LOCKED) )
5384 d_fprintf(stderr, "\nMachine locked, use -f switch to force\n");
5386 d_fprintf(stderr, "\nresult was: %s\n", dos_errstr(werr));
5393 * Shut down a remote RPC server
5395 * @param argc Standard main() style argc
5396 * @param argc Standard main() style argv. Initial components are already
5399 * @return A shell status integer (0 for success)
5402 static int rpc_shutdown(int argc, const char **argv)
5404 int rc = run_rpc_command(NULL, PI_INITSHUTDOWN, 0,
5405 rpc_init_shutdown_internals,
5409 DEBUG(1, ("initshutdown pipe failed, trying winreg pipe\n"));
5410 rc = run_rpc_command(NULL, PI_WINREG, 0,
5411 rpc_reg_shutdown_internals, argc, argv);
5417 /***************************************************************************
5418 NT Domain trusts code (i.e. 'net rpc trustdom' functionality)
5420 ***************************************************************************/
5423 * Add interdomain trust account to the RPC server.
5424 * All parameters (except for argc and argv) are passed by run_rpc_command
5427 * @param domain_sid The domain sid acquired from the server
5428 * @param cli A cli_state connected to the server.
5429 * @param mem_ctx Talloc context, destoyed on completion of the function.
5430 * @param argc Standard main() style argc
5431 * @param argc Standard main() style argv. Initial components are already
5434 * @return normal NTSTATUS return code
5437 static NTSTATUS rpc_trustdom_add_internals(const DOM_SID *domain_sid,
5438 const char *domain_name,
5439 struct cli_state *cli,
5440 struct rpc_pipe_client *pipe_hnd,
5441 TALLOC_CTX *mem_ctx,
5445 POLICY_HND connect_pol, domain_pol, user_pol;
5446 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
5449 uint32 acct_flags=0;
5453 d_printf("Usage: net rpc trustdom add <domain_name> <pw>\n");
5454 return NT_STATUS_INVALID_PARAMETER;
5458 * Make valid trusting domain account (ie. uppercased and with '$' appended)
5461 if (asprintf(&acct_name, "%s$", argv[0]) < 0) {
5462 return NT_STATUS_NO_MEMORY;
5465 strupper_m(acct_name);
5467 /* Get samr policy handle */
5468 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
5470 if (!NT_STATUS_IS_OK(result)) {
5474 /* Get domain policy handle */
5475 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
5477 MAXIMUM_ALLOWED_ACCESS,
5478 CONST_DISCARD(struct dom_sid2 *, domain_sid),
5480 if (!NT_STATUS_IS_OK(result)) {
5484 /* Create trusting domain's account */
5485 acb_info = ACB_NORMAL;
5486 acct_flags = SEC_GENERIC_READ | SEC_GENERIC_WRITE | SEC_GENERIC_EXECUTE |
5487 SEC_STD_WRITE_DAC | SEC_STD_DELETE |
5488 SAMR_USER_ACCESS_SET_PASSWORD |
5489 SAMR_USER_ACCESS_GET_ATTRIBUTES |
5490 SAMR_USER_ACCESS_SET_ATTRIBUTES;
5492 result = rpccli_samr_create_dom_user(pipe_hnd, mem_ctx, &domain_pol,
5493 acct_name, acb_info, acct_flags,
5494 &user_pol, &user_rid);
5495 if (!NT_STATUS_IS_OK(result)) {
5500 SAM_USERINFO_CTR ctr;
5501 SAM_USER_INFO_23 p23;
5507 encode_pw_buffer(pwbuf, argv[1], STR_UNICODE);
5511 ZERO_STRUCT(notime);
5515 memset(hrs.hours, 0xFF, sizeof(hrs.hours));
5516 acb_info = ACB_DOMTRUST;
5518 init_sam_user_info23A(&p23, ¬ime, ¬ime, ¬ime,
5519 ¬ime, ¬ime, ¬ime,
5520 nostr, nostr, nostr, nostr, nostr,
5521 nostr, nostr, nostr, nostr, nostr,
5522 0, 0, acb_info, ACCT_FLAGS, 168, &hrs,
5523 0, 0, (char *)pwbuf);
5524 ctr.switch_value = 23;
5525 ctr.info.id23 = &p23;
5526 p23.passmustchange = 0;
5528 result = rpccli_samr_set_userinfo(pipe_hnd, mem_ctx, &user_pol, 23,
5529 &cli->user_session_key, &ctr);
5531 if (!NT_STATUS_IS_OK(result)) {
5532 DEBUG(0,("Could not set trust account password: %s\n",
5533 nt_errstr(result)));
5539 SAFE_FREE(acct_name);
5544 * Create interdomain trust account for a remote domain.
5546 * @param argc standard argc
5547 * @param argv standard argv without initial components
5549 * @return Integer status (0 means success)
5552 static int rpc_trustdom_add(int argc, const char **argv)
5555 return run_rpc_command(NULL, PI_SAMR, 0, rpc_trustdom_add_internals,
5558 d_printf("Usage: net rpc trustdom add <domain>\n");
5565 * Remove interdomain trust account from the RPC server.
5566 * All parameters (except for argc and argv) are passed by run_rpc_command
5569 * @param domain_sid The domain sid acquired from the server
5570 * @param cli A cli_state connected to the server.
5571 * @param mem_ctx Talloc context, destoyed on completion of the function.
5572 * @param argc Standard main() style argc
5573 * @param argc Standard main() style argv. Initial components are already
5576 * @return normal NTSTATUS return code
5579 static NTSTATUS rpc_trustdom_del_internals(const DOM_SID *domain_sid,
5580 const char *domain_name,
5581 struct cli_state *cli,
5582 struct rpc_pipe_client *pipe_hnd,
5583 TALLOC_CTX *mem_ctx,
5587 POLICY_HND connect_pol, domain_pol, user_pol;
5588 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
5591 DOM_SID trust_acct_sid;
5592 uint32 *user_rids, num_rids, *name_types;
5593 uint32 flags = 0x000003e8; /* Unknown */
5596 d_printf("Usage: net rpc trustdom del <domain_name>\n");
5597 return NT_STATUS_INVALID_PARAMETER;
5601 * Make valid trusting domain account (ie. uppercased and with '$' appended)
5603 acct_name = talloc_asprintf(mem_ctx, "%s$", argv[0]);
5605 if (acct_name == NULL)
5606 return NT_STATUS_NO_MEMORY;
5608 strupper_m(acct_name);
5610 if ((names = TALLOC_ARRAY(mem_ctx, const char *, 1)) == NULL) {
5611 return NT_STATUS_NO_MEMORY;
5613 names[0] = acct_name;
5616 /* Get samr policy handle */
5617 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
5619 if (!NT_STATUS_IS_OK(result)) {
5623 /* Get domain policy handle */
5624 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
5626 MAXIMUM_ALLOWED_ACCESS,
5627 CONST_DISCARD(struct dom_sid2 *, domain_sid),
5629 if (!NT_STATUS_IS_OK(result)) {
5633 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, flags, 1,
5635 &user_rids, &name_types);
5637 if (!NT_STATUS_IS_OK(result)) {
5641 result = rpccli_samr_OpenUser(pipe_hnd, mem_ctx,
5643 MAXIMUM_ALLOWED_ACCESS,
5647 if (!NT_STATUS_IS_OK(result)) {
5651 /* append the rid to the domain sid */
5652 sid_copy(&trust_acct_sid, domain_sid);
5653 if (!sid_append_rid(&trust_acct_sid, user_rids[0])) {
5657 /* remove the sid */
5659 result = rpccli_samr_remove_sid_foreign_domain(pipe_hnd, mem_ctx, &user_pol,
5662 if (!NT_STATUS_IS_OK(result)) {
5668 result = rpccli_samr_DeleteUser(pipe_hnd, mem_ctx,
5671 if (!NT_STATUS_IS_OK(result)) {
5675 if (!NT_STATUS_IS_OK(result)) {
5676 DEBUG(0,("Could not set trust account password: %s\n",
5677 nt_errstr(result)));
5686 * Delete interdomain trust account for a remote domain.
5688 * @param argc standard argc
5689 * @param argv standard argv without initial components
5691 * @return Integer status (0 means success)
5694 static int rpc_trustdom_del(int argc, const char **argv)
5697 return run_rpc_command(NULL, PI_SAMR, 0, rpc_trustdom_del_internals,
5700 d_printf("Usage: net rpc trustdom del <domain>\n");
5707 * Establish trust relationship to a trusting domain.
5708 * Interdomain account must already be created on remote PDC.
5710 * @param argc standard argc
5711 * @param argv standard argv without initial components
5713 * @return Integer status (0 means success)
5716 static int rpc_trustdom_establish(int argc, const char **argv)
5718 struct cli_state *cli = NULL;
5719 struct sockaddr_storage server_ss;
5720 struct rpc_pipe_client *pipe_hnd = NULL;
5721 POLICY_HND connect_hnd;
5722 TALLOC_CTX *mem_ctx;
5724 DOM_SID *domain_sid;
5727 const char* domain_name_pol;
5733 * Connect to \\server\ipc$ as 'our domain' account with password
5737 d_printf("Usage: net rpc trustdom establish <domain_name>\n");
5741 domain_name = smb_xstrdup(argv[0]);
5742 strupper_m(domain_name);
5744 /* account name used at first is our domain's name with '$' */
5745 asprintf(&acct_name, "%s$", lp_workgroup());
5746 strupper_m(acct_name);
5749 * opt_workgroup will be used by connection functions further,
5750 * hence it should be set to remote domain name instead of ours
5752 if (opt_workgroup) {
5753 opt_workgroup = smb_xstrdup(domain_name);
5756 opt_user_name = acct_name;
5758 /* find the domain controller */
5759 if (!net_find_pdc(&server_ss, pdc_name, domain_name)) {
5760 DEBUG(0, ("Couldn't find domain controller for domain %s\n", domain_name));
5764 /* connect to ipc$ as username/password */
5765 nt_status = connect_to_ipc(&cli, &server_ss, pdc_name);
5766 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT)) {
5768 /* Is it trusting domain account for sure ? */
5769 DEBUG(0, ("Couldn't verify trusting domain account. Error was %s\n",
5770 nt_errstr(nt_status)));
5774 /* store who we connected to */
5776 saf_store( domain_name, pdc_name );
5779 * Connect to \\server\ipc$ again (this time anonymously)
5782 nt_status = connect_to_ipc_anonymous(&cli, &server_ss, (char*)pdc_name);
5784 if (NT_STATUS_IS_ERR(nt_status)) {
5785 DEBUG(0, ("Couldn't connect to domain %s controller. Error was %s.\n",
5786 domain_name, nt_errstr(nt_status)));
5791 * Use NetServerEnum2 to make sure we're talking to a proper server
5794 if (!cli_get_pdc_name(cli, domain_name, &dc_name)) {
5795 DEBUG(0, ("NetServerEnum2 error: Couldn't find primary domain controller\
5796 for domain %s\n", domain_name));
5802 if (!(mem_ctx = talloc_init("establishing trust relationship to "
5803 "domain %s", domain_name))) {
5804 DEBUG(0, ("talloc_init() failed\n"));
5810 * Call LsaOpenPolicy and LsaQueryInfo
5813 pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_LSARPC, &nt_status);
5815 DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n", nt_errstr(nt_status) ));
5817 talloc_destroy(mem_ctx);
5821 nt_status = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, True, SEC_RIGHTS_QUERY_VALUE,
5823 if (NT_STATUS_IS_ERR(nt_status)) {
5824 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
5825 nt_errstr(nt_status)));
5827 talloc_destroy(mem_ctx);
5831 /* Querying info level 5 */
5833 nt_status = rpccli_lsa_query_info_policy(pipe_hnd, mem_ctx, &connect_hnd,
5835 &domain_name_pol, &domain_sid);
5836 if (NT_STATUS_IS_ERR(nt_status)) {
5837 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
5838 nt_errstr(nt_status)));
5840 talloc_destroy(mem_ctx);
5844 /* There should be actually query info level 3 (following nt serv behaviour),
5845 but I still don't know if it's _really_ necessary */
5848 * Store the password in secrets db
5851 if (!pdb_set_trusteddom_pw(domain_name, opt_password, domain_sid)) {
5852 DEBUG(0, ("Storing password for trusted domain failed.\n"));
5854 talloc_destroy(mem_ctx);
5859 * Close the pipes and clean up
5862 nt_status = rpccli_lsa_Close(pipe_hnd, mem_ctx, &connect_hnd);
5863 if (NT_STATUS_IS_ERR(nt_status)) {
5864 DEBUG(0, ("Couldn't close LSA pipe. Error was %s\n",
5865 nt_errstr(nt_status)));
5867 talloc_destroy(mem_ctx);
5873 talloc_destroy(mem_ctx);
5875 d_printf("Trust to domain %s established\n", domain_name);
5880 * Revoke trust relationship to the remote domain
5882 * @param argc standard argc
5883 * @param argv standard argv without initial components
5885 * @return Integer status (0 means success)
5888 static int rpc_trustdom_revoke(int argc, const char **argv)
5893 if (argc < 1) return -1;
5895 /* generate upper cased domain name */
5896 domain_name = smb_xstrdup(argv[0]);
5897 strupper_m(domain_name);
5899 /* delete password of the trust */
5900 if (!pdb_del_trusteddom_pw(domain_name)) {
5901 DEBUG(0, ("Failed to revoke relationship to the trusted domain %s\n",
5908 SAFE_FREE(domain_name);
5913 * Usage for 'net rpc trustdom' command
5915 * @param argc standard argc
5916 * @param argv standard argv without inital components
5918 * @return Integer status returned to shell
5921 static int rpc_trustdom_usage(int argc, const char **argv)
5923 d_printf(" net rpc trustdom add \t\t add trusting domain's account\n");
5924 d_printf(" net rpc trustdom del \t\t delete trusting domain's account\n");
5925 d_printf(" net rpc trustdom establish \t establish relationship to trusted domain\n");
5926 d_printf(" net rpc trustdom revoke \t abandon relationship to trusted domain\n");
5927 d_printf(" net rpc trustdom list \t show current interdomain trust relationships\n");
5928 d_printf(" net rpc trustdom vampire \t vampire interdomain trust relationships from remote server\n");
5933 static NTSTATUS rpc_query_domain_sid(const DOM_SID *domain_sid,
5934 const char *domain_name,
5935 struct cli_state *cli,
5936 struct rpc_pipe_client *pipe_hnd,
5937 TALLOC_CTX *mem_ctx,
5942 sid_to_fstring(str_sid, domain_sid);
5943 d_printf("%s\n", str_sid);
5944 return NT_STATUS_OK;
5947 static void print_trusted_domain(DOM_SID *dom_sid, const char *trusted_dom_name)
5949 fstring ascii_sid, padding;
5950 int pad_len, col_len = 20;
5952 /* convert sid into ascii string */
5953 sid_to_fstring(ascii_sid, dom_sid);
5955 /* calculate padding space for d_printf to look nicer */
5956 pad_len = col_len - strlen(trusted_dom_name);
5957 padding[pad_len] = 0;
5958 do padding[--pad_len] = ' '; while (pad_len);
5960 d_printf("%s%s%s\n", trusted_dom_name, padding, ascii_sid);
5963 static NTSTATUS vampire_trusted_domain(struct rpc_pipe_client *pipe_hnd,
5964 TALLOC_CTX *mem_ctx,
5967 const char *trusted_dom_name)
5970 union lsa_TrustedDomainInfo info;
5971 char *cleartextpwd = NULL;
5974 nt_status = rpccli_lsa_QueryTrustedDomainInfoBySid(pipe_hnd, mem_ctx,
5977 LSA_TRUSTED_DOMAIN_INFO_PASSWORD,
5979 if (NT_STATUS_IS_ERR(nt_status)) {
5980 DEBUG(0,("Could not query trusted domain info. Error was %s\n",
5981 nt_errstr(nt_status)));
5985 data = data_blob(NULL, info.password.password->length);
5988 info.password.password->data,
5989 info.password.password->length);
5990 data.length = info.password.password->length;
5992 cleartextpwd = decrypt_trustdom_secret(pipe_hnd->cli->pwd.password,
5995 if (cleartextpwd == NULL) {
5996 DEBUG(0,("retrieved NULL password\n"));
5997 nt_status = NT_STATUS_UNSUCCESSFUL;
6001 if (!pdb_set_trusteddom_pw(trusted_dom_name, cleartextpwd, &dom_sid)) {
6002 DEBUG(0, ("Storing password for trusted domain failed.\n"));
6003 nt_status = NT_STATUS_UNSUCCESSFUL;
6007 #ifdef DEBUG_PASSWORD
6008 DEBUG(100,("sucessfully vampired trusted domain [%s], sid: [%s], "
6009 "password: [%s]\n", trusted_dom_name,
6010 sid_string_dbg(&dom_sid), cleartextpwd));
6014 SAFE_FREE(cleartextpwd);
6015 data_blob_free(&data);
6020 static int rpc_trustdom_vampire(int argc, const char **argv)
6022 /* common variables */
6023 TALLOC_CTX* mem_ctx;
6024 struct cli_state *cli = NULL;
6025 struct rpc_pipe_client *pipe_hnd = NULL;
6027 const char *domain_name = NULL;
6028 DOM_SID *queried_dom_sid;
6029 POLICY_HND connect_hnd;
6031 /* trusted domains listing variables */
6032 unsigned int num_domains, enum_ctx = 0;
6034 DOM_SID *domain_sids;
6035 char **trusted_dom_names;
6040 * Listing trusted domains (stored in secrets.tdb, if local)
6043 mem_ctx = talloc_init("trust relationships vampire");
6046 * set domain and pdc name to local samba server (default)
6047 * or to remote one given in command line
6050 if (StrCaseCmp(opt_workgroup, lp_workgroup())) {
6051 domain_name = opt_workgroup;
6052 opt_target_workgroup = opt_workgroup;
6054 fstrcpy(pdc_name, global_myname());
6055 domain_name = talloc_strdup(mem_ctx, lp_workgroup());
6056 opt_target_workgroup = domain_name;
6059 /* open \PIPE\lsarpc and open policy handle */
6060 nt_status = net_make_ipc_connection(NET_FLAGS_PDC, &cli);
6061 if (!NT_STATUS_IS_OK(nt_status)) {
6062 DEBUG(0, ("Couldn't connect to domain controller: %s\n",
6063 nt_errstr(nt_status)));
6064 talloc_destroy(mem_ctx);
6068 pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_LSARPC, &nt_status);
6070 DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n",
6071 nt_errstr(nt_status) ));
6073 talloc_destroy(mem_ctx);
6077 nt_status = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, False, SEC_RIGHTS_QUERY_VALUE,
6079 if (NT_STATUS_IS_ERR(nt_status)) {
6080 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
6081 nt_errstr(nt_status)));
6083 talloc_destroy(mem_ctx);
6087 /* query info level 5 to obtain sid of a domain being queried */
6088 nt_status = rpccli_lsa_query_info_policy(
6089 pipe_hnd, mem_ctx, &connect_hnd, 5 /* info level */,
6090 &dummy, &queried_dom_sid);
6092 if (NT_STATUS_IS_ERR(nt_status)) {
6093 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
6094 nt_errstr(nt_status)));
6096 talloc_destroy(mem_ctx);
6101 * Keep calling LsaEnumTrustdom over opened pipe until
6102 * the end of enumeration is reached
6105 d_printf("Vampire trusted domains:\n\n");
6108 nt_status = rpccli_lsa_enum_trust_dom(pipe_hnd, mem_ctx, &connect_hnd, &enum_ctx,
6110 &trusted_dom_names, &domain_sids);
6112 if (NT_STATUS_IS_ERR(nt_status)) {
6113 DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
6114 nt_errstr(nt_status)));
6116 talloc_destroy(mem_ctx);
6120 for (i = 0; i < num_domains; i++) {
6122 print_trusted_domain(&(domain_sids[i]), trusted_dom_names[i]);
6124 nt_status = vampire_trusted_domain(pipe_hnd, mem_ctx, &connect_hnd,
6125 domain_sids[i], trusted_dom_names[i]);
6126 if (!NT_STATUS_IS_OK(nt_status)) {
6128 talloc_destroy(mem_ctx);
6134 * in case of no trusted domains say something rather
6135 * than just display blank line
6137 if (!num_domains) d_printf("none\n");
6139 } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
6141 /* close this connection before doing next one */
6142 nt_status = rpccli_lsa_Close(pipe_hnd, mem_ctx, &connect_hnd);
6143 if (NT_STATUS_IS_ERR(nt_status)) {
6144 DEBUG(0, ("Couldn't properly close lsa policy handle. Error was %s\n",
6145 nt_errstr(nt_status)));
6147 talloc_destroy(mem_ctx);
6151 /* close lsarpc pipe and connection to IPC$ */
6154 talloc_destroy(mem_ctx);
6158 static int rpc_trustdom_list(int argc, const char **argv)
6160 /* common variables */
6161 TALLOC_CTX* mem_ctx;
6162 struct cli_state *cli = NULL, *remote_cli = NULL;
6163 struct rpc_pipe_client *pipe_hnd = NULL;
6165 const char *domain_name = NULL;
6166 DOM_SID *queried_dom_sid;
6168 int ascii_dom_name_len;
6169 POLICY_HND connect_hnd;
6171 /* trusted domains listing variables */
6172 unsigned int num_domains, enum_ctx = 0;
6173 int i, pad_len, col_len = 20;
6174 DOM_SID *domain_sids;
6175 char **trusted_dom_names;
6179 /* trusting domains listing variables */
6180 POLICY_HND domain_hnd;
6181 char **trusting_dom_names;
6182 uint32 *trusting_dom_rids;
6185 * Listing trusted domains (stored in secrets.tdb, if local)
6188 mem_ctx = talloc_init("trust relationships listing");
6191 * set domain and pdc name to local samba server (default)
6192 * or to remote one given in command line
6195 if (StrCaseCmp(opt_workgroup, lp_workgroup())) {
6196 domain_name = opt_workgroup;
6197 opt_target_workgroup = opt_workgroup;
6199 fstrcpy(pdc_name, global_myname());
6200 domain_name = talloc_strdup(mem_ctx, lp_workgroup());
6201 opt_target_workgroup = domain_name;
6204 /* open \PIPE\lsarpc and open policy handle */
6205 nt_status = net_make_ipc_connection(NET_FLAGS_PDC, &cli);
6206 if (!NT_STATUS_IS_OK(nt_status)) {
6207 DEBUG(0, ("Couldn't connect to domain controller: %s\n",
6208 nt_errstr(nt_status)));
6209 talloc_destroy(mem_ctx);
6213 pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_LSARPC, &nt_status);
6215 DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n",
6216 nt_errstr(nt_status) ));
6218 talloc_destroy(mem_ctx);
6222 nt_status = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, False, SEC_RIGHTS_QUERY_VALUE,
6224 if (NT_STATUS_IS_ERR(nt_status)) {
6225 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
6226 nt_errstr(nt_status)));
6228 talloc_destroy(mem_ctx);
6232 /* query info level 5 to obtain sid of a domain being queried */
6233 nt_status = rpccli_lsa_query_info_policy(
6234 pipe_hnd, mem_ctx, &connect_hnd, 5 /* info level */,
6235 &dummy, &queried_dom_sid);
6237 if (NT_STATUS_IS_ERR(nt_status)) {
6238 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
6239 nt_errstr(nt_status)));
6241 talloc_destroy(mem_ctx);
6246 * Keep calling LsaEnumTrustdom over opened pipe until
6247 * the end of enumeration is reached
6250 d_printf("Trusted domains list:\n\n");
6253 nt_status = rpccli_lsa_enum_trust_dom(pipe_hnd, mem_ctx, &connect_hnd, &enum_ctx,
6255 &trusted_dom_names, &domain_sids);
6257 if (NT_STATUS_IS_ERR(nt_status)) {
6258 DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
6259 nt_errstr(nt_status)));
6261 talloc_destroy(mem_ctx);
6265 for (i = 0; i < num_domains; i++) {
6266 print_trusted_domain(&(domain_sids[i]), trusted_dom_names[i]);
6270 * in case of no trusted domains say something rather
6271 * than just display blank line
6273 if (!num_domains) d_printf("none\n");
6275 } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
6277 /* close this connection before doing next one */
6278 nt_status = rpccli_lsa_Close(pipe_hnd, mem_ctx, &connect_hnd);
6279 if (NT_STATUS_IS_ERR(nt_status)) {
6280 DEBUG(0, ("Couldn't properly close lsa policy handle. Error was %s\n",
6281 nt_errstr(nt_status)));
6283 talloc_destroy(mem_ctx);
6287 cli_rpc_pipe_close(pipe_hnd);
6290 * Listing trusting domains (stored in passdb backend, if local)
6293 d_printf("\nTrusting domains list:\n\n");
6296 * Open \PIPE\samr and get needed policy handles
6298 pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SAMR, &nt_status);
6300 DEBUG(0, ("Could not initialise samr pipe. Error was %s\n", nt_errstr(nt_status)));
6302 talloc_destroy(mem_ctx);
6307 nt_status = rpccli_samr_connect(pipe_hnd, mem_ctx, SA_RIGHT_SAM_OPEN_DOMAIN,
6309 if (!NT_STATUS_IS_OK(nt_status)) {
6310 DEBUG(0, ("Couldn't open SAMR policy handle. Error was %s\n",
6311 nt_errstr(nt_status)));
6313 talloc_destroy(mem_ctx);
6317 /* SamrOpenDomain - we have to open domain policy handle in order to be
6318 able to enumerate accounts*/
6319 nt_status = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
6321 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
6324 if (!NT_STATUS_IS_OK(nt_status)) {
6325 DEBUG(0, ("Couldn't open domain object. Error was %s\n",
6326 nt_errstr(nt_status)));
6328 talloc_destroy(mem_ctx);
6333 * perform actual enumeration
6336 enum_ctx = 0; /* reset enumeration context from last enumeration */
6339 nt_status = rpccli_samr_enum_dom_users(pipe_hnd, mem_ctx, &domain_hnd,
6340 &enum_ctx, ACB_DOMTRUST, 0xffff,
6341 &trusting_dom_names, &trusting_dom_rids,
6343 if (NT_STATUS_IS_ERR(nt_status)) {
6344 DEBUG(0, ("Couldn't enumerate accounts. Error was: %s\n",
6345 nt_errstr(nt_status)));
6347 talloc_destroy(mem_ctx);
6351 for (i = 0; i < num_domains; i++) {
6354 * get each single domain's sid (do we _really_ need this ?):
6355 * 1) connect to domain's pdc
6356 * 2) query the pdc for domain's sid
6359 /* get rid of '$' tail */
6360 ascii_dom_name_len = strlen(trusting_dom_names[i]);
6361 if (ascii_dom_name_len && ascii_dom_name_len < FSTRING_LEN)
6362 trusting_dom_names[i][ascii_dom_name_len - 1] = '\0';
6364 /* calculate padding space for d_printf to look nicer */
6365 pad_len = col_len - strlen(trusting_dom_names[i]);
6366 padding[pad_len] = 0;
6367 do padding[--pad_len] = ' '; while (pad_len);
6369 /* set opt_* variables to remote domain */
6370 strupper_m(trusting_dom_names[i]);
6371 opt_workgroup = talloc_strdup(mem_ctx, trusting_dom_names[i]);
6372 opt_target_workgroup = opt_workgroup;
6374 d_printf("%s%s", trusting_dom_names[i], padding);
6376 /* connect to remote domain controller */
6377 nt_status = net_make_ipc_connection(
6378 NET_FLAGS_PDC | NET_FLAGS_ANONYMOUS,
6380 if (NT_STATUS_IS_OK(nt_status)) {
6381 /* query for domain's sid */
6382 if (run_rpc_command(remote_cli, PI_LSARPC, 0, rpc_query_domain_sid, argc, argv))
6383 d_fprintf(stderr, "couldn't get domain's sid\n");
6385 cli_shutdown(remote_cli);
6388 d_fprintf(stderr, "domain controller is not "
6390 nt_errstr(nt_status));
6394 if (!num_domains) d_printf("none\n");
6396 } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
6398 /* close opened samr and domain policy handles */
6399 nt_status = rpccli_samr_Close(pipe_hnd, mem_ctx, &domain_hnd);
6400 if (!NT_STATUS_IS_OK(nt_status)) {
6401 DEBUG(0, ("Couldn't properly close domain policy handle for domain %s\n", domain_name));
6404 nt_status = rpccli_samr_Close(pipe_hnd, mem_ctx, &connect_hnd);
6405 if (!NT_STATUS_IS_OK(nt_status)) {
6406 DEBUG(0, ("Couldn't properly close samr policy handle for domain %s\n", domain_name));
6409 /* close samr pipe and connection to IPC$ */
6412 talloc_destroy(mem_ctx);
6417 * Entrypoint for 'net rpc trustdom' code
6419 * @param argc standard argc
6420 * @param argv standard argv without initial components
6422 * @return Integer status (0 means success)
6425 static int rpc_trustdom(int argc, const char **argv)
6427 struct functable func[] = {
6428 {"add", rpc_trustdom_add},
6429 {"del", rpc_trustdom_del},
6430 {"establish", rpc_trustdom_establish},
6431 {"revoke", rpc_trustdom_revoke},
6432 {"help", rpc_trustdom_usage},
6433 {"list", rpc_trustdom_list},
6434 {"vampire", rpc_trustdom_vampire},
6439 rpc_trustdom_usage(argc, argv);
6443 return (net_run_function(argc, argv, func, rpc_user_usage));
6447 * Check if a server will take rpc commands
6448 * @param flags Type of server to connect to (PDC, DMB, localhost)
6449 * if the host is not explicitly specified
6450 * @return bool (true means rpc supported)
6452 bool net_rpc_check(unsigned flags)
6454 struct cli_state *cli;
6456 struct sockaddr_storage server_ss;
6457 char *server_name = NULL;
6460 /* flags (i.e. server type) may depend on command */
6461 if (!net_find_server(NULL, flags, &server_ss, &server_name))
6464 if ((cli = cli_initialise()) == NULL) {
6468 status = cli_connect(cli, server_name, &server_ss);
6469 if (!NT_STATUS_IS_OK(status))
6471 if (!attempt_netbios_session_request(&cli, global_myname(),
6472 server_name, &server_ss))
6474 if (!cli_negprot(cli))
6476 if (cli->protocol < PROTOCOL_NT1)
6485 /* dump sam database via samsync rpc calls */
6486 static int rpc_samdump(int argc, const char **argv) {
6487 return run_rpc_command(NULL, PI_NETLOGON, NET_FLAGS_ANONYMOUS, rpc_samdump_internals,
6491 /* syncronise sam database via samsync rpc calls */
6492 static int rpc_vampire(int argc, const char **argv) {
6493 return run_rpc_command(NULL, PI_NETLOGON, NET_FLAGS_ANONYMOUS, rpc_vampire_internals,
6498 * Migrate everything from a print-server
6500 * @param argc Standard main() style argc
6501 * @param argv Standard main() style argv. Initial components are already
6504 * @return A shell status integer (0 for success)
6506 * The order is important !
6507 * To successfully add drivers the print-queues have to exist !
6508 * Applying ACLs should be the last step, because you're easily locked out
6511 static int rpc_printer_migrate_all(int argc, const char **argv)
6516 printf("no server to migrate\n");
6520 ret = run_rpc_command(NULL, PI_SPOOLSS, 0, rpc_printer_migrate_printers_internals, argc, argv);
6524 ret = run_rpc_command(NULL, PI_SPOOLSS, 0, rpc_printer_migrate_drivers_internals, argc, argv);
6528 ret = run_rpc_command(NULL, PI_SPOOLSS, 0, rpc_printer_migrate_forms_internals, argc, argv);
6532 ret = run_rpc_command(NULL, PI_SPOOLSS, 0, rpc_printer_migrate_settings_internals, argc, argv);
6536 return run_rpc_command(NULL, PI_SPOOLSS, 0, rpc_printer_migrate_security_internals, argc, argv);
6541 * Migrate print-drivers from a print-server
6543 * @param argc Standard main() style argc
6544 * @param argv Standard main() style argv. Initial components are already
6547 * @return A shell status integer (0 for success)
6549 static int rpc_printer_migrate_drivers(int argc, const char **argv)
6552 printf("no server to migrate\n");
6556 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6557 rpc_printer_migrate_drivers_internals,
6562 * Migrate print-forms from a print-server
6564 * @param argc Standard main() style argc
6565 * @param argv Standard main() style argv. Initial components are already
6568 * @return A shell status integer (0 for success)
6570 static int rpc_printer_migrate_forms(int argc, const char **argv)
6573 printf("no server to migrate\n");
6577 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6578 rpc_printer_migrate_forms_internals,
6583 * Migrate printers from a print-server
6585 * @param argc Standard main() style argc
6586 * @param argv Standard main() style argv. Initial components are already
6589 * @return A shell status integer (0 for success)
6591 static int rpc_printer_migrate_printers(int argc, const char **argv)
6594 printf("no server to migrate\n");
6598 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6599 rpc_printer_migrate_printers_internals,
6604 * Migrate printer-ACLs from a print-server
6606 * @param argc Standard main() style argc
6607 * @param argv Standard main() style argv. Initial components are already
6610 * @return A shell status integer (0 for success)
6612 static int rpc_printer_migrate_security(int argc, const char **argv)
6615 printf("no server to migrate\n");
6619 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6620 rpc_printer_migrate_security_internals,
6625 * Migrate printer-settings from a print-server
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_migrate_settings(int argc, const char **argv)
6636 printf("no server to migrate\n");
6640 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6641 rpc_printer_migrate_settings_internals,
6646 * 'net rpc printer' entrypoint.
6647 * @param argc Standard main() style argc
6648 * @param argv Standard main() style argv. Initial components are already
6652 int rpc_printer_migrate(int argc, const char **argv)
6655 /* ouch: when addriver and setdriver are called from within
6656 rpc_printer_migrate_drivers_internals, the printer-queue already
6659 struct functable func[] = {
6660 {"all", rpc_printer_migrate_all},
6661 {"drivers", rpc_printer_migrate_drivers},
6662 {"forms", rpc_printer_migrate_forms},
6663 {"help", rpc_printer_usage},
6664 {"printers", rpc_printer_migrate_printers},
6665 {"security", rpc_printer_migrate_security},
6666 {"settings", rpc_printer_migrate_settings},
6670 return net_run_function(argc, argv, func, rpc_printer_usage);
6675 * List printers on a remote RPC server
6677 * @param argc Standard main() style argc
6678 * @param argv Standard main() style argv. Initial components are already
6681 * @return A shell status integer (0 for success)
6683 static int rpc_printer_list(int argc, const char **argv)
6686 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6687 rpc_printer_list_internals,
6692 * List printer-drivers on a remote RPC server
6694 * @param argc Standard main() style argc
6695 * @param argv Standard main() style argv. Initial components are already
6698 * @return A shell status integer (0 for success)
6700 static int rpc_printer_driver_list(int argc, const char **argv)
6703 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6704 rpc_printer_driver_list_internals,
6709 * Publish printer in ADS via MSRPC
6711 * @param argc Standard main() style argc
6712 * @param argv Standard main() style argv. Initial components are already
6715 * @return A shell status integer (0 for success)
6717 static int rpc_printer_publish_publish(int argc, const char **argv)
6720 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6721 rpc_printer_publish_publish_internals,
6726 * Update printer in ADS via MSRPC
6728 * @param argc Standard main() style argc
6729 * @param argv Standard main() style argv. Initial components are already
6732 * @return A shell status integer (0 for success)
6734 static int rpc_printer_publish_update(int argc, const char **argv)
6737 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6738 rpc_printer_publish_update_internals,
6743 * UnPublish printer in ADS via MSRPC
6745 * @param argc Standard main() style argc
6746 * @param argv Standard main() style argv. Initial components are already
6749 * @return A shell status integer (0 for success)
6751 static int rpc_printer_publish_unpublish(int argc, const char **argv)
6754 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6755 rpc_printer_publish_unpublish_internals,
6760 * List published printers via MSRPC
6762 * @param argc Standard main() style argc
6763 * @param argv Standard main() style argv. Initial components are already
6766 * @return A shell status integer (0 for success)
6768 static int rpc_printer_publish_list(int argc, const char **argv)
6771 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6772 rpc_printer_publish_list_internals,
6778 * Publish printer in ADS
6780 * @param argc Standard main() style argc
6781 * @param argv Standard main() style argv. Initial components are already
6784 * @return A shell status integer (0 for success)
6786 static int rpc_printer_publish(int argc, const char **argv)
6789 struct functable func[] = {
6790 {"publish", rpc_printer_publish_publish},
6791 {"update", rpc_printer_publish_update},
6792 {"unpublish", rpc_printer_publish_unpublish},
6793 {"list", rpc_printer_publish_list},
6794 {"help", rpc_printer_usage},
6799 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6800 rpc_printer_publish_list_internals,
6803 return net_run_function(argc, argv, func, rpc_printer_usage);
6809 * Display rpc printer help page.
6810 * @param argc Standard main() style argc
6811 * @param argv Standard main() style argv. Initial components are already
6814 int rpc_printer_usage(int argc, const char **argv)
6816 return net_help_printer(argc, argv);
6820 * 'net rpc printer' entrypoint.
6821 * @param argc Standard main() style argc
6822 * @param argv Standard main() style argv. Initial components are already
6825 int net_rpc_printer(int argc, const char **argv)
6827 struct functable func[] = {
6828 {"list", rpc_printer_list},
6829 {"migrate", rpc_printer_migrate},
6830 {"driver", rpc_printer_driver_list},
6831 {"publish", rpc_printer_publish},
6836 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6837 rpc_printer_list_internals,
6840 return net_run_function(argc, argv, func, rpc_printer_usage);
6843 /****************************************************************************/
6847 * Basic usage function for 'net rpc'
6848 * @param argc Standard main() style argc
6849 * @param argv Standard main() style argv. Initial components are already
6853 int net_rpc_usage(int argc, const char **argv)
6855 d_printf(" net rpc info \t\t\tshow basic info about a domain \n");
6856 d_printf(" net rpc join \t\t\tto join a domain \n");
6857 d_printf(" net rpc oldjoin \t\tto join a domain created in server manager\n");
6858 d_printf(" net rpc testjoin \t\ttests that a join is valid\n");
6859 d_printf(" net rpc user \t\t\tto add, delete and list users\n");
6860 d_printf(" net rpc password <username> [<password>] -Uadmin_username%%admin_pass\n");
6861 d_printf(" net rpc group \t\tto list groups\n");
6862 d_printf(" net rpc share \t\tto add, delete, list and migrate shares\n");
6863 d_printf(" net rpc printer \t\tto list and migrate printers\n");
6864 d_printf(" net rpc file \t\t\tto list open files\n");
6865 d_printf(" net rpc changetrustpw \tto change the trust account password\n");
6866 d_printf(" net rpc getsid \t\tfetch the domain sid into the local secrets.tdb\n");
6867 d_printf(" net rpc vampire \t\tsyncronise an NT PDC's users and groups into the local passdb\n");
6868 d_printf(" net rpc samdump \t\tdisplay an NT PDC's users, groups and other data\n");
6869 d_printf(" net rpc trustdom \t\tto create trusting domain's account or establish trust\n");
6870 d_printf(" net rpc abortshutdown \tto abort the shutdown of a remote server\n");
6871 d_printf(" net rpc shutdown \t\tto shutdown a remote server\n");
6872 d_printf(" net rpc rights\t\tto manage privileges assigned to SIDs\n");
6873 d_printf(" net rpc registry\t\tto manage registry hives\n");
6874 d_printf(" net rpc service\t\tto start, stop and query services\n");
6875 d_printf(" net rpc audit\t\t\tto modify global auditing settings\n");
6876 d_printf(" net rpc shell\t\t\tto open an interactive shell for remote server/account management\n");
6878 d_printf("'net rpc shutdown' also accepts the following miscellaneous options:\n"); /* misc options */
6879 d_printf("\t-r or --reboot\trequest remote server reboot on shutdown\n");
6880 d_printf("\t-f or --force\trequest the remote server force its shutdown\n");
6881 d_printf("\t-t or --timeout=<timeout>\tnumber of seconds before shutdown\n");
6882 d_printf("\t-C or --comment=<message>\ttext message to display on impending shutdown\n");
6888 * Help function for 'net rpc'. Calls command specific help if requested
6889 * or displays usage of net rpc
6890 * @param argc Standard main() style argc
6891 * @param argv Standard main() style argv. Initial components are already
6895 int net_rpc_help(int argc, const char **argv)
6897 struct functable func[] = {
6898 {"join", rpc_join_usage},
6899 {"user", rpc_user_usage},
6900 {"group", rpc_group_usage},
6901 {"share", rpc_share_usage},
6902 /*{"changetrustpw", rpc_changetrustpw_usage}, */
6903 {"trustdom", rpc_trustdom_usage},
6904 /*{"abortshutdown", rpc_shutdown_abort_usage},*/
6905 /*{"shutdown", rpc_shutdown_usage}, */
6906 {"vampire", rpc_vampire_usage},
6911 net_rpc_usage(argc, argv);
6915 return (net_run_function(argc, argv, func, rpc_user_usage));
6919 * 'net rpc' entrypoint.
6920 * @param argc Standard main() style argc
6921 * @param argv Standard main() style argv. Initial components are already
6925 int net_rpc(int argc, const char **argv)
6927 struct functable func[] = {
6928 {"audit", net_rpc_audit},
6929 {"info", net_rpc_info},
6930 {"join", net_rpc_join},
6931 {"oldjoin", net_rpc_oldjoin},
6932 {"testjoin", net_rpc_testjoin},
6933 {"user", net_rpc_user},
6934 {"password", rpc_user_password},
6935 {"group", net_rpc_group},
6936 {"share", net_rpc_share},
6937 {"file", net_rpc_file},
6938 {"printer", net_rpc_printer},
6939 {"changetrustpw", net_rpc_changetrustpw},
6940 {"trustdom", rpc_trustdom},
6941 {"abortshutdown", rpc_shutdown_abort},
6942 {"shutdown", rpc_shutdown},
6943 {"samdump", rpc_samdump},
6944 {"vampire", rpc_vampire},
6945 {"getsid", net_rpc_getsid},
6946 {"rights", net_rpc_rights},
6947 {"service", net_rpc_service},
6948 {"registry", net_rpc_registry},
6949 {"shell", net_rpc_shell},
6950 {"help", net_rpc_help},
6953 return net_run_function(argc, argv, func, net_rpc_usage);