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,
54 DOM_SID **domain_sid, char **domain_name)
56 struct rpc_pipe_client *lsa_pipe;
58 NTSTATUS result = NT_STATUS_OK;
59 uint32 info_class = 5;
61 lsa_pipe = cli_rpc_pipe_open_noauth(cli, PI_LSARPC, &result);
63 d_fprintf(stderr, "Could not initialise lsa pipe\n");
67 result = rpccli_lsa_open_policy(lsa_pipe, mem_ctx, False,
68 SEC_RIGHTS_MAXIMUM_ALLOWED,
70 if (!NT_STATUS_IS_OK(result)) {
71 d_fprintf(stderr, "open_policy failed: %s\n",
76 result = rpccli_lsa_query_info_policy(lsa_pipe, mem_ctx, &pol,
77 info_class, domain_name,
79 if (!NT_STATUS_IS_OK(result)) {
80 d_fprintf(stderr, "lsaquery failed: %s\n",
85 rpccli_lsa_Close(lsa_pipe, mem_ctx, &pol);
86 cli_rpc_pipe_close(lsa_pipe);
92 * Run a single RPC command, from start to finish.
94 * @param pipe_name the pipe to connect to (usually a PIPE_ constant)
95 * @param conn_flag a NET_FLAG_ combination. Passed to
96 * net_make_ipc_connection.
97 * @param argc Standard main() style argc
98 * @param argc Standard main() style argv. Initial components are already
100 * @return A shell status integer (0 for success)
103 int run_rpc_command(struct cli_state *cli_arg,
110 struct cli_state *cli = NULL;
111 struct rpc_pipe_client *pipe_hnd = NULL;
117 /* make use of cli_state handed over as an argument, if possible */
119 nt_status = net_make_ipc_connection(conn_flags, &cli);
120 if (!NT_STATUS_IS_OK(nt_status)) {
121 DEBUG(1, ("failed to make ipc connection: %s\n",
122 nt_errstr(nt_status)));
135 if (!(mem_ctx = talloc_init("run_rpc_command"))) {
136 DEBUG(0, ("talloc_init() failed\n"));
141 nt_status = net_get_remote_domain_sid(cli, mem_ctx, &domain_sid,
143 if (!NT_STATUS_IS_OK(nt_status)) {
148 if (!(conn_flags & NET_FLAGS_NO_PIPE)) {
149 if (lp_client_schannel() && (pipe_idx == PI_NETLOGON)) {
150 /* Always try and create an schannel netlogon pipe. */
151 pipe_hnd = cli_rpc_pipe_open_schannel(cli, pipe_idx,
152 PIPE_AUTH_LEVEL_PRIVACY,
156 DEBUG(0, ("Could not initialise schannel netlogon pipe. Error was %s\n",
157 nt_errstr(nt_status) ));
162 pipe_hnd = cli_rpc_pipe_open_noauth(cli, pipe_idx, &nt_status);
164 DEBUG(0, ("Could not initialise pipe %s. Error was %s\n",
165 cli_get_pipe_name(pipe_idx),
166 nt_errstr(nt_status) ));
173 nt_status = fn(domain_sid, domain_name, cli, pipe_hnd, mem_ctx, argc, argv);
175 if (!NT_STATUS_IS_OK(nt_status)) {
176 DEBUG(1, ("rpc command function failed! (%s)\n", nt_errstr(nt_status)));
178 DEBUG(5, ("rpc command function succedded\n"));
181 if (!(conn_flags & NET_FLAGS_NO_PIPE)) {
183 cli_rpc_pipe_close(pipe_hnd);
187 /* close the connection only if it was opened here */
192 talloc_destroy(mem_ctx);
193 return (!NT_STATUS_IS_OK(nt_status));
197 * Force a change of the trust acccount password.
199 * All parameters are provided by the run_rpc_command function, except for
200 * argc, argv which are passes through.
202 * @param domain_sid The domain sid aquired from the remote server
203 * @param cli A cli_state connected to the server.
204 * @param mem_ctx Talloc context, destoyed on compleation of the function.
205 * @param argc Standard main() style argc
206 * @param argc Standard main() style argv. Initial components are already
209 * @return Normal NTSTATUS return.
212 static NTSTATUS rpc_changetrustpw_internals(const DOM_SID *domain_sid,
213 const char *domain_name,
214 struct cli_state *cli,
215 struct rpc_pipe_client *pipe_hnd,
221 return trust_pw_find_change_and_store_it(pipe_hnd, mem_ctx, opt_target_workgroup);
225 * Force a change of the trust acccount password.
227 * @param argc Standard main() style argc
228 * @param argc Standard main() style argv. Initial components are already
231 * @return A shell status integer (0 for success)
234 int net_rpc_changetrustpw(int argc, const char **argv)
236 return run_rpc_command(NULL, PI_NETLOGON, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC,
237 rpc_changetrustpw_internals,
242 * Join a domain, the old way.
244 * This uses 'machinename' as the inital password, and changes it.
246 * The password should be created with 'server manager' or equiv first.
248 * All parameters are provided by the run_rpc_command function, except for
249 * argc, argv which are passes through.
251 * @param domain_sid The domain sid aquired from the remote server
252 * @param cli A cli_state connected to the server.
253 * @param mem_ctx Talloc context, destoyed on compleation of the function.
254 * @param argc Standard main() style argc
255 * @param argc Standard main() style argv. Initial components are already
258 * @return Normal NTSTATUS return.
261 static NTSTATUS rpc_oldjoin_internals(const DOM_SID *domain_sid,
262 const char *domain_name,
263 struct cli_state *cli,
264 struct rpc_pipe_client *pipe_hnd,
270 fstring trust_passwd;
271 unsigned char orig_trust_passwd_hash[16];
273 uint32 sec_channel_type;
275 pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_NETLOGON, &result);
277 DEBUG(0,("rpc_oldjoin_internals: netlogon pipe open to machine %s failed. "
280 nt_errstr(result) ));
285 check what type of join - if the user want's to join as
286 a BDC, the server must agree that we are a BDC.
289 sec_channel_type = get_sec_channel_type(argv[0]);
291 sec_channel_type = get_sec_channel_type(NULL);
294 fstrcpy(trust_passwd, global_myname());
295 strlower_m(trust_passwd);
298 * Machine names can be 15 characters, but the max length on
299 * a password is 14. --jerry
302 trust_passwd[14] = '\0';
304 E_md4hash(trust_passwd, orig_trust_passwd_hash);
306 result = trust_pw_change_and_store_it(pipe_hnd, mem_ctx, opt_target_workgroup,
307 orig_trust_passwd_hash,
310 if (NT_STATUS_IS_OK(result))
311 printf("Joined domain %s.\n",opt_target_workgroup);
314 if (!secrets_store_domain_sid(opt_target_workgroup, domain_sid)) {
315 DEBUG(0, ("error storing domain sid for %s\n", opt_target_workgroup));
316 result = NT_STATUS_UNSUCCESSFUL;
323 * Join a domain, the old way.
325 * @param argc Standard main() style argc
326 * @param argc Standard main() style argv. Initial components are already
329 * @return A shell status integer (0 for success)
332 static int net_rpc_perform_oldjoin(int argc, const char **argv)
334 return run_rpc_command(NULL, PI_NETLOGON,
335 NET_FLAGS_NO_PIPE | NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC,
336 rpc_oldjoin_internals,
341 * Join a domain, the old way. This function exists to allow
342 * the message to be displayed when oldjoin was explicitly
343 * requested, but not when it was implied by "net rpc join"
345 * @param argc Standard main() style argc
346 * @param argc Standard main() style argv. Initial components are already
349 * @return A shell status integer (0 for success)
352 static int net_rpc_oldjoin(int argc, const char **argv)
354 int rc = net_rpc_perform_oldjoin(argc, argv);
357 d_fprintf(stderr, "Failed to join domain\n");
364 * Basic usage function for 'net rpc join'
365 * @param argc Standard main() style argc
366 * @param argc Standard main() style argv. Initial components are already
370 static int rpc_join_usage(int argc, const char **argv)
372 d_printf("net rpc join -U <username>[%%password] <type>[options]\n"\
373 "\t to join a domain with admin username & password\n"\
374 "\t\t password will be prompted if needed and none is specified\n"\
375 "\t <type> can be (default MEMBER)\n"\
376 "\t\t BDC - Join as a BDC\n"\
377 "\t\t PDC - Join as a PDC\n"\
378 "\t\t MEMBER - Join as a MEMBER server\n");
380 net_common_flags_usage(argc, argv);
385 * 'net rpc join' entrypoint.
386 * @param argc Standard main() style argc
387 * @param argc Standard main() style argv. Initial components are already
390 * Main 'net_rpc_join()' (where the admain username/password is used) is
392 * Try to just change the password, but if that doesn't work, use/prompt
393 * for a username/password.
396 int net_rpc_join(int argc, const char **argv)
398 if (lp_server_role() == ROLE_STANDALONE) {
399 d_printf("cannot join as standalone machine\n");
403 if (strlen(global_myname()) > 15) {
404 d_printf("Our netbios name can be at most 15 chars long, "
405 "\"%s\" is %u chars long\n",
406 global_myname(), (unsigned int)strlen(global_myname()));
410 if ((net_rpc_perform_oldjoin(argc, argv) == 0))
413 return net_rpc_join_newstyle(argc, argv);
417 * display info about a rpc domain
419 * All parameters are provided by the run_rpc_command function, except for
420 * argc, argv which are passed through.
422 * @param domain_sid The domain sid acquired from the remote server
423 * @param cli A cli_state connected to the server.
424 * @param mem_ctx Talloc context, destoyed on completion of the function.
425 * @param argc Standard main() style argc
426 * @param argv Standard main() style argv. Initial components are already
429 * @return Normal NTSTATUS return.
432 NTSTATUS rpc_info_internals(const DOM_SID *domain_sid,
433 const char *domain_name,
434 struct cli_state *cli,
435 struct rpc_pipe_client *pipe_hnd,
440 POLICY_HND connect_pol, domain_pol;
441 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
445 sid_to_fstring(sid_str, domain_sid);
447 /* Get sam policy handle */
448 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
450 if (!NT_STATUS_IS_OK(result)) {
451 d_fprintf(stderr, "Could not connect to SAM: %s\n", nt_errstr(result));
455 /* Get domain policy handle */
456 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
457 MAXIMUM_ALLOWED_ACCESS,
458 domain_sid, &domain_pol);
459 if (!NT_STATUS_IS_OK(result)) {
460 d_fprintf(stderr, "Could not open domain: %s\n", nt_errstr(result));
465 result = rpccli_samr_query_dom_info(pipe_hnd, mem_ctx, &domain_pol,
467 if (NT_STATUS_IS_OK(result)) {
468 TALLOC_CTX *ctx = talloc_init("rpc_info_internals");
469 d_printf("Domain Name: %s\n", unistr2_to_ascii_talloc(ctx, &ctr.info.inf2.uni_domain));
470 d_printf("Domain SID: %s\n", sid_str);
471 d_printf("Sequence number: %llu\n", (unsigned long long)ctr.info.inf2.seq_num);
472 d_printf("Num users: %u\n", ctr.info.inf2.num_domain_usrs);
473 d_printf("Num domain groups: %u\n", ctr.info.inf2.num_domain_grps);
474 d_printf("Num local groups: %u\n", ctr.info.inf2.num_local_grps);
483 * 'net rpc info' entrypoint.
484 * @param argc Standard main() style argc
485 * @param argc Standard main() style argv. Initial components are already
489 int net_rpc_info(int argc, const char **argv)
491 return run_rpc_command(NULL, PI_SAMR, NET_FLAGS_PDC,
497 * Fetch domain SID into the local secrets.tdb
499 * All parameters are provided by the run_rpc_command function, except for
500 * argc, argv which are passes through.
502 * @param domain_sid The domain sid acquired from the remote server
503 * @param cli A cli_state connected to the server.
504 * @param mem_ctx Talloc context, destoyed on completion of the function.
505 * @param argc Standard main() style argc
506 * @param argv Standard main() style argv. Initial components are already
509 * @return Normal NTSTATUS return.
512 static NTSTATUS rpc_getsid_internals(const DOM_SID *domain_sid,
513 const char *domain_name,
514 struct cli_state *cli,
515 struct rpc_pipe_client *pipe_hnd,
522 sid_to_fstring(sid_str, domain_sid);
523 d_printf("Storing SID %s for Domain %s in secrets.tdb\n",
524 sid_str, domain_name);
526 if (!secrets_store_domain_sid(domain_name, domain_sid)) {
527 DEBUG(0,("Can't store domain SID\n"));
528 return NT_STATUS_UNSUCCESSFUL;
535 * 'net rpc getsid' entrypoint.
536 * @param argc Standard main() style argc
537 * @param argc Standard main() style argv. Initial components are already
541 int net_rpc_getsid(int argc, const char **argv)
543 return run_rpc_command(NULL, PI_SAMR, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC,
544 rpc_getsid_internals,
548 /****************************************************************************/
551 * Basic usage function for 'net rpc user'
552 * @param argc Standard main() style argc.
553 * @param argv Standard main() style argv. Initial components are already
557 static int rpc_user_usage(int argc, const char **argv)
559 return net_help_user(argc, argv);
563 * Add a new user to a remote RPC server
565 * All parameters are provided by the run_rpc_command function, except for
566 * argc, argv which are passes through.
568 * @param domain_sid The domain sid acquired from the remote server
569 * @param cli A cli_state connected to the server.
570 * @param mem_ctx Talloc context, destoyed on completion of the function.
571 * @param argc Standard main() style argc
572 * @param argv Standard main() style argv. Initial components are already
575 * @return Normal NTSTATUS return.
578 static NTSTATUS rpc_user_add_internals(const DOM_SID *domain_sid,
579 const char *domain_name,
580 struct cli_state *cli,
581 struct rpc_pipe_client *pipe_hnd,
583 int argc, const char **argv)
586 POLICY_HND connect_pol, domain_pol, user_pol;
587 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
588 const char *acct_name;
590 uint32 access_mask, user_rid;
593 d_printf("User must be specified\n");
594 rpc_user_usage(argc, argv);
600 /* Get sam policy handle */
602 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
604 if (!NT_STATUS_IS_OK(result)) {
608 /* Get domain policy handle */
610 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
611 MAXIMUM_ALLOWED_ACCESS,
612 domain_sid, &domain_pol);
613 if (!NT_STATUS_IS_OK(result)) {
617 /* Create domain user */
619 acb_info = ACB_NORMAL;
620 access_mask = 0xe005000b;
622 result = rpccli_samr_create_dom_user(pipe_hnd, mem_ctx, &domain_pol,
623 acct_name, acb_info, access_mask,
624 &user_pol, &user_rid);
625 if (!NT_STATUS_IS_OK(result)) {
631 uint32 *user_rids, num_rids, *name_types;
632 uint32 flags = 0x000003e8; /* Unknown */
633 SAM_USERINFO_CTR ctr;
634 SAM_USER_INFO_24 p24;
637 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol,
638 flags, 1, &acct_name,
639 &num_rids, &user_rids,
642 if (!NT_STATUS_IS_OK(result)) {
646 result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
647 MAXIMUM_ALLOWED_ACCESS,
648 user_rids[0], &user_pol);
650 if (!NT_STATUS_IS_OK(result)) {
654 /* Set password on account */
659 encode_pw_buffer(pwbuf, argv[1], STR_UNICODE);
661 init_sam_user_info24(&p24, (char *)pwbuf,24);
663 ctr.switch_value = 24;
664 ctr.info.id24 = &p24;
666 result = rpccli_samr_set_userinfo(pipe_hnd, mem_ctx, &user_pol, 24,
667 &cli->user_session_key, &ctr);
669 if (!NT_STATUS_IS_OK(result)) {
670 d_fprintf(stderr, "Failed to set password for user %s - %s\n",
671 acct_name, nt_errstr(result));
673 result = rpccli_samr_delete_dom_user(pipe_hnd, mem_ctx, &user_pol);
675 if (!NT_STATUS_IS_OK(result)) {
676 d_fprintf(stderr, "Failed to delete user %s - %s\n",
677 acct_name, nt_errstr(result));
684 if (!NT_STATUS_IS_OK(result)) {
685 d_fprintf(stderr, "Failed to add user '%s' with %s.\n",
686 acct_name, nt_errstr(result));
688 d_printf("Added user '%s'.\n", acct_name);
694 * Add a new user to a remote RPC server
696 * @param argc Standard main() style argc
697 * @param argv Standard main() style argv. Initial components are already
700 * @return A shell status integer (0 for success)
703 static int rpc_user_add(int argc, const char **argv)
705 return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_add_internals,
710 * Delete a user from a remote RPC server
712 * All parameters are provided by the run_rpc_command function, except for
713 * argc, argv which are passes through.
715 * @param domain_sid The domain sid acquired from the remote server
716 * @param cli A cli_state connected to the server.
717 * @param mem_ctx Talloc context, destoyed on completion of the function.
718 * @param argc Standard main() style argc
719 * @param argv Standard main() style argv. Initial components are already
722 * @return Normal NTSTATUS return.
725 static NTSTATUS rpc_user_del_internals(const DOM_SID *domain_sid,
726 const char *domain_name,
727 struct cli_state *cli,
728 struct rpc_pipe_client *pipe_hnd,
733 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
734 POLICY_HND connect_pol, domain_pol, user_pol;
735 const char *acct_name;
738 d_printf("User must be specified\n");
739 rpc_user_usage(argc, argv);
745 /* Get sam policy and domain handles */
747 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
750 if (!NT_STATUS_IS_OK(result)) {
754 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
755 MAXIMUM_ALLOWED_ACCESS,
756 domain_sid, &domain_pol);
758 if (!NT_STATUS_IS_OK(result)) {
762 /* Get handle on user */
765 uint32 *user_rids, num_rids, *name_types;
766 uint32 flags = 0x000003e8; /* Unknown */
768 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol,
769 flags, 1, &acct_name,
770 &num_rids, &user_rids,
773 if (!NT_STATUS_IS_OK(result)) {
777 result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
778 MAXIMUM_ALLOWED_ACCESS,
779 user_rids[0], &user_pol);
781 if (!NT_STATUS_IS_OK(result)) {
788 result = rpccli_samr_delete_dom_user(pipe_hnd, mem_ctx, &user_pol);
790 if (!NT_STATUS_IS_OK(result)) {
795 if (!NT_STATUS_IS_OK(result)) {
796 d_fprintf(stderr, "Failed to delete user '%s' with %s.\n",
797 acct_name, nt_errstr(result));
799 d_printf("Deleted user '%s'.\n", acct_name);
806 * Rename a user on a remote RPC server
808 * All parameters are provided by the run_rpc_command function, except for
809 * argc, argv which are passes through.
811 * @param domain_sid The domain sid acquired from the remote server
812 * @param cli A cli_state connected to the server.
813 * @param mem_ctx Talloc context, destoyed on completion of the function.
814 * @param argc Standard main() style argc
815 * @param argv Standard main() style argv. Initial components are already
818 * @return Normal NTSTATUS return.
821 static NTSTATUS rpc_user_rename_internals(const DOM_SID *domain_sid,
822 const char *domain_name,
823 struct cli_state *cli,
824 struct rpc_pipe_client *pipe_hnd,
829 POLICY_HND connect_pol, domain_pol, user_pol;
830 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
831 uint32 info_level = 7;
832 const char *old_name, *new_name;
834 uint32 flags = 0x000003e8; /* Unknown */
835 uint32 num_rids, *name_types;
836 uint32 num_names = 1;
838 SAM_USERINFO_CTR *user_ctr;
839 SAM_USERINFO_CTR ctr;
840 SAM_USER_INFO_7 info7;
843 d_printf("Old and new username must be specified\n");
844 rpc_user_usage(argc, argv);
852 ZERO_STRUCT(user_ctr);
854 /* Get sam policy handle */
856 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
858 if (!NT_STATUS_IS_OK(result)) {
862 /* Get domain policy handle */
864 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
865 MAXIMUM_ALLOWED_ACCESS,
866 domain_sid, &domain_pol);
867 if (!NT_STATUS_IS_OK(result)) {
871 if ((names = TALLOC_ARRAY(mem_ctx, const char *, num_names)) == NULL) {
872 result = NT_STATUS_NO_MEMORY;
876 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol,
877 flags, num_names, names,
878 &num_rids, &user_rid, &name_types);
879 if (!NT_STATUS_IS_OK(result)) {
883 /* Open domain user */
884 result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
885 MAXIMUM_ALLOWED_ACCESS, user_rid[0], &user_pol);
887 if (!NT_STATUS_IS_OK(result)) {
891 /* Query user info */
892 result = rpccli_samr_query_userinfo(pipe_hnd, mem_ctx, &user_pol,
893 info_level, &user_ctr);
895 if (!NT_STATUS_IS_OK(result)) {
899 ctr.switch_value = info_level;
900 ctr.info.id7 = &info7;
902 init_sam_user_info7(&info7, new_name);
905 result = rpccli_samr_set_userinfo(pipe_hnd, mem_ctx, &user_pol,
906 info_level, &cli->user_session_key, &ctr);
908 if (!NT_STATUS_IS_OK(result)) {
913 if (!NT_STATUS_IS_OK(result)) {
914 d_fprintf(stderr, "Failed to rename user from %s to %s - %s\n", old_name, new_name,
917 d_printf("Renamed user from %s to %s\n", old_name, new_name);
923 * Rename a user on a remote RPC server
925 * @param argc Standard main() style argc
926 * @param argv Standard main() style argv. Initial components are already
929 * @return A shell status integer (0 for success)
932 static int rpc_user_rename(int argc, const char **argv)
934 return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_rename_internals,
939 * Delete a user from a remote RPC server
941 * @param argc Standard main() style argc
942 * @param argv Standard main() style argv. Initial components are already
945 * @return A shell status integer (0 for success)
948 static int rpc_user_delete(int argc, const char **argv)
950 return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_del_internals,
955 * Set a password for a user on a remote RPC server
957 * All parameters are provided by the run_rpc_command function, except for
958 * argc, argv which are passes through.
960 * @param domain_sid The domain sid acquired from the remote server
961 * @param cli A cli_state connected to the server.
962 * @param mem_ctx Talloc context, destoyed on completion of the function.
963 * @param argc Standard main() style argc
964 * @param argv Standard main() style argv. Initial components are already
967 * @return Normal NTSTATUS return.
970 static NTSTATUS rpc_user_password_internals(const DOM_SID *domain_sid,
971 const char *domain_name,
972 struct cli_state *cli,
973 struct rpc_pipe_client *pipe_hnd,
978 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
979 POLICY_HND connect_pol, domain_pol, user_pol;
980 SAM_USERINFO_CTR ctr;
981 SAM_USER_INFO_24 p24;
984 const char *new_password;
988 d_printf("User must be specified\n");
989 rpc_user_usage(argc, argv);
996 new_password = argv[1];
998 asprintf(&prompt, "Enter new password for %s:", user);
999 new_password = getpass(prompt);
1003 /* Get sam policy and domain handles */
1005 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1008 if (!NT_STATUS_IS_OK(result)) {
1012 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
1013 MAXIMUM_ALLOWED_ACCESS,
1014 domain_sid, &domain_pol);
1016 if (!NT_STATUS_IS_OK(result)) {
1020 /* Get handle on user */
1023 uint32 *user_rids, num_rids, *name_types;
1024 uint32 flags = 0x000003e8; /* Unknown */
1026 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol,
1028 &num_rids, &user_rids,
1031 if (!NT_STATUS_IS_OK(result)) {
1035 result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
1036 MAXIMUM_ALLOWED_ACCESS,
1037 user_rids[0], &user_pol);
1039 if (!NT_STATUS_IS_OK(result)) {
1044 /* Set password on account */
1049 encode_pw_buffer(pwbuf, new_password, STR_UNICODE);
1051 init_sam_user_info24(&p24, (char *)pwbuf,24);
1053 ctr.switch_value = 24;
1054 ctr.info.id24 = &p24;
1056 result = rpccli_samr_set_userinfo(pipe_hnd, mem_ctx, &user_pol, 24,
1057 &cli->user_session_key, &ctr);
1059 if (!NT_STATUS_IS_OK(result)) {
1063 /* Display results */
1071 * Set a user's password on a remote RPC server
1073 * @param argc Standard main() style argc
1074 * @param argv Standard main() style argv. Initial components are already
1077 * @return A shell status integer (0 for success)
1080 static int rpc_user_password(int argc, const char **argv)
1082 return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_password_internals,
1087 * List user's groups on a remote RPC server
1089 * All parameters are provided by the run_rpc_command function, except for
1090 * argc, argv which are passes through.
1092 * @param domain_sid The domain sid acquired from the remote server
1093 * @param cli A cli_state connected to the server.
1094 * @param mem_ctx Talloc context, destoyed on completion of the function.
1095 * @param argc Standard main() style argc
1096 * @param argv Standard main() style argv. Initial components are already
1099 * @return Normal NTSTATUS return.
1102 static NTSTATUS rpc_user_info_internals(const DOM_SID *domain_sid,
1103 const char *domain_name,
1104 struct cli_state *cli,
1105 struct rpc_pipe_client *pipe_hnd,
1106 TALLOC_CTX *mem_ctx,
1110 POLICY_HND connect_pol, domain_pol, user_pol;
1111 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1112 uint32 *rids, num_rids, *name_types, num_names;
1113 uint32 flags = 0x000003e8; /* Unknown */
1119 d_printf("User must be specified\n");
1120 rpc_user_usage(argc, argv);
1121 return NT_STATUS_OK;
1123 /* Get sam policy handle */
1125 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1127 if (!NT_STATUS_IS_OK(result)) goto done;
1129 /* Get domain policy handle */
1131 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
1132 MAXIMUM_ALLOWED_ACCESS,
1133 domain_sid, &domain_pol);
1134 if (!NT_STATUS_IS_OK(result)) goto done;
1136 /* Get handle on user */
1138 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol,
1140 &num_rids, &rids, &name_types);
1142 if (!NT_STATUS_IS_OK(result)) goto done;
1144 result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
1145 MAXIMUM_ALLOWED_ACCESS,
1146 rids[0], &user_pol);
1147 if (!NT_STATUS_IS_OK(result)) goto done;
1149 result = rpccli_samr_query_usergroups(pipe_hnd, mem_ctx, &user_pol,
1150 &num_rids, &user_gids);
1152 if (!NT_STATUS_IS_OK(result)) goto done;
1157 if ((rids = TALLOC_ARRAY(mem_ctx, uint32, num_rids)) == NULL) {
1158 result = NT_STATUS_NO_MEMORY;
1162 for (i = 0; i < num_rids; i++)
1163 rids[i] = user_gids[i].g_rid;
1165 result = rpccli_samr_lookup_rids(pipe_hnd, mem_ctx, &domain_pol,
1167 &num_names, &names, &name_types);
1169 if (!NT_STATUS_IS_OK(result)) {
1173 /* Display results */
1175 for (i = 0; i < num_names; i++)
1176 printf("%s\n", names[i]);
1183 * List a user's groups from a remote RPC server
1185 * @param argc Standard main() style argc
1186 * @param argv Standard main() style argv. Initial components are already
1189 * @return A shell status integer (0 for success)
1192 static int rpc_user_info(int argc, const char **argv)
1194 return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_info_internals,
1199 * List users on a remote RPC server
1201 * All parameters are provided by the run_rpc_command function, except for
1202 * argc, argv which are passes through.
1204 * @param domain_sid The domain sid acquired from the remote server
1205 * @param cli A cli_state connected to the server.
1206 * @param mem_ctx Talloc context, destoyed on completion of the function.
1207 * @param argc Standard main() style argc
1208 * @param argv Standard main() style argv. Initial components are already
1211 * @return Normal NTSTATUS return.
1214 static NTSTATUS rpc_user_list_internals(const DOM_SID *domain_sid,
1215 const char *domain_name,
1216 struct cli_state *cli,
1217 struct rpc_pipe_client *pipe_hnd,
1218 TALLOC_CTX *mem_ctx,
1222 POLICY_HND connect_pol, domain_pol;
1223 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1224 uint32 start_idx=0, num_entries, i, loop_count = 0;
1225 SAM_DISPINFO_CTR ctr;
1226 SAM_DISPINFO_1 info1;
1228 /* Get sam policy handle */
1230 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1232 if (!NT_STATUS_IS_OK(result)) {
1236 /* Get domain policy handle */
1238 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
1239 MAXIMUM_ALLOWED_ACCESS,
1240 domain_sid, &domain_pol);
1241 if (!NT_STATUS_IS_OK(result)) {
1245 /* Query domain users */
1248 ctr.sam.info1 = &info1;
1249 if (opt_long_list_entries)
1250 d_printf("\nUser name Comment"\
1251 "\n-----------------------------\n");
1254 uint32 max_entries, max_size;
1256 get_query_dispinfo_params(
1257 loop_count, &max_entries, &max_size);
1259 result = rpccli_samr_query_dispinfo(pipe_hnd, mem_ctx, &domain_pol,
1260 &start_idx, 1, &num_entries,
1261 max_entries, max_size, &ctr);
1264 for (i = 0; i < num_entries; i++) {
1265 unistr2_to_ascii(user, &(&ctr.sam.info1->str[i])->uni_acct_name, sizeof(user));
1266 if (opt_long_list_entries)
1267 unistr2_to_ascii(desc, &(&ctr.sam.info1->str[i])->uni_acct_desc, sizeof(desc));
1269 if (opt_long_list_entries)
1270 printf("%-21.21s %s\n", user, desc);
1272 printf("%s\n", user);
1274 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
1281 * 'net rpc user' entrypoint.
1282 * @param argc Standard main() style argc
1283 * @param argc Standard main() style argv. Initial components are already
1287 int net_rpc_user(int argc, const char **argv)
1289 struct functable func[] = {
1290 {"add", rpc_user_add},
1291 {"info", rpc_user_info},
1292 {"delete", rpc_user_delete},
1293 {"password", rpc_user_password},
1294 {"rename", rpc_user_rename},
1299 return run_rpc_command(NULL,PI_SAMR, 0,
1300 rpc_user_list_internals,
1304 return net_run_function(argc, argv, func, rpc_user_usage);
1307 static NTSTATUS rpc_sh_user_list(TALLOC_CTX *mem_ctx,
1308 struct rpc_sh_ctx *ctx,
1309 struct rpc_pipe_client *pipe_hnd,
1310 int argc, const char **argv)
1312 return rpc_user_list_internals(ctx->domain_sid, ctx->domain_name,
1313 ctx->cli, pipe_hnd, mem_ctx,
1317 static NTSTATUS rpc_sh_user_info(TALLOC_CTX *mem_ctx,
1318 struct rpc_sh_ctx *ctx,
1319 struct rpc_pipe_client *pipe_hnd,
1320 int argc, const char **argv)
1322 return rpc_user_info_internals(ctx->domain_sid, ctx->domain_name,
1323 ctx->cli, pipe_hnd, mem_ctx,
1327 static NTSTATUS rpc_sh_handle_user(TALLOC_CTX *mem_ctx,
1328 struct rpc_sh_ctx *ctx,
1329 struct rpc_pipe_client *pipe_hnd,
1330 int argc, const char **argv,
1332 TALLOC_CTX *mem_ctx,
1333 struct rpc_sh_ctx *ctx,
1334 struct rpc_pipe_client *pipe_hnd,
1335 const POLICY_HND *user_hnd,
1336 int argc, const char **argv))
1339 POLICY_HND connect_pol, domain_pol, user_pol;
1340 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1343 enum lsa_SidType type;
1346 d_fprintf(stderr, "usage: %s <username>\n", ctx->whoami);
1347 return NT_STATUS_INVALID_PARAMETER;
1350 ZERO_STRUCT(connect_pol);
1351 ZERO_STRUCT(domain_pol);
1352 ZERO_STRUCT(user_pol);
1354 result = net_rpc_lookup_name(mem_ctx, pipe_hnd->cli, argv[0],
1355 NULL, NULL, &sid, &type);
1356 if (!NT_STATUS_IS_OK(result)) {
1357 d_fprintf(stderr, "Could not lookup %s: %s\n", argv[0],
1362 if (type != SID_NAME_USER) {
1363 d_fprintf(stderr, "%s is a %s, not a user\n", argv[0],
1364 sid_type_lookup(type));
1365 result = NT_STATUS_NO_SUCH_USER;
1369 if (!sid_peek_check_rid(ctx->domain_sid, &sid, &rid)) {
1370 d_fprintf(stderr, "%s is not in our domain\n", argv[0]);
1371 result = NT_STATUS_NO_SUCH_USER;
1375 result = rpccli_samr_connect(pipe_hnd, mem_ctx,
1376 MAXIMUM_ALLOWED_ACCESS, &connect_pol);
1377 if (!NT_STATUS_IS_OK(result)) {
1381 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
1382 MAXIMUM_ALLOWED_ACCESS,
1383 ctx->domain_sid, &domain_pol);
1384 if (!NT_STATUS_IS_OK(result)) {
1388 result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
1389 MAXIMUM_ALLOWED_ACCESS,
1391 if (!NT_STATUS_IS_OK(result)) {
1395 result = fn(mem_ctx, ctx, pipe_hnd, &user_pol, argc-1, argv+1);
1398 if (is_valid_policy_hnd(&user_pol)) {
1399 rpccli_samr_close(pipe_hnd, mem_ctx, &user_pol);
1401 if (is_valid_policy_hnd(&domain_pol)) {
1402 rpccli_samr_close(pipe_hnd, mem_ctx, &domain_pol);
1404 if (is_valid_policy_hnd(&connect_pol)) {
1405 rpccli_samr_close(pipe_hnd, mem_ctx, &connect_pol);
1410 static NTSTATUS rpc_sh_user_show_internals(TALLOC_CTX *mem_ctx,
1411 struct rpc_sh_ctx *ctx,
1412 struct rpc_pipe_client *pipe_hnd,
1413 const POLICY_HND *user_hnd,
1414 int argc, const char **argv)
1417 SAM_USERINFO_CTR *ctr;
1418 SAM_USER_INFO_21 *info;
1421 d_fprintf(stderr, "usage: %s show <username>\n", ctx->whoami);
1422 return NT_STATUS_INVALID_PARAMETER;
1425 result = rpccli_samr_query_userinfo(pipe_hnd, mem_ctx, user_hnd,
1427 if (!NT_STATUS_IS_OK(result)) {
1431 info = ctr->info.id21;
1433 d_printf("user rid: %d, group rid: %d\n", info->user_rid,
1439 static NTSTATUS rpc_sh_user_show(TALLOC_CTX *mem_ctx,
1440 struct rpc_sh_ctx *ctx,
1441 struct rpc_pipe_client *pipe_hnd,
1442 int argc, const char **argv)
1444 return rpc_sh_handle_user(mem_ctx, ctx, pipe_hnd, argc, argv,
1445 rpc_sh_user_show_internals);
1448 #define FETCHSTR(name, rec) \
1449 do { if (strequal(ctx->thiscmd, name)) { \
1450 oldval = rpcstr_pull_unistr2_talloc(mem_ctx, &usr->uni_##rec); } \
1453 #define SETSTR(name, rec, flag) \
1454 do { if (strequal(ctx->thiscmd, name)) { \
1455 init_unistr2(&usr->uni_##rec, argv[0], UNI_STR_TERMINATE); \
1456 init_uni_hdr(&usr->hdr_##rec, &usr->uni_##rec); \
1457 usr->fields_present |= ACCT_##flag; } \
1460 static NTSTATUS rpc_sh_user_str_edit_internals(TALLOC_CTX *mem_ctx,
1461 struct rpc_sh_ctx *ctx,
1462 struct rpc_pipe_client *pipe_hnd,
1463 const POLICY_HND *user_hnd,
1464 int argc, const char **argv)
1467 SAM_USERINFO_CTR *ctr;
1468 SAM_USER_INFO_21 *usr;
1469 const char *username;
1470 const char *oldval = "";
1473 d_fprintf(stderr, "usage: %s <username> [new value|NULL]\n",
1475 return NT_STATUS_INVALID_PARAMETER;
1478 result = rpccli_samr_query_userinfo(pipe_hnd, mem_ctx, user_hnd,
1480 if (!NT_STATUS_IS_OK(result)) {
1484 usr = ctr->info.id21;
1486 username = rpcstr_pull_unistr2_talloc(mem_ctx, &usr->uni_user_name);
1488 FETCHSTR("fullname", full_name);
1489 FETCHSTR("homedir", home_dir);
1490 FETCHSTR("homedrive", dir_drive);
1491 FETCHSTR("logonscript", logon_script);
1492 FETCHSTR("profilepath", profile_path);
1493 FETCHSTR("description", acct_desc);
1496 d_printf("%s's %s: [%s]\n", username, ctx->thiscmd, oldval);
1502 if (strcmp(argv[0], "NULL") == 0) {
1506 SETSTR("fullname", full_name, FULL_NAME);
1507 SETSTR("homedir", home_dir, HOME_DIR);
1508 SETSTR("homedrive", dir_drive, HOME_DRIVE);
1509 SETSTR("logonscript", logon_script, LOGON_SCRIPT);
1510 SETSTR("profilepath", profile_path, PROFILE);
1511 SETSTR("description", acct_desc, DESCRIPTION);
1513 result = rpccli_samr_set_userinfo2(
1514 pipe_hnd, mem_ctx, user_hnd, 21,
1515 &pipe_hnd->cli->user_session_key, ctr);
1517 d_printf("Set %s's %s from [%s] to [%s]\n", username,
1518 ctx->thiscmd, oldval, argv[0]);
1525 #define HANDLEFLG(name, rec) \
1526 do { if (strequal(ctx->thiscmd, name)) { \
1527 oldval = (oldflags & ACB_##rec) ? "yes" : "no"; \
1529 newflags = oldflags | ACB_##rec; \
1531 newflags = oldflags & ~ACB_##rec; \
1534 static NTSTATUS rpc_sh_user_str_edit(TALLOC_CTX *mem_ctx,
1535 struct rpc_sh_ctx *ctx,
1536 struct rpc_pipe_client *pipe_hnd,
1537 int argc, const char **argv)
1539 return rpc_sh_handle_user(mem_ctx, ctx, pipe_hnd, argc, argv,
1540 rpc_sh_user_str_edit_internals);
1543 static NTSTATUS rpc_sh_user_flag_edit_internals(TALLOC_CTX *mem_ctx,
1544 struct rpc_sh_ctx *ctx,
1545 struct rpc_pipe_client *pipe_hnd,
1546 const POLICY_HND *user_hnd,
1547 int argc, const char **argv)
1550 SAM_USERINFO_CTR *ctr;
1551 SAM_USER_INFO_21 *usr;
1552 const char *username;
1553 const char *oldval = "unknown";
1554 uint32 oldflags, newflags;
1558 ((argc == 1) && !strequal(argv[0], "yes") &&
1559 !strequal(argv[0], "no"))) {
1560 d_fprintf(stderr, "usage: %s <username> [yes|no]\n",
1562 return NT_STATUS_INVALID_PARAMETER;
1565 newval = strequal(argv[0], "yes");
1567 result = rpccli_samr_query_userinfo(pipe_hnd, mem_ctx, user_hnd,
1569 if (!NT_STATUS_IS_OK(result)) {
1573 usr = ctr->info.id21;
1575 username = rpcstr_pull_unistr2_talloc(mem_ctx, &usr->uni_user_name);
1576 oldflags = usr->acb_info;
1577 newflags = usr->acb_info;
1579 HANDLEFLG("disabled", DISABLED);
1580 HANDLEFLG("pwnotreq", PWNOTREQ);
1581 HANDLEFLG("autolock", AUTOLOCK);
1582 HANDLEFLG("pwnoexp", PWNOEXP);
1585 d_printf("%s's %s flag: %s\n", username, ctx->thiscmd, oldval);
1591 usr->acb_info = newflags;
1592 usr->fields_present = ACCT_FLAGS;
1594 result = rpccli_samr_set_userinfo2(
1595 pipe_hnd, mem_ctx, user_hnd, 21,
1596 &pipe_hnd->cli->user_session_key, ctr);
1598 if (NT_STATUS_IS_OK(result)) {
1599 d_printf("Set %s's %s flag from [%s] to [%s]\n", username,
1600 ctx->thiscmd, oldval, argv[0]);
1608 static NTSTATUS rpc_sh_user_flag_edit(TALLOC_CTX *mem_ctx,
1609 struct rpc_sh_ctx *ctx,
1610 struct rpc_pipe_client *pipe_hnd,
1611 int argc, const char **argv)
1613 return rpc_sh_handle_user(mem_ctx, ctx, pipe_hnd, argc, argv,
1614 rpc_sh_user_flag_edit_internals);
1617 struct rpc_sh_cmd *net_rpc_user_edit_cmds(TALLOC_CTX *mem_ctx,
1618 struct rpc_sh_ctx *ctx)
1620 static struct rpc_sh_cmd cmds[] = {
1622 { "fullname", NULL, PI_SAMR, rpc_sh_user_str_edit,
1623 "Show/Set a user's full name" },
1625 { "homedir", NULL, PI_SAMR, rpc_sh_user_str_edit,
1626 "Show/Set a user's home directory" },
1628 { "homedrive", NULL, PI_SAMR, rpc_sh_user_str_edit,
1629 "Show/Set a user's home drive" },
1631 { "logonscript", NULL, PI_SAMR, rpc_sh_user_str_edit,
1632 "Show/Set a user's logon script" },
1634 { "profilepath", NULL, PI_SAMR, rpc_sh_user_str_edit,
1635 "Show/Set a user's profile path" },
1637 { "description", NULL, PI_SAMR, rpc_sh_user_str_edit,
1638 "Show/Set a user's description" },
1640 { "disabled", NULL, PI_SAMR, rpc_sh_user_flag_edit,
1641 "Show/Set whether a user is disabled" },
1643 { "autolock", NULL, PI_SAMR, rpc_sh_user_flag_edit,
1644 "Show/Set whether a user locked out" },
1646 { "pwnotreq", NULL, PI_SAMR, rpc_sh_user_flag_edit,
1647 "Show/Set whether a user does not need a password" },
1649 { "pwnoexp", NULL, PI_SAMR, rpc_sh_user_flag_edit,
1650 "Show/Set whether a user's password does not expire" },
1652 { NULL, NULL, 0, NULL, NULL }
1658 struct rpc_sh_cmd *net_rpc_user_cmds(TALLOC_CTX *mem_ctx,
1659 struct rpc_sh_ctx *ctx)
1661 static struct rpc_sh_cmd cmds[] = {
1663 { "list", NULL, PI_SAMR, rpc_sh_user_list,
1664 "List available users" },
1666 { "info", NULL, PI_SAMR, rpc_sh_user_info,
1667 "List the domain groups a user is member of" },
1669 { "show", NULL, PI_SAMR, rpc_sh_user_show,
1670 "Show info about a user" },
1672 { "edit", net_rpc_user_edit_cmds, 0, NULL,
1673 "Show/Modify a user's fields" },
1675 { NULL, NULL, 0, NULL, NULL }
1681 /****************************************************************************/
1684 * Basic usage function for 'net rpc group'
1685 * @param argc Standard main() style argc.
1686 * @param argv Standard main() style argv. Initial components are already
1690 static int rpc_group_usage(int argc, const char **argv)
1692 return net_help_group(argc, argv);
1696 * Delete group on a remote RPC server
1698 * All parameters are provided by the run_rpc_command function, except for
1699 * argc, argv which are passes through.
1701 * @param domain_sid The domain sid acquired from the remote server
1702 * @param cli A cli_state connected to the server.
1703 * @param mem_ctx Talloc context, destoyed on completion of the function.
1704 * @param argc Standard main() style argc
1705 * @param argv Standard main() style argv. Initial components are already
1708 * @return Normal NTSTATUS return.
1711 static NTSTATUS rpc_group_delete_internals(const DOM_SID *domain_sid,
1712 const char *domain_name,
1713 struct cli_state *cli,
1714 struct rpc_pipe_client *pipe_hnd,
1715 TALLOC_CTX *mem_ctx,
1719 POLICY_HND connect_pol, domain_pol, group_pol, user_pol;
1720 bool group_is_primary = False;
1721 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1723 uint32 *group_rids, num_rids, *name_types, num_members,
1724 *group_attrs, group_rid;
1725 uint32 flags = 0x000003e8; /* Unknown */
1728 /* DOM_GID *user_gids; */
1729 SAM_USERINFO_CTR *user_ctr;
1733 d_printf("specify group\n");
1734 rpc_group_usage(argc,argv);
1735 return NT_STATUS_OK; /* ok? */
1738 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1741 if (!NT_STATUS_IS_OK(result)) {
1742 d_fprintf(stderr, "Request samr_connect failed\n");
1746 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
1747 MAXIMUM_ALLOWED_ACCESS,
1748 domain_sid, &domain_pol);
1750 if (!NT_STATUS_IS_OK(result)) {
1751 d_fprintf(stderr, "Request open_domain failed\n");
1755 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol,
1757 &num_rids, &group_rids,
1760 if (!NT_STATUS_IS_OK(result)) {
1761 d_fprintf(stderr, "Lookup of '%s' failed\n",argv[0]);
1765 switch (name_types[0])
1767 case SID_NAME_DOM_GRP:
1768 result = rpccli_samr_open_group(pipe_hnd, mem_ctx, &domain_pol,
1769 MAXIMUM_ALLOWED_ACCESS,
1770 group_rids[0], &group_pol);
1771 if (!NT_STATUS_IS_OK(result)) {
1772 d_fprintf(stderr, "Request open_group failed");
1776 group_rid = group_rids[0];
1778 result = rpccli_samr_query_groupmem(pipe_hnd, mem_ctx, &group_pol,
1779 &num_members, &group_rids,
1782 if (!NT_STATUS_IS_OK(result)) {
1783 d_fprintf(stderr, "Unable to query group members of %s",argv[0]);
1788 d_printf("Domain Group %s (rid: %d) has %d members\n",
1789 argv[0],group_rid,num_members);
1792 /* Check if group is anyone's primary group */
1793 for (i = 0; i < num_members; i++)
1795 result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
1796 MAXIMUM_ALLOWED_ACCESS,
1797 group_rids[i], &user_pol);
1799 if (!NT_STATUS_IS_OK(result)) {
1800 d_fprintf(stderr, "Unable to open group member %d\n",group_rids[i]);
1804 ZERO_STRUCT(user_ctr);
1806 result = rpccli_samr_query_userinfo(pipe_hnd, mem_ctx, &user_pol,
1809 if (!NT_STATUS_IS_OK(result)) {
1810 d_fprintf(stderr, "Unable to lookup userinfo for group member %d\n",group_rids[i]);
1814 if (user_ctr->info.id21->group_rid == group_rid) {
1815 unistr2_to_ascii(temp, &(user_ctr->info.id21)->uni_user_name,
1818 d_printf("Group is primary group of %s\n",temp);
1819 group_is_primary = True;
1822 rpccli_samr_close(pipe_hnd, mem_ctx, &user_pol);
1825 if (group_is_primary) {
1826 d_fprintf(stderr, "Unable to delete group because some "
1827 "of it's members have it as primary group\n");
1828 result = NT_STATUS_MEMBERS_PRIMARY_GROUP;
1832 /* remove all group members */
1833 for (i = 0; i < num_members; i++)
1836 d_printf("Remove group member %d...",group_rids[i]);
1837 result = rpccli_samr_del_groupmem(pipe_hnd, mem_ctx, &group_pol, group_rids[i]);
1839 if (NT_STATUS_IS_OK(result)) {
1844 d_printf("failed\n");
1849 result = rpccli_samr_delete_dom_group(pipe_hnd, mem_ctx, &group_pol);
1852 /* removing a local group is easier... */
1853 case SID_NAME_ALIAS:
1854 result = rpccli_samr_open_alias(pipe_hnd, mem_ctx, &domain_pol,
1855 MAXIMUM_ALLOWED_ACCESS,
1856 group_rids[0], &group_pol);
1858 if (!NT_STATUS_IS_OK(result)) {
1859 d_fprintf(stderr, "Request open_alias failed\n");
1863 result = rpccli_samr_delete_dom_alias(pipe_hnd, mem_ctx, &group_pol);
1866 d_fprintf(stderr, "%s is of type %s. This command is only for deleting local or global groups\n",
1867 argv[0],sid_type_lookup(name_types[0]));
1868 result = NT_STATUS_UNSUCCESSFUL;
1873 if (NT_STATUS_IS_OK(result)) {
1875 d_printf("Deleted %s '%s'\n",sid_type_lookup(name_types[0]),argv[0]);
1877 d_fprintf(stderr, "Deleting of %s failed: %s\n",argv[0],
1878 get_friendly_nt_error_msg(result));
1886 static int rpc_group_delete(int argc, const char **argv)
1888 return run_rpc_command(NULL, PI_SAMR, 0, rpc_group_delete_internals,
1892 static NTSTATUS rpc_group_add_internals(const DOM_SID *domain_sid,
1893 const char *domain_name,
1894 struct cli_state *cli,
1895 struct rpc_pipe_client *pipe_hnd,
1896 TALLOC_CTX *mem_ctx,
1900 POLICY_HND connect_pol, domain_pol, group_pol;
1901 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1902 GROUP_INFO_CTR group_info;
1905 d_printf("Group name must be specified\n");
1906 rpc_group_usage(argc, argv);
1907 return NT_STATUS_OK;
1910 /* Get sam policy handle */
1912 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1914 if (!NT_STATUS_IS_OK(result)) goto done;
1916 /* Get domain policy handle */
1918 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
1919 MAXIMUM_ALLOWED_ACCESS,
1920 domain_sid, &domain_pol);
1921 if (!NT_STATUS_IS_OK(result)) goto done;
1923 /* Create the group */
1925 result = rpccli_samr_create_dom_group(pipe_hnd, mem_ctx, &domain_pol,
1926 argv[0], MAXIMUM_ALLOWED_ACCESS,
1928 if (!NT_STATUS_IS_OK(result)) goto done;
1930 if (strlen(opt_comment) == 0) goto done;
1932 /* We've got a comment to set */
1934 group_info.switch_value1 = 4;
1935 init_samr_group_info4(&group_info.group.info4, opt_comment);
1937 result = rpccli_samr_set_groupinfo(pipe_hnd, mem_ctx, &group_pol, &group_info);
1938 if (!NT_STATUS_IS_OK(result)) goto done;
1941 if (NT_STATUS_IS_OK(result))
1942 DEBUG(5, ("add group succeeded\n"));
1944 d_fprintf(stderr, "add group failed: %s\n", nt_errstr(result));
1949 static NTSTATUS rpc_alias_add_internals(const DOM_SID *domain_sid,
1950 const char *domain_name,
1951 struct cli_state *cli,
1952 struct rpc_pipe_client *pipe_hnd,
1953 TALLOC_CTX *mem_ctx,
1957 POLICY_HND connect_pol, domain_pol, alias_pol;
1958 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1959 ALIAS_INFO_CTR alias_info;
1962 d_printf("Alias name must be specified\n");
1963 rpc_group_usage(argc, argv);
1964 return NT_STATUS_OK;
1967 /* Get sam policy handle */
1969 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1971 if (!NT_STATUS_IS_OK(result)) goto done;
1973 /* Get domain policy handle */
1975 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
1976 MAXIMUM_ALLOWED_ACCESS,
1977 domain_sid, &domain_pol);
1978 if (!NT_STATUS_IS_OK(result)) goto done;
1980 /* Create the group */
1982 result = rpccli_samr_create_dom_alias(pipe_hnd, mem_ctx, &domain_pol,
1983 argv[0], &alias_pol);
1984 if (!NT_STATUS_IS_OK(result)) goto done;
1986 if (strlen(opt_comment) == 0) goto done;
1988 /* We've got a comment to set */
1990 alias_info.level = 3;
1991 init_samr_alias_info3(&alias_info.alias.info3, opt_comment);
1993 result = rpccli_samr_set_aliasinfo(pipe_hnd, mem_ctx, &alias_pol, &alias_info);
1994 if (!NT_STATUS_IS_OK(result)) goto done;
1997 if (NT_STATUS_IS_OK(result))
1998 DEBUG(5, ("add alias succeeded\n"));
2000 d_fprintf(stderr, "add alias failed: %s\n", nt_errstr(result));
2005 static int rpc_group_add(int argc, const char **argv)
2008 return run_rpc_command(NULL, PI_SAMR, 0,
2009 rpc_alias_add_internals,
2012 return run_rpc_command(NULL, PI_SAMR, 0,
2013 rpc_group_add_internals,
2017 static NTSTATUS get_sid_from_name(struct cli_state *cli,
2018 TALLOC_CTX *mem_ctx,
2021 enum lsa_SidType *type)
2023 DOM_SID *sids = NULL;
2024 enum lsa_SidType *types = NULL;
2025 struct rpc_pipe_client *pipe_hnd;
2027 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2029 pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_LSARPC, &result);
2034 result = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, False,
2035 SEC_RIGHTS_MAXIMUM_ALLOWED, &lsa_pol);
2037 if (!NT_STATUS_IS_OK(result)) {
2041 result = rpccli_lsa_lookup_names(pipe_hnd, mem_ctx, &lsa_pol, 1,
2042 &name, NULL, 1, &sids, &types);
2044 if (NT_STATUS_IS_OK(result)) {
2045 sid_copy(sid, &sids[0]);
2049 rpccli_lsa_Close(pipe_hnd, mem_ctx, &lsa_pol);
2053 cli_rpc_pipe_close(pipe_hnd);
2056 if (!NT_STATUS_IS_OK(result) && (StrnCaseCmp(name, "S-", 2) == 0)) {
2058 /* Try as S-1-5-whatever */
2062 if (string_to_sid(&tmp_sid, name)) {
2063 sid_copy(sid, &tmp_sid);
2064 *type = SID_NAME_UNKNOWN;
2065 result = NT_STATUS_OK;
2072 static NTSTATUS rpc_add_groupmem(struct rpc_pipe_client *pipe_hnd,
2073 TALLOC_CTX *mem_ctx,
2074 const DOM_SID *group_sid,
2077 POLICY_HND connect_pol, domain_pol;
2080 POLICY_HND group_pol;
2083 uint32 *rids = NULL;
2084 uint32 *rid_types = NULL;
2088 sid_copy(&sid, group_sid);
2090 if (!sid_split_rid(&sid, &group_rid)) {
2091 return NT_STATUS_UNSUCCESSFUL;
2094 /* Get sam policy handle */
2095 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
2097 if (!NT_STATUS_IS_OK(result)) {
2101 /* Get domain policy handle */
2102 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
2103 MAXIMUM_ALLOWED_ACCESS,
2105 if (!NT_STATUS_IS_OK(result)) {
2109 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, 1000,
2111 &num_rids, &rids, &rid_types);
2113 if (!NT_STATUS_IS_OK(result)) {
2114 d_fprintf(stderr, "Could not lookup up group member %s\n", member);
2118 result = rpccli_samr_open_group(pipe_hnd, mem_ctx, &domain_pol,
2119 MAXIMUM_ALLOWED_ACCESS,
2120 group_rid, &group_pol);
2122 if (!NT_STATUS_IS_OK(result)) {
2126 result = rpccli_samr_add_groupmem(pipe_hnd, mem_ctx, &group_pol, rids[0]);
2129 rpccli_samr_close(pipe_hnd, mem_ctx, &connect_pol);
2133 static NTSTATUS rpc_add_aliasmem(struct rpc_pipe_client *pipe_hnd,
2134 TALLOC_CTX *mem_ctx,
2135 const DOM_SID *alias_sid,
2138 POLICY_HND connect_pol, domain_pol;
2141 POLICY_HND alias_pol;
2144 enum lsa_SidType member_type;
2148 sid_copy(&sid, alias_sid);
2150 if (!sid_split_rid(&sid, &alias_rid)) {
2151 return NT_STATUS_UNSUCCESSFUL;
2154 result = get_sid_from_name(pipe_hnd->cli, mem_ctx, member,
2155 &member_sid, &member_type);
2157 if (!NT_STATUS_IS_OK(result)) {
2158 d_fprintf(stderr, "Could not lookup up group member %s\n", member);
2162 /* Get sam policy handle */
2163 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
2165 if (!NT_STATUS_IS_OK(result)) {
2169 /* Get domain policy handle */
2170 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
2171 MAXIMUM_ALLOWED_ACCESS,
2173 if (!NT_STATUS_IS_OK(result)) {
2177 result = rpccli_samr_open_alias(pipe_hnd, mem_ctx, &domain_pol,
2178 MAXIMUM_ALLOWED_ACCESS,
2179 alias_rid, &alias_pol);
2181 if (!NT_STATUS_IS_OK(result)) {
2185 result = rpccli_samr_add_aliasmem(pipe_hnd, mem_ctx, &alias_pol, &member_sid);
2187 if (!NT_STATUS_IS_OK(result)) {
2192 rpccli_samr_close(pipe_hnd, mem_ctx, &connect_pol);
2196 static NTSTATUS rpc_group_addmem_internals(const DOM_SID *domain_sid,
2197 const char *domain_name,
2198 struct cli_state *cli,
2199 struct rpc_pipe_client *pipe_hnd,
2200 TALLOC_CTX *mem_ctx,
2205 enum lsa_SidType group_type;
2208 d_printf("Usage: 'net rpc group addmem <group> <member>\n");
2209 return NT_STATUS_UNSUCCESSFUL;
2212 if (!NT_STATUS_IS_OK(get_sid_from_name(cli, mem_ctx, argv[0],
2213 &group_sid, &group_type))) {
2214 d_fprintf(stderr, "Could not lookup group name %s\n", argv[0]);
2215 return NT_STATUS_UNSUCCESSFUL;
2218 if (group_type == SID_NAME_DOM_GRP) {
2219 NTSTATUS result = rpc_add_groupmem(pipe_hnd, mem_ctx,
2220 &group_sid, argv[1]);
2222 if (!NT_STATUS_IS_OK(result)) {
2223 d_fprintf(stderr, "Could not add %s to %s: %s\n",
2224 argv[1], argv[0], nt_errstr(result));
2229 if (group_type == SID_NAME_ALIAS) {
2230 NTSTATUS result = rpc_add_aliasmem(pipe_hnd, mem_ctx,
2231 &group_sid, argv[1]);
2233 if (!NT_STATUS_IS_OK(result)) {
2234 d_fprintf(stderr, "Could not add %s to %s: %s\n",
2235 argv[1], argv[0], nt_errstr(result));
2240 d_fprintf(stderr, "Can only add members to global or local groups "
2241 "which %s is not\n", argv[0]);
2243 return NT_STATUS_UNSUCCESSFUL;
2246 static int rpc_group_addmem(int argc, const char **argv)
2248 return run_rpc_command(NULL, PI_SAMR, 0,
2249 rpc_group_addmem_internals,
2253 static NTSTATUS rpc_del_groupmem(struct rpc_pipe_client *pipe_hnd,
2254 TALLOC_CTX *mem_ctx,
2255 const DOM_SID *group_sid,
2258 POLICY_HND connect_pol, domain_pol;
2261 POLICY_HND group_pol;
2264 uint32 *rids = NULL;
2265 uint32 *rid_types = NULL;
2269 sid_copy(&sid, group_sid);
2271 if (!sid_split_rid(&sid, &group_rid))
2272 return NT_STATUS_UNSUCCESSFUL;
2274 /* Get sam policy handle */
2275 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
2277 if (!NT_STATUS_IS_OK(result))
2280 /* Get domain policy handle */
2281 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
2282 MAXIMUM_ALLOWED_ACCESS,
2284 if (!NT_STATUS_IS_OK(result))
2287 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, 1000,
2289 &num_rids, &rids, &rid_types);
2291 if (!NT_STATUS_IS_OK(result)) {
2292 d_fprintf(stderr, "Could not lookup up group member %s\n", member);
2296 result = rpccli_samr_open_group(pipe_hnd, mem_ctx, &domain_pol,
2297 MAXIMUM_ALLOWED_ACCESS,
2298 group_rid, &group_pol);
2300 if (!NT_STATUS_IS_OK(result))
2303 result = rpccli_samr_del_groupmem(pipe_hnd, mem_ctx, &group_pol, rids[0]);
2306 rpccli_samr_close(pipe_hnd, mem_ctx, &connect_pol);
2310 static NTSTATUS rpc_del_aliasmem(struct rpc_pipe_client *pipe_hnd,
2311 TALLOC_CTX *mem_ctx,
2312 const DOM_SID *alias_sid,
2315 POLICY_HND connect_pol, domain_pol;
2318 POLICY_HND alias_pol;
2321 enum lsa_SidType member_type;
2325 sid_copy(&sid, alias_sid);
2327 if (!sid_split_rid(&sid, &alias_rid))
2328 return NT_STATUS_UNSUCCESSFUL;
2330 result = get_sid_from_name(pipe_hnd->cli, mem_ctx, member,
2331 &member_sid, &member_type);
2333 if (!NT_STATUS_IS_OK(result)) {
2334 d_fprintf(stderr, "Could not lookup up group member %s\n", member);
2338 /* Get sam policy handle */
2339 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
2341 if (!NT_STATUS_IS_OK(result)) {
2345 /* Get domain policy handle */
2346 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
2347 MAXIMUM_ALLOWED_ACCESS,
2349 if (!NT_STATUS_IS_OK(result)) {
2353 result = rpccli_samr_open_alias(pipe_hnd, mem_ctx, &domain_pol,
2354 MAXIMUM_ALLOWED_ACCESS,
2355 alias_rid, &alias_pol);
2357 if (!NT_STATUS_IS_OK(result))
2360 result = rpccli_samr_del_aliasmem(pipe_hnd, mem_ctx, &alias_pol, &member_sid);
2362 if (!NT_STATUS_IS_OK(result))
2366 rpccli_samr_close(pipe_hnd, mem_ctx, &connect_pol);
2370 static NTSTATUS rpc_group_delmem_internals(const DOM_SID *domain_sid,
2371 const char *domain_name,
2372 struct cli_state *cli,
2373 struct rpc_pipe_client *pipe_hnd,
2374 TALLOC_CTX *mem_ctx,
2379 enum lsa_SidType group_type;
2382 d_printf("Usage: 'net rpc group delmem <group> <member>\n");
2383 return NT_STATUS_UNSUCCESSFUL;
2386 if (!NT_STATUS_IS_OK(get_sid_from_name(cli, mem_ctx, argv[0],
2387 &group_sid, &group_type))) {
2388 d_fprintf(stderr, "Could not lookup group name %s\n", argv[0]);
2389 return NT_STATUS_UNSUCCESSFUL;
2392 if (group_type == SID_NAME_DOM_GRP) {
2393 NTSTATUS result = rpc_del_groupmem(pipe_hnd, mem_ctx,
2394 &group_sid, argv[1]);
2396 if (!NT_STATUS_IS_OK(result)) {
2397 d_fprintf(stderr, "Could not del %s from %s: %s\n",
2398 argv[1], argv[0], nt_errstr(result));
2403 if (group_type == SID_NAME_ALIAS) {
2404 NTSTATUS result = rpc_del_aliasmem(pipe_hnd, mem_ctx,
2405 &group_sid, argv[1]);
2407 if (!NT_STATUS_IS_OK(result)) {
2408 d_fprintf(stderr, "Could not del %s from %s: %s\n",
2409 argv[1], argv[0], nt_errstr(result));
2414 d_fprintf(stderr, "Can only delete members from global or local groups "
2415 "which %s is not\n", argv[0]);
2417 return NT_STATUS_UNSUCCESSFUL;
2420 static int rpc_group_delmem(int argc, const char **argv)
2422 return run_rpc_command(NULL, PI_SAMR, 0,
2423 rpc_group_delmem_internals,
2428 * List groups on a remote RPC server
2430 * All parameters are provided by the run_rpc_command function, except for
2431 * argc, argv which are passes through.
2433 * @param domain_sid The domain sid acquired from the remote server
2434 * @param cli A cli_state connected to the server.
2435 * @param mem_ctx Talloc context, destoyed on completion of the function.
2436 * @param argc Standard main() style argc
2437 * @param argv Standard main() style argv. Initial components are already
2440 * @return Normal NTSTATUS return.
2443 static NTSTATUS rpc_group_list_internals(const DOM_SID *domain_sid,
2444 const char *domain_name,
2445 struct cli_state *cli,
2446 struct rpc_pipe_client *pipe_hnd,
2447 TALLOC_CTX *mem_ctx,
2451 POLICY_HND connect_pol, domain_pol;
2452 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2453 uint32 start_idx=0, max_entries=250, num_entries, i, loop_count = 0;
2454 struct acct_info *groups;
2455 bool global = False;
2457 bool builtin = False;
2465 for (i=0; i<argc; i++) {
2466 if (strequal(argv[i], "global"))
2469 if (strequal(argv[i], "local"))
2472 if (strequal(argv[i], "builtin"))
2476 /* Get sam policy handle */
2478 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
2480 if (!NT_STATUS_IS_OK(result)) {
2484 /* Get domain policy handle */
2486 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
2487 MAXIMUM_ALLOWED_ACCESS,
2488 domain_sid, &domain_pol);
2489 if (!NT_STATUS_IS_OK(result)) {
2493 /* Query domain groups */
2494 if (opt_long_list_entries)
2495 d_printf("\nGroup name Comment"\
2496 "\n-----------------------------\n");
2498 SAM_DISPINFO_CTR ctr;
2499 SAM_DISPINFO_3 info3;
2504 ctr.sam.info3 = &info3;
2508 get_query_dispinfo_params(
2509 loop_count, &max_entries, &max_size);
2511 result = rpccli_samr_query_dispinfo(pipe_hnd, mem_ctx, &domain_pol,
2512 &start_idx, 3, &num_entries,
2513 max_entries, max_size, &ctr);
2515 if (!NT_STATUS_IS_OK(result) &&
2516 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
2519 for (i = 0; i < num_entries; i++) {
2521 fstring group, desc;
2523 unistr2_to_ascii(group, &(&ctr.sam.info3->str[i])->uni_grp_name, sizeof(group));
2524 unistr2_to_ascii(desc, &(&ctr.sam.info3->str[i])->uni_grp_desc, sizeof(desc));
2526 if (opt_long_list_entries)
2527 printf("%-21.21s %-50.50s\n",
2530 printf("%s\n", group);
2532 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
2533 /* query domain aliases */
2538 /* The max_size field in cli_samr_enum_als_groups is more like
2539 * an account_control field with indiviual bits what to
2540 * retrieve. Set this to 0xffff as NT4 usrmgr.exe does to get
2541 * everything. I'm too lazy (sorry) to get this through to
2542 * rpc_parse/ etc. Volker */
2544 result = rpccli_samr_enum_als_groups(pipe_hnd, mem_ctx, &domain_pol,
2546 &groups, &num_entries);
2548 if (!NT_STATUS_IS_OK(result) &&
2549 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
2552 for (i = 0; i < num_entries; i++) {
2554 char *description = NULL;
2556 if (opt_long_list_entries) {
2558 POLICY_HND alias_pol;
2561 if ((NT_STATUS_IS_OK(rpccli_samr_open_alias(pipe_hnd, mem_ctx,
2566 (NT_STATUS_IS_OK(rpccli_samr_query_alias_info(pipe_hnd, mem_ctx,
2569 (NT_STATUS_IS_OK(rpccli_samr_close(pipe_hnd, mem_ctx,
2571 description = unistr2_to_ascii_talloc(mem_ctx,
2572 ctr.alias.info3.description.string);
2576 if (description != NULL) {
2577 printf("%-21.21s %-50.50s\n",
2578 groups[i].acct_name,
2581 printf("%s\n", groups[i].acct_name);
2584 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
2585 rpccli_samr_close(pipe_hnd, mem_ctx, &domain_pol);
2586 /* Get builtin policy handle */
2588 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
2589 MAXIMUM_ALLOWED_ACCESS,
2590 &global_sid_Builtin, &domain_pol);
2591 if (!NT_STATUS_IS_OK(result)) {
2594 /* query builtin aliases */
2597 if (!builtin) break;
2599 result = rpccli_samr_enum_als_groups(pipe_hnd, mem_ctx, &domain_pol,
2600 &start_idx, max_entries,
2601 &groups, &num_entries);
2603 if (!NT_STATUS_IS_OK(result) &&
2604 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
2607 for (i = 0; i < num_entries; i++) {
2609 char *description = NULL;
2611 if (opt_long_list_entries) {
2613 POLICY_HND alias_pol;
2616 if ((NT_STATUS_IS_OK(rpccli_samr_open_alias(pipe_hnd, mem_ctx,
2621 (NT_STATUS_IS_OK(rpccli_samr_query_alias_info(pipe_hnd, mem_ctx,
2624 (NT_STATUS_IS_OK(rpccli_samr_close(pipe_hnd, mem_ctx,
2626 description = unistr2_to_ascii_talloc(mem_ctx,
2627 ctr.alias.info3.description.string);
2631 if (description != NULL) {
2632 printf("%-21.21s %-50.50s\n",
2633 groups[i].acct_name,
2636 printf("%s\n", groups[i].acct_name);
2639 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
2645 static int rpc_group_list(int argc, const char **argv)
2647 return run_rpc_command(NULL, PI_SAMR, 0,
2648 rpc_group_list_internals,
2652 static NTSTATUS rpc_list_group_members(struct rpc_pipe_client *pipe_hnd,
2653 TALLOC_CTX *mem_ctx,
2654 const char *domain_name,
2655 const DOM_SID *domain_sid,
2656 POLICY_HND *domain_pol,
2660 POLICY_HND group_pol;
2661 uint32 num_members, *group_rids, *group_attrs;
2668 sid_to_fstring(sid_str, domain_sid);
2670 result = rpccli_samr_open_group(pipe_hnd, mem_ctx, domain_pol,
2671 MAXIMUM_ALLOWED_ACCESS,
2674 if (!NT_STATUS_IS_OK(result))
2677 result = rpccli_samr_query_groupmem(pipe_hnd, mem_ctx, &group_pol,
2678 &num_members, &group_rids,
2681 if (!NT_STATUS_IS_OK(result))
2684 while (num_members > 0) {
2685 int this_time = 512;
2687 if (num_members < this_time)
2688 this_time = num_members;
2690 result = rpccli_samr_lookup_rids(pipe_hnd, mem_ctx, domain_pol,
2691 this_time, group_rids,
2692 &num_names, &names, &name_types);
2694 if (!NT_STATUS_IS_OK(result))
2697 /* We only have users as members, but make the output
2698 the same as the output of alias members */
2700 for (i = 0; i < this_time; i++) {
2702 if (opt_long_list_entries) {
2703 printf("%s-%d %s\\%s %d\n", sid_str,
2704 group_rids[i], domain_name, names[i],
2707 printf("%s\\%s\n", domain_name, names[i]);
2711 num_members -= this_time;
2715 return NT_STATUS_OK;
2718 static NTSTATUS rpc_list_alias_members(struct rpc_pipe_client *pipe_hnd,
2719 TALLOC_CTX *mem_ctx,
2720 POLICY_HND *domain_pol,
2724 struct rpc_pipe_client *lsa_pipe;
2725 POLICY_HND alias_pol, lsa_pol;
2727 DOM_SID *alias_sids;
2730 enum lsa_SidType *types;
2733 result = rpccli_samr_open_alias(pipe_hnd, mem_ctx, domain_pol,
2734 MAXIMUM_ALLOWED_ACCESS, rid, &alias_pol);
2736 if (!NT_STATUS_IS_OK(result))
2739 result = rpccli_samr_query_aliasmem(pipe_hnd, mem_ctx, &alias_pol,
2740 &num_members, &alias_sids);
2742 if (!NT_STATUS_IS_OK(result)) {
2743 d_fprintf(stderr, "Couldn't list alias members\n");
2747 if (num_members == 0) {
2748 return NT_STATUS_OK;
2751 lsa_pipe = cli_rpc_pipe_open_noauth(pipe_hnd->cli, PI_LSARPC, &result);
2753 d_fprintf(stderr, "Couldn't open LSA pipe. Error was %s\n",
2754 nt_errstr(result) );
2758 result = rpccli_lsa_open_policy(lsa_pipe, mem_ctx, True,
2759 SEC_RIGHTS_MAXIMUM_ALLOWED, &lsa_pol);
2761 if (!NT_STATUS_IS_OK(result)) {
2762 d_fprintf(stderr, "Couldn't open LSA policy handle\n");
2763 cli_rpc_pipe_close(lsa_pipe);
2767 result = rpccli_lsa_lookup_sids(lsa_pipe, mem_ctx, &lsa_pol, num_members,
2769 &domains, &names, &types);
2771 if (!NT_STATUS_IS_OK(result) &&
2772 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
2773 d_fprintf(stderr, "Couldn't lookup SIDs\n");
2774 cli_rpc_pipe_close(lsa_pipe);
2778 for (i = 0; i < num_members; i++) {
2780 sid_to_fstring(sid_str, &alias_sids[i]);
2782 if (opt_long_list_entries) {
2783 printf("%s %s\\%s %d\n", sid_str,
2784 domains[i] ? domains[i] : "*unknown*",
2785 names[i] ? names[i] : "*unknown*", types[i]);
2788 printf("%s\\%s\n", domains[i], names[i]);
2790 printf("%s\n", sid_str);
2794 cli_rpc_pipe_close(lsa_pipe);
2795 return NT_STATUS_OK;
2798 static NTSTATUS rpc_group_members_internals(const DOM_SID *domain_sid,
2799 const char *domain_name,
2800 struct cli_state *cli,
2801 struct rpc_pipe_client *pipe_hnd,
2802 TALLOC_CTX *mem_ctx,
2807 POLICY_HND connect_pol, domain_pol;
2808 uint32 num_rids, *rids, *rid_types;
2810 /* Get sam policy handle */
2812 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
2815 if (!NT_STATUS_IS_OK(result))
2818 /* Get domain policy handle */
2820 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
2821 MAXIMUM_ALLOWED_ACCESS,
2822 domain_sid, &domain_pol);
2824 if (!NT_STATUS_IS_OK(result))
2827 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, 1000,
2828 1, argv, &num_rids, &rids, &rid_types);
2830 if (!NT_STATUS_IS_OK(result)) {
2832 /* Ok, did not find it in the global sam, try with builtin */
2834 DOM_SID sid_Builtin;
2836 rpccli_samr_close(pipe_hnd, mem_ctx, &domain_pol);
2838 string_to_sid(&sid_Builtin, "S-1-5-32");
2840 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
2841 MAXIMUM_ALLOWED_ACCESS,
2842 &sid_Builtin, &domain_pol);
2844 if (!NT_STATUS_IS_OK(result)) {
2845 d_fprintf(stderr, "Couldn't find group %s\n", argv[0]);
2849 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, 1000,
2853 if (!NT_STATUS_IS_OK(result)) {
2854 d_fprintf(stderr, "Couldn't find group %s\n", argv[0]);
2859 if (num_rids != 1) {
2860 d_fprintf(stderr, "Couldn't find group %s\n", argv[0]);
2864 if (rid_types[0] == SID_NAME_DOM_GRP) {
2865 return rpc_list_group_members(pipe_hnd, mem_ctx, domain_name,
2866 domain_sid, &domain_pol,
2870 if (rid_types[0] == SID_NAME_ALIAS) {
2871 return rpc_list_alias_members(pipe_hnd, mem_ctx, &domain_pol,
2875 return NT_STATUS_NO_SUCH_GROUP;
2878 static int rpc_group_members(int argc, const char **argv)
2881 return rpc_group_usage(argc, argv);
2884 return run_rpc_command(NULL, PI_SAMR, 0,
2885 rpc_group_members_internals,
2889 static NTSTATUS rpc_group_rename_internals(const DOM_SID *domain_sid,
2890 const char *domain_name,
2891 struct cli_state *cli,
2892 struct rpc_pipe_client *pipe_hnd,
2893 TALLOC_CTX *mem_ctx,
2898 POLICY_HND connect_pol, domain_pol, group_pol;
2899 uint32 num_rids, *rids, *rid_types;
2903 d_printf("Usage: 'net rpc group rename group newname'\n");
2904 return NT_STATUS_UNSUCCESSFUL;
2907 /* Get sam policy handle */
2909 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
2912 if (!NT_STATUS_IS_OK(result))
2915 /* Get domain policy handle */
2917 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
2918 MAXIMUM_ALLOWED_ACCESS,
2919 domain_sid, &domain_pol);
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 (num_rids != 1) {
2928 d_fprintf(stderr, "Couldn't find group %s\n", argv[0]);
2932 if (rid_types[0] != SID_NAME_DOM_GRP) {
2933 d_fprintf(stderr, "Can only rename domain groups\n");
2934 return NT_STATUS_UNSUCCESSFUL;
2937 result = rpccli_samr_open_group(pipe_hnd, mem_ctx, &domain_pol,
2938 MAXIMUM_ALLOWED_ACCESS,
2939 rids[0], &group_pol);
2941 if (!NT_STATUS_IS_OK(result))
2946 ctr.switch_value1 = 2;
2947 init_samr_group_info2(&ctr.group.info2, argv[1]);
2949 result = rpccli_samr_set_groupinfo(pipe_hnd, mem_ctx, &group_pol, &ctr);
2951 if (!NT_STATUS_IS_OK(result))
2954 return NT_STATUS_NO_SUCH_GROUP;
2957 static int rpc_group_rename(int argc, const char **argv)
2960 return rpc_group_usage(argc, argv);
2963 return run_rpc_command(NULL, PI_SAMR, 0,
2964 rpc_group_rename_internals,
2969 * 'net rpc group' entrypoint.
2970 * @param argc Standard main() style argc
2971 * @param argc Standard main() style argv. Initial components are already
2975 int net_rpc_group(int argc, const char **argv)
2977 struct functable func[] = {
2978 {"add", rpc_group_add},
2979 {"delete", rpc_group_delete},
2980 {"addmem", rpc_group_addmem},
2981 {"delmem", rpc_group_delmem},
2982 {"list", rpc_group_list},
2983 {"members", rpc_group_members},
2984 {"rename", rpc_group_rename},
2989 return run_rpc_command(NULL, PI_SAMR, 0,
2990 rpc_group_list_internals,
2994 return net_run_function(argc, argv, func, rpc_group_usage);
2997 /****************************************************************************/
2999 static int rpc_share_usage(int argc, const char **argv)
3001 return net_help_share(argc, argv);
3005 * Add a share on a remote RPC server
3007 * All parameters are provided by the run_rpc_command function, except for
3008 * argc, argv which are passes through.
3010 * @param domain_sid The domain sid acquired from the remote server
3011 * @param cli A cli_state connected to the server.
3012 * @param mem_ctx Talloc context, destoyed on completion of the function.
3013 * @param argc Standard main() style argc
3014 * @param argv Standard main() style argv. Initial components are already
3017 * @return Normal NTSTATUS return.
3019 static NTSTATUS rpc_share_add_internals(const DOM_SID *domain_sid,
3020 const char *domain_name,
3021 struct cli_state *cli,
3022 struct rpc_pipe_client *pipe_hnd,
3023 TALLOC_CTX *mem_ctx,int argc,
3029 uint32 type = STYPE_DISKTREE; /* only allow disk shares to be added */
3030 uint32 num_users=0, perms=0;
3031 char *password=NULL; /* don't allow a share password */
3034 if ((sharename = talloc_strdup(mem_ctx, argv[0])) == NULL) {
3035 return NT_STATUS_NO_MEMORY;
3038 path = strchr(sharename, '=');
3040 return NT_STATUS_UNSUCCESSFUL;
3043 result = rpccli_srvsvc_net_share_add(pipe_hnd, mem_ctx, sharename, type,
3044 opt_comment, perms, opt_maxusers,
3045 num_users, path, password,
3047 return werror_to_ntstatus(result);
3050 static int rpc_share_add(int argc, const char **argv)
3052 if ((argc < 1) || !strchr(argv[0], '=')) {
3053 DEBUG(1,("Sharename or path not specified on add\n"));
3054 return rpc_share_usage(argc, argv);
3056 return run_rpc_command(NULL, PI_SRVSVC, 0,
3057 rpc_share_add_internals,
3062 * Delete a share on a remote RPC server
3064 * All parameters are provided by the run_rpc_command function, except for
3065 * argc, argv which are passes through.
3067 * @param domain_sid The domain sid acquired from the remote server
3068 * @param cli A cli_state connected to the server.
3069 * @param mem_ctx Talloc context, destoyed on completion of the function.
3070 * @param argc Standard main() style argc
3071 * @param argv Standard main() style argv. Initial components are already
3074 * @return Normal NTSTATUS return.
3076 static NTSTATUS rpc_share_del_internals(const DOM_SID *domain_sid,
3077 const char *domain_name,
3078 struct cli_state *cli,
3079 struct rpc_pipe_client *pipe_hnd,
3080 TALLOC_CTX *mem_ctx,
3086 result = rpccli_srvsvc_net_share_del(pipe_hnd, mem_ctx, argv[0]);
3087 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
3091 * Delete a share on a remote RPC server
3093 * @param domain_sid The domain sid acquired from the remote server
3094 * @param argc Standard main() style argc
3095 * @param argv Standard main() style argv. Initial components are already
3098 * @return A shell status integer (0 for success)
3100 static int rpc_share_delete(int argc, const char **argv)
3103 DEBUG(1,("Sharename not specified on delete\n"));
3104 return rpc_share_usage(argc, argv);
3106 return run_rpc_command(NULL, PI_SRVSVC, 0,
3107 rpc_share_del_internals,
3112 * Formatted print of share info
3114 * @param info1 pointer to SRV_SHARE_INFO_1 to format
3117 static void display_share_info_1(SRV_SHARE_INFO_1 *info1)
3119 fstring netname = "", remark = "";
3121 rpcstr_pull_unistr2_fstring(netname, &info1->info_1_str.uni_netname);
3122 rpcstr_pull_unistr2_fstring(remark, &info1->info_1_str.uni_remark);
3124 if (opt_long_list_entries) {
3125 d_printf("%-12s %-8.8s %-50s\n",
3126 netname, share_type[info1->info_1.type & ~(STYPE_TEMPORARY|STYPE_HIDDEN)], remark);
3128 d_printf("%s\n", netname);
3133 static WERROR get_share_info(struct rpc_pipe_client *pipe_hnd,
3134 TALLOC_CTX *mem_ctx,
3138 SRV_SHARE_INFO_CTR *ctr)
3141 SRV_SHARE_INFO info;
3143 /* no specific share requested, enumerate all */
3147 uint32 preferred_len = 0xffffffff;
3149 init_enum_hnd(&hnd, 0);
3151 return rpccli_srvsvc_net_share_enum(pipe_hnd, mem_ctx, level, ctr,
3152 preferred_len, &hnd);
3155 /* request just one share */
3156 result = rpccli_srvsvc_net_share_get_info(pipe_hnd, mem_ctx, argv[0], level, &info);
3158 if (!W_ERROR_IS_OK(result))
3164 ctr->info_level = ctr->switch_value = level;
3165 ctr->ptr_share_info = ctr->ptr_entries = 1;
3166 ctr->num_entries = ctr->num_entries2 = 1;
3172 SRV_SHARE_INFO_1 *info1;
3174 ctr->share.info1 = TALLOC_ARRAY(mem_ctx, SRV_SHARE_INFO_1, 1);
3175 if (ctr->share.info1 == NULL) {
3176 result = WERR_NOMEM;
3179 info1 = ctr->share.info1;
3181 memset(ctr->share.info1, 0, sizeof(SRV_SHARE_INFO_1));
3183 /* Copy pointer crap */
3185 memcpy(&info1->info_1, &info.share.info1.info_1, sizeof(SH_INFO_1));
3187 /* Duplicate strings */
3189 s = unistr2_to_ascii_talloc(mem_ctx, &info.share.info1.info_1_str.uni_netname);
3191 init_unistr2(&info1->info_1_str.uni_netname, s, UNI_STR_TERMINATE);
3193 s = unistr2_to_ascii_talloc(mem_ctx, &info.share.info1.info_1_str.uni_remark);
3195 init_unistr2(&info1->info_1_str.uni_remark, s, UNI_STR_TERMINATE);
3200 SRV_SHARE_INFO_2 *info2;
3202 ctr->share.info2 = TALLOC_ARRAY(mem_ctx, SRV_SHARE_INFO_2, 1);
3203 if (ctr->share.info2 == NULL) {
3204 result = WERR_NOMEM;
3207 info2 = ctr->share.info2;
3209 memset(ctr->share.info2, 0, sizeof(SRV_SHARE_INFO_2));
3211 /* Copy pointer crap */
3213 memcpy(&info2->info_2, &info.share.info2.info_2, sizeof(SH_INFO_2));
3215 /* Duplicate strings */
3217 s = unistr2_to_ascii_talloc(mem_ctx, &info.share.info2.info_2_str.uni_netname);
3219 init_unistr2(&info2->info_2_str.uni_netname, s, UNI_STR_TERMINATE);
3221 s = unistr2_to_ascii_talloc(mem_ctx, &info.share.info2.info_2_str.uni_remark);
3223 init_unistr2(&info2->info_2_str.uni_remark, s, UNI_STR_TERMINATE);
3225 s = unistr2_to_ascii_talloc(mem_ctx, &info.share.info2.info_2_str.uni_path);
3227 init_unistr2(&info2->info_2_str.uni_path, s, UNI_STR_TERMINATE);
3229 s = unistr2_to_ascii_talloc(mem_ctx, &info.share.info2.info_2_str.uni_passwd);
3231 init_unistr2(&info2->info_2_str.uni_passwd, s, UNI_STR_TERMINATE);
3236 SRV_SHARE_INFO_502 *info502;
3238 ctr->share.info502 = TALLOC_ARRAY(mem_ctx, SRV_SHARE_INFO_502, 1);
3239 if (ctr->share.info502 == NULL) {
3240 result = WERR_NOMEM;
3243 info502 = ctr->share.info502;
3245 memset(ctr->share.info502, 0, sizeof(SRV_SHARE_INFO_502));
3247 /* Copy pointer crap */
3249 memcpy(&info502->info_502, &info.share.info502.info_502, sizeof(SH_INFO_502));
3251 /* Duplicate strings */
3253 s = unistr2_to_ascii_talloc(mem_ctx, &info.share.info502.info_502_str.uni_netname);
3255 init_unistr2(&info502->info_502_str.uni_netname, s, UNI_STR_TERMINATE);
3257 s = unistr2_to_ascii_talloc(mem_ctx, &info.share.info502.info_502_str.uni_remark);
3259 init_unistr2(&info502->info_502_str.uni_remark, s, UNI_STR_TERMINATE);
3261 s = unistr2_to_ascii_talloc(mem_ctx, &info.share.info502.info_502_str.uni_path);
3263 init_unistr2(&info502->info_502_str.uni_path, s, UNI_STR_TERMINATE);
3265 s = unistr2_to_ascii_talloc(mem_ctx, &info.share.info502.info_502_str.uni_passwd);
3267 init_unistr2(&info502->info_502_str.uni_passwd, s, UNI_STR_TERMINATE);
3269 info502->info_502_str.sd = dup_sec_desc(mem_ctx, info.share.info502.info_502_str.sd);
3280 * List shares on a remote RPC server
3282 * All parameters are provided by the run_rpc_command function, except for
3283 * argc, argv which are passes through.
3285 * @param domain_sid The domain sid acquired from the remote server
3286 * @param cli A cli_state connected to the server.
3287 * @param mem_ctx Talloc context, destoyed on completion of the function.
3288 * @param argc Standard main() style argc
3289 * @param argv Standard main() style argv. Initial components are already
3292 * @return Normal NTSTATUS return.
3295 static NTSTATUS rpc_share_list_internals(const DOM_SID *domain_sid,
3296 const char *domain_name,
3297 struct cli_state *cli,
3298 struct rpc_pipe_client *pipe_hnd,
3299 TALLOC_CTX *mem_ctx,
3303 SRV_SHARE_INFO_CTR ctr;
3305 uint32 i, level = 1;
3307 result = get_share_info(pipe_hnd, mem_ctx, level, argc, argv, &ctr);
3308 if (!W_ERROR_IS_OK(result))
3311 /* Display results */
3313 if (opt_long_list_entries) {
3315 "\nEnumerating shared resources (exports) on remote server:\n\n"\
3316 "\nShare name Type Description\n"\
3317 "---------- ---- -----------\n");
3319 for (i = 0; i < ctr.num_entries; i++)
3320 display_share_info_1(&ctr.share.info1[i]);
3322 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
3326 * 'net rpc share list' entrypoint.
3327 * @param argc Standard main() style argc
3328 * @param argv Standard main() style argv. Initial components are already
3331 static int rpc_share_list(int argc, const char **argv)
3333 return run_rpc_command(NULL, PI_SRVSVC, 0, rpc_share_list_internals, argc, argv);
3336 static bool check_share_availability(struct cli_state *cli, const char *netname)
3338 if (!cli_send_tconX(cli, netname, "A:", "", 0)) {
3339 d_printf("skipping [%s]: not a file share.\n", netname);
3349 static bool check_share_sanity(struct cli_state *cli, fstring netname, uint32 type)
3351 /* only support disk shares */
3352 if (! ( type == STYPE_DISKTREE || type == (STYPE_DISKTREE | STYPE_HIDDEN)) ) {
3353 printf("share [%s] is not a diskshare (type: %x)\n", netname, type);
3357 /* skip builtin shares */
3358 /* FIXME: should print$ be added too ? */
3359 if (strequal(netname,"IPC$") || strequal(netname,"ADMIN$") ||
3360 strequal(netname,"global"))
3363 if (opt_exclude && in_list(netname, opt_exclude, False)) {
3364 printf("excluding [%s]\n", netname);
3368 return check_share_availability(cli, netname);
3372 * Migrate shares from a remote RPC server to the local RPC srever
3374 * All parameters are provided by the run_rpc_command function, except for
3375 * argc, argv which are passes through.
3377 * @param domain_sid The domain sid acquired from the remote server
3378 * @param cli A cli_state connected to the server.
3379 * @param mem_ctx Talloc context, destoyed on completion of the function.
3380 * @param argc Standard main() style argc
3381 * @param argv Standard main() style argv. Initial components are already
3384 * @return Normal NTSTATUS return.
3387 static NTSTATUS rpc_share_migrate_shares_internals(const DOM_SID *domain_sid,
3388 const char *domain_name,
3389 struct cli_state *cli,
3390 struct rpc_pipe_client *pipe_hnd,
3391 TALLOC_CTX *mem_ctx,
3396 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
3397 SRV_SHARE_INFO_CTR ctr_src;
3398 uint32 type = STYPE_DISKTREE; /* only allow disk shares to be added */
3399 char *password = NULL; /* don't allow a share password */
3401 struct rpc_pipe_client *srvsvc_pipe = NULL;
3402 struct cli_state *cli_dst = NULL;
3403 uint32 level = 502; /* includes secdesc */
3405 result = get_share_info(pipe_hnd, mem_ctx, level, argc, argv, &ctr_src);
3406 if (!W_ERROR_IS_OK(result))
3409 /* connect destination PI_SRVSVC */
3410 nt_status = connect_dst_pipe(&cli_dst, &srvsvc_pipe, PI_SRVSVC);
3411 if (!NT_STATUS_IS_OK(nt_status))
3415 for (i = 0; i < ctr_src.num_entries; i++) {
3417 fstring netname = "", remark = "", path = "";
3418 /* reset error-code */
3419 nt_status = NT_STATUS_UNSUCCESSFUL;
3421 rpcstr_pull_unistr2_fstring(
3422 netname, &ctr_src.share.info502[i].info_502_str.uni_netname);
3423 rpcstr_pull_unistr2_fstring(
3424 remark, &ctr_src.share.info502[i].info_502_str.uni_remark);
3425 rpcstr_pull_unistr2_fstring(
3426 path, &ctr_src.share.info502[i].info_502_str.uni_path);
3428 if (!check_share_sanity(cli, netname, ctr_src.share.info502[i].info_502.type))
3431 /* finally add the share on the dst server */
3433 printf("migrating: [%s], path: %s, comment: %s, without share-ACLs\n",
3434 netname, path, remark);
3436 result = rpccli_srvsvc_net_share_add(srvsvc_pipe, mem_ctx, netname, type, remark,
3437 ctr_src.share.info502[i].info_502.perms,
3438 ctr_src.share.info502[i].info_502.max_uses,
3439 ctr_src.share.info502[i].info_502.num_uses,
3440 path, password, level,
3443 if (W_ERROR_V(result) == W_ERROR_V(WERR_ALREADY_EXISTS)) {
3444 printf(" [%s] does already exist\n", netname);
3448 if (!W_ERROR_IS_OK(result)) {
3449 printf("cannot add share: %s\n", dos_errstr(result));
3455 nt_status = NT_STATUS_OK;
3459 cli_shutdown(cli_dst);
3467 * Migrate shares from a rpc-server to another
3469 * @param argc Standard main() style argc
3470 * @param argv Standard main() style argv. Initial components are already
3473 * @return A shell status integer (0 for success)
3475 static int rpc_share_migrate_shares(int argc, const char **argv)
3479 printf("no server to migrate\n");
3483 return run_rpc_command(NULL, PI_SRVSVC, 0,
3484 rpc_share_migrate_shares_internals,
3491 * @param f file_info
3492 * @param mask current search mask
3493 * @param state arg-pointer
3496 static void copy_fn(const char *mnt, file_info *f, const char *mask, void *state)
3498 static NTSTATUS nt_status;
3499 static struct copy_clistate *local_state;
3500 static fstring filename, new_mask;
3504 local_state = (struct copy_clistate *)state;
3505 nt_status = NT_STATUS_UNSUCCESSFUL;
3507 if (strequal(f->name, ".") || strequal(f->name, ".."))
3510 DEBUG(3,("got mask: %s, name: %s\n", mask, f->name));
3513 if (f->mode & aDIR) {
3515 DEBUG(3,("got dir: %s\n", f->name));
3517 fstrcpy(dir, local_state->cwd);
3519 fstrcat(dir, f->name);
3521 switch (net_mode_share)
3523 case NET_MODE_SHARE_MIGRATE:
3524 /* create that directory */
3525 nt_status = net_copy_file(local_state->mem_ctx,
3526 local_state->cli_share_src,
3527 local_state->cli_share_dst,
3529 opt_acls? True : False,
3530 opt_attrs? True : False,
3531 opt_timestamps? True : False,
3535 d_fprintf(stderr, "Unsupported mode %d\n", net_mode_share);
3539 if (!NT_STATUS_IS_OK(nt_status))
3540 printf("could not handle dir %s: %s\n",
3541 dir, nt_errstr(nt_status));
3543 /* search below that directory */
3544 fstrcpy(new_mask, dir);
3545 fstrcat(new_mask, "\\*");
3547 old_dir = local_state->cwd;
3548 local_state->cwd = dir;
3549 if (!sync_files(local_state, new_mask))
3550 printf("could not handle files\n");
3551 local_state->cwd = old_dir;
3558 fstrcpy(filename, local_state->cwd);
3559 fstrcat(filename, "\\");
3560 fstrcat(filename, f->name);
3562 DEBUG(3,("got file: %s\n", filename));
3564 switch (net_mode_share)
3566 case NET_MODE_SHARE_MIGRATE:
3567 nt_status = net_copy_file(local_state->mem_ctx,
3568 local_state->cli_share_src,
3569 local_state->cli_share_dst,
3571 opt_acls? True : False,
3572 opt_attrs? True : False,
3573 opt_timestamps? True: False,
3577 d_fprintf(stderr, "Unsupported file mode %d\n", net_mode_share);
3581 if (!NT_STATUS_IS_OK(nt_status))
3582 printf("could not handle file %s: %s\n",
3583 filename, nt_errstr(nt_status));
3588 * sync files, can be called recursivly to list files
3589 * and then call copy_fn for each file
3591 * @param cp_clistate pointer to the copy_clistate we work with
3592 * @param mask the current search mask
3594 * @return Boolean result
3596 static bool sync_files(struct copy_clistate *cp_clistate, const char *mask)
3598 struct cli_state *targetcli;
3599 char *targetpath = NULL;
3601 DEBUG(3,("calling cli_list with mask: %s\n", mask));
3603 if ( !cli_resolve_path(talloc_tos(), "", cp_clistate->cli_share_src,
3604 mask, &targetcli, &targetpath ) ) {
3605 d_fprintf(stderr, "cli_resolve_path %s failed with error: %s\n",
3606 mask, cli_errstr(cp_clistate->cli_share_src));
3610 if (cli_list(targetcli, targetpath, cp_clistate->attribute, copy_fn, cp_clistate) == -1) {
3611 d_fprintf(stderr, "listing %s failed with error: %s\n",
3612 mask, cli_errstr(targetcli));
3621 * Set the top level directory permissions before we do any further copies.
3622 * Should set up ACL inheritance.
3625 bool copy_top_level_perms(struct copy_clistate *cp_clistate,
3626 const char *sharename)
3628 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
3630 switch (net_mode_share) {
3631 case NET_MODE_SHARE_MIGRATE:
3632 DEBUG(3,("calling net_copy_fileattr for '.' directory in share %s\n", sharename));
3633 nt_status = net_copy_fileattr(cp_clistate->mem_ctx,
3634 cp_clistate->cli_share_src,
3635 cp_clistate->cli_share_dst,
3637 opt_acls? True : False,
3638 opt_attrs? True : False,
3639 opt_timestamps? True: False,
3643 d_fprintf(stderr, "Unsupported mode %d\n", net_mode_share);
3647 if (!NT_STATUS_IS_OK(nt_status)) {
3648 printf("Could handle directory attributes for top level directory of share %s. Error %s\n",
3649 sharename, nt_errstr(nt_status));
3657 * Sync all files inside a remote share to another share (over smb)
3659 * All parameters are provided by the run_rpc_command function, except for
3660 * argc, argv which are passes through.
3662 * @param domain_sid The domain sid acquired from the remote server
3663 * @param cli A cli_state connected to the server.
3664 * @param mem_ctx Talloc context, destoyed on completion of the function.
3665 * @param argc Standard main() style argc
3666 * @param argv Standard main() style argv. Initial components are already
3669 * @return Normal NTSTATUS return.
3672 static NTSTATUS rpc_share_migrate_files_internals(const DOM_SID *domain_sid,
3673 const char *domain_name,
3674 struct cli_state *cli,
3675 struct rpc_pipe_client *pipe_hnd,
3676 TALLOC_CTX *mem_ctx,
3681 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
3682 SRV_SHARE_INFO_CTR ctr_src;
3685 struct copy_clistate cp_clistate;
3686 bool got_src_share = False;
3687 bool got_dst_share = False;
3688 const char *mask = "\\*";
3691 dst = SMB_STRDUP(opt_destination?opt_destination:"127.0.0.1");
3693 result = get_share_info(pipe_hnd, mem_ctx, level, argc, argv, &ctr_src);
3695 if (!W_ERROR_IS_OK(result))
3698 for (i = 0; i < ctr_src.num_entries; i++) {
3700 fstring netname = "";
3702 rpcstr_pull_unistr2_fstring(
3703 netname, &ctr_src.share.info502[i].info_502_str.uni_netname);
3705 if (!check_share_sanity(cli, netname, ctr_src.share.info502[i].info_502.type))
3708 /* one might not want to mirror whole discs :) */
3709 if (strequal(netname, "print$") || netname[1] == '$') {
3710 d_printf("skipping [%s]: builtin/hidden share\n", netname);
3714 switch (net_mode_share)
3716 case NET_MODE_SHARE_MIGRATE:
3720 d_fprintf(stderr, "Unsupported mode %d\n", net_mode_share);
3723 printf(" [%s] files and directories %s ACLs, %s DOS Attributes %s\n",
3725 opt_acls ? "including" : "without",
3726 opt_attrs ? "including" : "without",
3727 opt_timestamps ? "(preserving timestamps)" : "");
3729 cp_clistate.mem_ctx = mem_ctx;
3730 cp_clistate.cli_share_src = NULL;
3731 cp_clistate.cli_share_dst = NULL;
3732 cp_clistate.cwd = NULL;
3733 cp_clistate.attribute = aSYSTEM | aHIDDEN | aDIR;
3735 /* open share source */
3736 nt_status = connect_to_service(&cp_clistate.cli_share_src,
3737 &cli->dest_ss, cli->desthost,
3739 if (!NT_STATUS_IS_OK(nt_status))
3742 got_src_share = True;
3744 if (net_mode_share == NET_MODE_SHARE_MIGRATE) {
3745 /* open share destination */
3746 nt_status = connect_to_service(&cp_clistate.cli_share_dst,
3747 NULL, dst, netname, "A:");
3748 if (!NT_STATUS_IS_OK(nt_status))
3751 got_dst_share = True;
3754 if (!copy_top_level_perms(&cp_clistate, netname)) {
3755 d_fprintf(stderr, "Could not handle the top level directory permissions for the share: %s\n", netname);
3756 nt_status = NT_STATUS_UNSUCCESSFUL;
3760 if (!sync_files(&cp_clistate, mask)) {
3761 d_fprintf(stderr, "could not handle files for share: %s\n", netname);
3762 nt_status = NT_STATUS_UNSUCCESSFUL;
3767 nt_status = NT_STATUS_OK;
3772 cli_shutdown(cp_clistate.cli_share_src);
3775 cli_shutdown(cp_clistate.cli_share_dst);
3781 static int rpc_share_migrate_files(int argc, const char **argv)
3785 printf("no server to migrate\n");
3789 return run_rpc_command(NULL, PI_SRVSVC, 0,
3790 rpc_share_migrate_files_internals,
3795 * Migrate share-ACLs from a remote RPC server to the local RPC srever
3797 * All parameters are provided by the run_rpc_command function, except for
3798 * argc, argv which are passes through.
3800 * @param domain_sid The domain sid acquired from the remote server
3801 * @param cli A cli_state connected to the server.
3802 * @param mem_ctx Talloc context, destoyed on completion of the function.
3803 * @param argc Standard main() style argc
3804 * @param argv Standard main() style argv. Initial components are already
3807 * @return Normal NTSTATUS return.
3810 static NTSTATUS rpc_share_migrate_security_internals(const DOM_SID *domain_sid,
3811 const char *domain_name,
3812 struct cli_state *cli,
3813 struct rpc_pipe_client *pipe_hnd,
3814 TALLOC_CTX *mem_ctx,
3819 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
3820 SRV_SHARE_INFO_CTR ctr_src;
3821 SRV_SHARE_INFO info;
3823 struct rpc_pipe_client *srvsvc_pipe = NULL;
3824 struct cli_state *cli_dst = NULL;
3825 uint32 level = 502; /* includes secdesc */
3827 result = get_share_info(pipe_hnd, mem_ctx, level, argc, argv, &ctr_src);
3829 if (!W_ERROR_IS_OK(result))
3832 /* connect destination PI_SRVSVC */
3833 nt_status = connect_dst_pipe(&cli_dst, &srvsvc_pipe, PI_SRVSVC);
3834 if (!NT_STATUS_IS_OK(nt_status))
3838 for (i = 0; i < ctr_src.num_entries; i++) {
3840 fstring netname = "", remark = "", path = "";
3841 /* reset error-code */
3842 nt_status = NT_STATUS_UNSUCCESSFUL;
3844 rpcstr_pull_unistr2_fstring(
3845 netname, &ctr_src.share.info502[i].info_502_str.uni_netname);
3846 rpcstr_pull_unistr2_fstring(
3847 remark, &ctr_src.share.info502[i].info_502_str.uni_remark);
3848 rpcstr_pull_unistr2_fstring(
3849 path, &ctr_src.share.info502[i].info_502_str.uni_path);
3851 if (!check_share_sanity(cli, netname, ctr_src.share.info502[i].info_502.type))
3854 printf("migrating: [%s], path: %s, comment: %s, including share-ACLs\n",
3855 netname, path, remark);
3858 display_sec_desc(ctr_src.share.info502[i].info_502_str.sd);
3863 info.switch_value = level;
3864 info.ptr_share_ctr = 1;
3866 /* FIXME: shouldn't we be able to just set the security descriptor ? */
3867 info.share.info502 = ctr_src.share.info502[i];
3869 /* finally modify the share on the dst server */
3870 result = rpccli_srvsvc_net_share_set_info(srvsvc_pipe, mem_ctx, netname, level, &info);
3872 if (!W_ERROR_IS_OK(result)) {
3873 printf("cannot set share-acl: %s\n", dos_errstr(result));
3879 nt_status = NT_STATUS_OK;
3883 cli_shutdown(cli_dst);
3891 * Migrate share-acls from a rpc-server to another
3893 * @param argc Standard main() style argc
3894 * @param argv Standard main() style argv. Initial components are already
3897 * @return A shell status integer (0 for success)
3899 static int rpc_share_migrate_security(int argc, const char **argv)
3903 printf("no server to migrate\n");
3907 return run_rpc_command(NULL, PI_SRVSVC, 0,
3908 rpc_share_migrate_security_internals,
3913 * Migrate shares (including share-definitions, share-acls and files with acls/attrs)
3914 * from one server to another
3916 * @param argc Standard main() style argc
3917 * @param argv Standard main() style argv. Initial components are already
3920 * @return A shell status integer (0 for success)
3923 static int rpc_share_migrate_all(int argc, const char **argv)
3928 printf("no server to migrate\n");
3932 /* order is important. we don't want to be locked out by the share-acl
3933 * before copying files - gd */
3935 ret = run_rpc_command(NULL, PI_SRVSVC, 0, rpc_share_migrate_shares_internals, argc, argv);
3939 ret = run_rpc_command(NULL, PI_SRVSVC, 0, rpc_share_migrate_files_internals, argc, argv);
3943 return run_rpc_command(NULL, PI_SRVSVC, 0, rpc_share_migrate_security_internals, argc, argv);
3948 * 'net rpc share migrate' entrypoint.
3949 * @param argc Standard main() style argc
3950 * @param argv Standard main() style argv. Initial components are already
3953 static int rpc_share_migrate(int argc, const char **argv)
3956 struct functable func[] = {
3957 {"all", rpc_share_migrate_all},
3958 {"files", rpc_share_migrate_files},
3959 {"help", rpc_share_usage},
3960 {"security", rpc_share_migrate_security},
3961 {"shares", rpc_share_migrate_shares},
3965 net_mode_share = NET_MODE_SHARE_MIGRATE;
3967 return net_run_function(argc, argv, func, rpc_share_usage);
3976 static int num_server_aliases;
3977 static struct full_alias *server_aliases;
3980 * Add an alias to the static list.
3982 static void push_alias(TALLOC_CTX *mem_ctx, struct full_alias *alias)
3984 if (server_aliases == NULL)
3985 server_aliases = SMB_MALLOC_ARRAY(struct full_alias, 100);
3987 server_aliases[num_server_aliases] = *alias;
3988 num_server_aliases += 1;
3992 * For a specific domain on the server, fetch all the aliases
3993 * and their members. Add all of them to the server_aliases.
3996 static NTSTATUS rpc_fetch_domain_aliases(struct rpc_pipe_client *pipe_hnd,
3997 TALLOC_CTX *mem_ctx,
3998 POLICY_HND *connect_pol,
3999 const DOM_SID *domain_sid)
4001 uint32 start_idx, max_entries, num_entries, i;
4002 struct acct_info *groups;
4004 POLICY_HND domain_pol;
4006 /* Get domain policy handle */
4008 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, connect_pol,
4009 MAXIMUM_ALLOWED_ACCESS,
4010 domain_sid, &domain_pol);
4011 if (!NT_STATUS_IS_OK(result))
4018 result = rpccli_samr_enum_als_groups(pipe_hnd, mem_ctx, &domain_pol,
4019 &start_idx, max_entries,
4020 &groups, &num_entries);
4022 for (i = 0; i < num_entries; i++) {
4024 POLICY_HND alias_pol;
4025 struct full_alias alias;
4029 result = rpccli_samr_open_alias(pipe_hnd, mem_ctx, &domain_pol,
4030 MAXIMUM_ALLOWED_ACCESS,
4033 if (!NT_STATUS_IS_OK(result))
4036 result = rpccli_samr_query_aliasmem(pipe_hnd, mem_ctx,
4040 if (!NT_STATUS_IS_OK(result))
4043 result = rpccli_samr_close(pipe_hnd, mem_ctx, &alias_pol);
4044 if (!NT_STATUS_IS_OK(result))
4047 alias.members = NULL;
4049 if (alias.num_members > 0) {
4050 alias.members = SMB_MALLOC_ARRAY(DOM_SID, alias.num_members);
4052 for (j = 0; j < alias.num_members; j++)
4053 sid_copy(&alias.members[j],
4057 sid_copy(&alias.sid, domain_sid);
4058 sid_append_rid(&alias.sid, groups[i].rid);
4060 push_alias(mem_ctx, &alias);
4062 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
4064 result = NT_STATUS_OK;
4067 rpccli_samr_close(pipe_hnd, mem_ctx, &domain_pol);
4073 * Dump server_aliases as names for debugging purposes.
4076 static NTSTATUS rpc_aliaslist_dump(const DOM_SID *domain_sid,
4077 const char *domain_name,
4078 struct cli_state *cli,
4079 struct rpc_pipe_client *pipe_hnd,
4080 TALLOC_CTX *mem_ctx,
4088 result = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, True,
4089 SEC_RIGHTS_MAXIMUM_ALLOWED,
4091 if (!NT_STATUS_IS_OK(result))
4094 for (i=0; i<num_server_aliases; i++) {
4097 enum lsa_SidType *types;
4100 struct full_alias *alias = &server_aliases[i];
4102 result = rpccli_lsa_lookup_sids(pipe_hnd, mem_ctx, &lsa_pol, 1,
4104 &domains, &names, &types);
4105 if (!NT_STATUS_IS_OK(result))
4108 DEBUG(1, ("%s\\%s %d: ", domains[0], names[0], types[0]));
4110 if (alias->num_members == 0) {
4115 result = rpccli_lsa_lookup_sids(pipe_hnd, mem_ctx, &lsa_pol,
4118 &domains, &names, &types);
4120 if (!NT_STATUS_IS_OK(result) &&
4121 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
4124 for (j=0; j<alias->num_members; j++)
4125 DEBUG(1, ("%s\\%s (%d); ",
4126 domains[j] ? domains[j] : "*unknown*",
4127 names[j] ? names[j] : "*unknown*",types[j]));
4131 rpccli_lsa_Close(pipe_hnd, mem_ctx, &lsa_pol);
4133 return NT_STATUS_OK;
4137 * Fetch a list of all server aliases and their members into
4141 static NTSTATUS rpc_aliaslist_internals(const DOM_SID *domain_sid,
4142 const char *domain_name,
4143 struct cli_state *cli,
4144 struct rpc_pipe_client *pipe_hnd,
4145 TALLOC_CTX *mem_ctx,
4150 POLICY_HND connect_pol;
4152 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
4155 if (!NT_STATUS_IS_OK(result))
4158 result = rpc_fetch_domain_aliases(pipe_hnd, mem_ctx, &connect_pol,
4159 &global_sid_Builtin);
4161 if (!NT_STATUS_IS_OK(result))
4164 result = rpc_fetch_domain_aliases(pipe_hnd, mem_ctx, &connect_pol,
4167 rpccli_samr_close(pipe_hnd, mem_ctx, &connect_pol);
4172 static void init_user_token(NT_USER_TOKEN *token, DOM_SID *user_sid)
4174 token->num_sids = 4;
4176 if (!(token->user_sids = SMB_MALLOC_ARRAY(DOM_SID, 4))) {
4177 d_fprintf(stderr, "malloc failed\n");
4178 token->num_sids = 0;
4182 token->user_sids[0] = *user_sid;
4183 sid_copy(&token->user_sids[1], &global_sid_World);
4184 sid_copy(&token->user_sids[2], &global_sid_Network);
4185 sid_copy(&token->user_sids[3], &global_sid_Authenticated_Users);
4188 static void free_user_token(NT_USER_TOKEN *token)
4190 SAFE_FREE(token->user_sids);
4193 static bool is_sid_in_token(NT_USER_TOKEN *token, DOM_SID *sid)
4197 for (i=0; i<token->num_sids; i++) {
4198 if (sid_compare(sid, &token->user_sids[i]) == 0)
4204 static void add_sid_to_token(NT_USER_TOKEN *token, DOM_SID *sid)
4206 if (is_sid_in_token(token, sid))
4209 token->user_sids = SMB_REALLOC_ARRAY(token->user_sids, DOM_SID, token->num_sids+1);
4210 if (!token->user_sids) {
4214 sid_copy(&token->user_sids[token->num_sids], sid);
4216 token->num_sids += 1;
4221 NT_USER_TOKEN token;
4224 static void dump_user_token(struct user_token *token)
4228 d_printf("%s\n", token->name);
4230 for (i=0; i<token->token.num_sids; i++) {
4231 d_printf(" %s\n", sid_string_tos(&token->token.user_sids[i]));
4235 static bool is_alias_member(DOM_SID *sid, struct full_alias *alias)
4239 for (i=0; i<alias->num_members; i++) {
4240 if (sid_compare(sid, &alias->members[i]) == 0)
4247 static void collect_sid_memberships(NT_USER_TOKEN *token, DOM_SID sid)
4251 for (i=0; i<num_server_aliases; i++) {
4252 if (is_alias_member(&sid, &server_aliases[i]))
4253 add_sid_to_token(token, &server_aliases[i].sid);
4258 * We got a user token with all the SIDs we can know about without asking the
4259 * server directly. These are the user and domain group sids. All of these can
4260 * be members of aliases. So scan the list of aliases for each of the SIDs and
4261 * add them to the token.
4264 static void collect_alias_memberships(NT_USER_TOKEN *token)
4266 int num_global_sids = token->num_sids;
4269 for (i=0; i<num_global_sids; i++) {
4270 collect_sid_memberships(token, token->user_sids[i]);
4274 static bool get_user_sids(const char *domain, const char *user, NT_USER_TOKEN *token)
4276 struct winbindd_request request;
4277 struct winbindd_response response;
4285 fstr_sprintf(full_name, "%s%c%s",
4286 domain, *lp_winbind_separator(), user);
4288 /* First let's find out the user sid */
4290 ZERO_STRUCT(request);
4291 ZERO_STRUCT(response);
4293 fstrcpy(request.data.name.dom_name, domain);
4294 fstrcpy(request.data.name.name, user);
4296 result = winbindd_request_response(WINBINDD_LOOKUPNAME, &request, &response);
4298 if (result != NSS_STATUS_SUCCESS) {
4299 DEBUG(1, ("winbind could not find %s\n", full_name));
4303 if (response.data.sid.type != SID_NAME_USER) {
4304 DEBUG(1, ("%s is not a user\n", full_name));
4308 string_to_sid(&user_sid, response.data.sid.sid);
4310 init_user_token(token, &user_sid);
4312 /* And now the groups winbind knows about */
4314 ZERO_STRUCT(response);
4316 fstrcpy(request.data.username, full_name);
4318 result = winbindd_request_response(WINBINDD_GETGROUPS, &request, &response);
4320 if (result != NSS_STATUS_SUCCESS) {
4321 DEBUG(1, ("winbind could not get groups of %s\n", full_name));
4325 for (i = 0; i < response.data.num_entries; i++) {
4326 gid_t gid = ((gid_t *)response.extra_data.data)[i];
4329 struct winbindd_request sidrequest;
4330 struct winbindd_response sidresponse;
4332 ZERO_STRUCT(sidrequest);
4333 ZERO_STRUCT(sidresponse);
4335 sidrequest.data.gid = gid;
4337 result = winbindd_request_response(WINBINDD_GID_TO_SID,
4338 &sidrequest, &sidresponse);
4340 if (result != NSS_STATUS_SUCCESS) {
4341 DEBUG(1, ("winbind could not find SID of gid %d\n",
4346 DEBUG(3, (" %s\n", sidresponse.data.sid.sid));
4348 string_to_sid(&sid, sidresponse.data.sid.sid);
4349 add_sid_to_token(token, &sid);
4352 SAFE_FREE(response.extra_data.data);
4358 * Get a list of all user tokens we want to look at
4361 static bool get_user_tokens(int *num_tokens, struct user_token **user_tokens)
4363 struct winbindd_request request;
4364 struct winbindd_response response;
4365 const char *extra_data;
4368 struct user_token *result;
4369 TALLOC_CTX *frame = NULL;
4371 if (lp_winbind_use_default_domain() &&
4372 (opt_target_workgroup == NULL)) {
4373 d_fprintf(stderr, "winbind use default domain = yes set, "
4374 "please specify a workgroup\n");
4378 /* Send request to winbind daemon */
4380 ZERO_STRUCT(request);
4381 ZERO_STRUCT(response);
4383 if (winbindd_request_response(WINBINDD_LIST_USERS, &request, &response) !=
4387 /* Look through extra data */
4389 if (!response.extra_data.data)
4392 extra_data = (const char *)response.extra_data.data;
4395 frame = talloc_stackframe();
4396 while(next_token_talloc(frame, &extra_data, &name, ",")) {
4400 result = SMB_MALLOC_ARRAY(struct user_token, *num_tokens);
4402 if (result == NULL) {
4403 DEBUG(1, ("Could not malloc sid array\n"));
4408 extra_data = (const char *)response.extra_data.data;
4411 while(next_token_talloc(frame, &extra_data, &name, ",")) {
4412 fstring domain, user;
4415 fstrcpy(result[i].name, name);
4417 p = strchr(name, *lp_winbind_separator());
4419 DEBUG(3, ("%s\n", name));
4422 fstrcpy(domain, opt_target_workgroup);
4423 fstrcpy(user, name);
4426 fstrcpy(domain, name);
4431 get_user_sids(domain, user, &(result[i].token));
4435 SAFE_FREE(response.extra_data.data);
4437 *user_tokens = result;
4442 static bool get_user_tokens_from_file(FILE *f,
4444 struct user_token **tokens)
4446 struct user_token *token = NULL;
4451 if (fgets(line, sizeof(line)-1, f) == NULL) {
4455 if (line[strlen(line)-1] == '\n')
4456 line[strlen(line)-1] = '\0';
4458 if (line[0] == ' ') {
4462 string_to_sid(&sid, &line[1]);
4464 if (token == NULL) {
4465 DEBUG(0, ("File does not begin with username"));
4469 add_sid_to_token(&token->token, &sid);
4473 /* And a new user... */
4476 *tokens = SMB_REALLOC_ARRAY(*tokens, struct user_token, *num_tokens);
4477 if (*tokens == NULL) {
4478 DEBUG(0, ("Could not realloc tokens\n"));
4482 token = &((*tokens)[*num_tokens-1]);
4484 fstrcpy(token->name, line);
4485 token->token.num_sids = 0;
4486 token->token.user_sids = NULL;
4495 * Show the list of all users that have access to a share
4498 static void show_userlist(struct rpc_pipe_client *pipe_hnd,
4499 TALLOC_CTX *mem_ctx,
4500 const char *netname,
4502 struct user_token *tokens)
4505 SEC_DESC *share_sd = NULL;
4506 SEC_DESC *root_sd = NULL;
4507 struct cli_state *cli = pipe_hnd->cli;
4509 SRV_SHARE_INFO info;
4513 result = rpccli_srvsvc_net_share_get_info(pipe_hnd, mem_ctx, netname,
4516 if (!W_ERROR_IS_OK(result)) {
4517 DEBUG(1, ("Coult not query secdesc for share %s\n",
4522 share_sd = info.share.info502.info_502_str.sd;
4523 if (share_sd == NULL) {
4524 DEBUG(1, ("Got no secdesc for share %s\n",
4530 if (!cli_send_tconX(cli, netname, "A:", "", 0)) {
4534 fnum = cli_nt_create(cli, "\\", READ_CONTROL_ACCESS);
4537 root_sd = cli_query_secdesc(cli, fnum, mem_ctx);
4540 for (i=0; i<num_tokens; i++) {
4544 if (share_sd != NULL) {
4545 if (!se_access_check(share_sd, &tokens[i].token,
4546 1, &acc_granted, &status)) {
4547 DEBUG(1, ("Could not check share_sd for "
4553 if (!NT_STATUS_IS_OK(status))
4557 if (root_sd == NULL) {
4558 d_printf(" %s\n", tokens[i].name);
4562 if (!se_access_check(root_sd, &tokens[i].token,
4563 1, &acc_granted, &status)) {
4564 DEBUG(1, ("Could not check root_sd for user %s\n",
4569 if (!NT_STATUS_IS_OK(status))
4572 d_printf(" %s\n", tokens[i].name);
4576 cli_close(cli, fnum);
4588 static void collect_share(const char *name, uint32 m,
4589 const char *comment, void *state)
4591 struct share_list *share_list = (struct share_list *)state;
4593 if (m != STYPE_DISKTREE)
4596 share_list->num_shares += 1;
4597 share_list->shares = SMB_REALLOC_ARRAY(share_list->shares, char *, share_list->num_shares);
4598 if (!share_list->shares) {
4599 share_list->num_shares = 0;
4602 share_list->shares[share_list->num_shares-1] = SMB_STRDUP(name);
4605 static void rpc_share_userlist_usage(void)
4611 * List shares on a remote RPC server, including the security descriptors
4613 * All parameters are provided by the run_rpc_command function, except for
4614 * argc, argv which are passes through.
4616 * @param domain_sid The domain sid acquired from the remote server
4617 * @param cli A cli_state connected to the server.
4618 * @param mem_ctx Talloc context, destoyed on completion of the function.
4619 * @param argc Standard main() style argc
4620 * @param argv Standard main() style argv. Initial components are already
4623 * @return Normal NTSTATUS return.
4626 static NTSTATUS rpc_share_allowedusers_internals(const DOM_SID *domain_sid,
4627 const char *domain_name,
4628 struct cli_state *cli,
4629 struct rpc_pipe_client *pipe_hnd,
4630 TALLOC_CTX *mem_ctx,
4640 struct user_token *tokens = NULL;
4643 struct share_list share_list;
4646 rpc_share_userlist_usage();
4647 return NT_STATUS_UNSUCCESSFUL;
4653 f = fopen(argv[0], "r");
4657 DEBUG(0, ("Could not open userlist: %s\n", strerror(errno)));
4658 return NT_STATUS_UNSUCCESSFUL;
4661 r = get_user_tokens_from_file(f, &num_tokens, &tokens);
4667 DEBUG(0, ("Could not read users from file\n"));
4668 return NT_STATUS_UNSUCCESSFUL;
4671 for (i=0; i<num_tokens; i++)
4672 collect_alias_memberships(&tokens[i].token);
4674 init_enum_hnd(&hnd, 0);
4676 share_list.num_shares = 0;
4677 share_list.shares = NULL;
4679 ret = cli_RNetShareEnum(cli, collect_share, &share_list);
4682 DEBUG(0, ("Error returning browse list: %s\n",
4687 for (i = 0; i < share_list.num_shares; i++) {
4688 char *netname = share_list.shares[i];
4690 if (netname[strlen(netname)-1] == '$')
4693 d_printf("%s\n", netname);
4695 show_userlist(pipe_hnd, mem_ctx, netname,
4696 num_tokens, tokens);
4699 for (i=0; i<num_tokens; i++) {
4700 free_user_token(&tokens[i].token);
4703 SAFE_FREE(share_list.shares);
4705 return NT_STATUS_OK;
4708 static int rpc_share_allowedusers(int argc, const char **argv)
4712 result = run_rpc_command(NULL, PI_SAMR, 0,
4713 rpc_aliaslist_internals,
4718 result = run_rpc_command(NULL, PI_LSARPC, 0,
4724 return run_rpc_command(NULL, PI_SRVSVC, 0,
4725 rpc_share_allowedusers_internals,
4729 int net_usersidlist(int argc, const char **argv)
4732 struct user_token *tokens = NULL;
4736 net_usersidlist_usage(argc, argv);
4740 if (!get_user_tokens(&num_tokens, &tokens)) {
4741 DEBUG(0, ("Could not get the user/sid list\n"));
4745 for (i=0; i<num_tokens; i++) {
4746 dump_user_token(&tokens[i]);
4747 free_user_token(&tokens[i].token);
4754 int net_usersidlist_usage(int argc, const char **argv)
4756 d_printf("net usersidlist\n"
4757 "\tprints out a list of all users the running winbind knows\n"
4758 "\tabout, together with all their SIDs. This is used as\n"
4759 "\tinput to the 'net rpc share allowedusers' command.\n\n");
4761 net_common_flags_usage(argc, argv);
4766 * 'net rpc share' entrypoint.
4767 * @param argc Standard main() style argc
4768 * @param argv Standard main() style argv. Initial components are already
4772 int net_rpc_share(int argc, const char **argv)
4774 struct functable func[] = {
4775 {"add", rpc_share_add},
4776 {"delete", rpc_share_delete},
4777 {"allowedusers", rpc_share_allowedusers},
4778 {"migrate", rpc_share_migrate},
4779 {"list", rpc_share_list},
4784 return run_rpc_command(NULL, PI_SRVSVC, 0,
4785 rpc_share_list_internals,
4788 return net_run_function(argc, argv, func, rpc_share_usage);
4791 static NTSTATUS rpc_sh_share_list(TALLOC_CTX *mem_ctx,
4792 struct rpc_sh_ctx *ctx,
4793 struct rpc_pipe_client *pipe_hnd,
4794 int argc, const char **argv)
4796 return rpc_share_list_internals(ctx->domain_sid, ctx->domain_name,
4797 ctx->cli, pipe_hnd, mem_ctx,
4801 static NTSTATUS rpc_sh_share_add(TALLOC_CTX *mem_ctx,
4802 struct rpc_sh_ctx *ctx,
4803 struct rpc_pipe_client *pipe_hnd,
4804 int argc, const char **argv)
4808 if ((argc < 2) || (argc > 3)) {
4809 d_fprintf(stderr, "usage: %s <share> <path> [comment]\n",
4811 return NT_STATUS_INVALID_PARAMETER;
4814 result = rpccli_srvsvc_net_share_add(
4815 pipe_hnd, mem_ctx, argv[0], STYPE_DISKTREE,
4816 (argc == 3) ? argv[2] : "",
4817 0, 0, 0, argv[1], NULL, 2, NULL);
4819 return werror_to_ntstatus(result);
4822 static NTSTATUS rpc_sh_share_delete(TALLOC_CTX *mem_ctx,
4823 struct rpc_sh_ctx *ctx,
4824 struct rpc_pipe_client *pipe_hnd,
4825 int argc, const char **argv)
4830 d_fprintf(stderr, "usage: %s <share>\n", ctx->whoami);
4831 return NT_STATUS_INVALID_PARAMETER;
4834 result = rpccli_srvsvc_net_share_del(pipe_hnd, mem_ctx, argv[0]);
4835 return werror_to_ntstatus(result);
4838 static NTSTATUS rpc_sh_share_info(TALLOC_CTX *mem_ctx,
4839 struct rpc_sh_ctx *ctx,
4840 struct rpc_pipe_client *pipe_hnd,
4841 int argc, const char **argv)
4843 SRV_SHARE_INFO info;
4844 SRV_SHARE_INFO_2 *info2 = &info.share.info2;
4848 d_fprintf(stderr, "usage: %s <share>\n", ctx->whoami);
4849 return NT_STATUS_INVALID_PARAMETER;
4852 result = rpccli_srvsvc_net_share_get_info(
4853 pipe_hnd, mem_ctx, argv[0], 2, &info);
4854 if (!W_ERROR_IS_OK(result)) {
4858 d_printf("Name: %s\n",
4859 rpcstr_pull_unistr2_talloc(mem_ctx,
4860 &info2->info_2_str.uni_netname));
4861 d_printf("Comment: %s\n",
4862 rpcstr_pull_unistr2_talloc(mem_ctx,
4863 &info2->info_2_str.uni_remark));
4865 d_printf("Path: %s\n",
4866 rpcstr_pull_unistr2_talloc(mem_ctx,
4867 &info2->info_2_str.uni_path));
4868 d_printf("Password: %s\n",
4869 rpcstr_pull_unistr2_talloc(mem_ctx,
4870 &info2->info_2_str.uni_passwd));
4873 return werror_to_ntstatus(result);
4876 struct rpc_sh_cmd *net_rpc_share_cmds(TALLOC_CTX *mem_ctx,
4877 struct rpc_sh_ctx *ctx)
4879 static struct rpc_sh_cmd cmds[] = {
4881 { "list", NULL, PI_SRVSVC, rpc_sh_share_list,
4882 "List available shares" },
4884 { "add", NULL, PI_SRVSVC, rpc_sh_share_add,
4887 { "delete", NULL, PI_SRVSVC, rpc_sh_share_delete,
4890 { "info", NULL, PI_SRVSVC, rpc_sh_share_info,
4891 "Get information about a share" },
4893 { NULL, NULL, 0, NULL, NULL }
4899 /****************************************************************************/
4901 static int rpc_file_usage(int argc, const char **argv)
4903 return net_help_file(argc, argv);
4907 * Close a file on a remote RPC server
4909 * All parameters are provided by the run_rpc_command function, except for
4910 * argc, argv which are passes through.
4912 * @param domain_sid The domain sid acquired from the remote server
4913 * @param cli A cli_state connected to the server.
4914 * @param mem_ctx Talloc context, destoyed on completion of the function.
4915 * @param argc Standard main() style argc
4916 * @param argv Standard main() style argv. Initial components are already
4919 * @return Normal NTSTATUS return.
4921 static NTSTATUS rpc_file_close_internals(const DOM_SID *domain_sid,
4922 const char *domain_name,
4923 struct cli_state *cli,
4924 struct rpc_pipe_client *pipe_hnd,
4925 TALLOC_CTX *mem_ctx,
4929 return rpccli_srvsvc_NetFileClose(pipe_hnd, mem_ctx,
4930 pipe_hnd->cli->desthost,
4931 atoi(argv[0]), NULL);
4935 * Close a file on a remote RPC server
4937 * @param argc Standard main() style argc
4938 * @param argv Standard main() style argv. Initial components are already
4941 * @return A shell status integer (0 for success)
4943 static int rpc_file_close(int argc, const char **argv)
4946 DEBUG(1, ("No fileid given on close\n"));
4947 return(rpc_file_usage(argc, argv));
4950 return run_rpc_command(NULL, PI_SRVSVC, 0,
4951 rpc_file_close_internals,
4956 * Formatted print of open file info
4958 * @param info3 FILE_INFO_3 contents
4959 * @param str3 strings for FILE_INFO_3
4962 static void display_file_info_3( FILE_INFO_3 *info3 )
4964 fstring user = "", path = "";
4966 rpcstr_pull_unistr2_fstring(user, info3->user);
4967 rpcstr_pull_unistr2_fstring(path, info3->path);
4969 d_printf("%-7.1d %-20.20s 0x%-4.2x %-6.1d %s\n",
4970 info3->id, user, info3->perms, info3->num_locks, path);
4974 * List open files on a remote RPC server
4976 * All parameters are provided by the run_rpc_command function, except for
4977 * argc, argv which are passes through.
4979 * @param domain_sid The domain sid acquired from the remote server
4980 * @param cli A cli_state connected to the server.
4981 * @param mem_ctx Talloc context, destoyed on completion of the function.
4982 * @param argc Standard main() style argc
4983 * @param argv Standard main() style argv. Initial components are already
4986 * @return Normal NTSTATUS return.
4989 static NTSTATUS rpc_file_list_internals(const DOM_SID *domain_sid,
4990 const char *domain_name,
4991 struct cli_state *cli,
4992 struct rpc_pipe_client *pipe_hnd,
4993 TALLOC_CTX *mem_ctx,
4997 SRV_FILE_INFO_CTR ctr;
5000 uint32 preferred_len = 0xffffffff, i;
5001 const char *username=NULL;
5003 init_enum_hnd(&hnd, 0);
5005 /* if argc > 0, must be user command */
5007 username = smb_xstrdup(argv[0]);
5009 result = rpccli_srvsvc_net_file_enum(pipe_hnd,
5010 mem_ctx, 3, username, &ctr, preferred_len, &hnd);
5012 if (!W_ERROR_IS_OK(result))
5015 /* Display results */
5018 "\nEnumerating open files on remote server:\n\n"\
5019 "\nFileId Opened by Perms Locks Path"\
5020 "\n------ --------- ----- ----- ---- \n");
5021 for (i = 0; i < ctr.num_entries; i++)
5022 display_file_info_3(&ctr.file.info3[i]);
5024 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
5028 * List files for a user on a remote RPC server
5030 * @param argc Standard main() style argc
5031 * @param argv Standard main() style argv. Initial components are already
5034 * @return A shell status integer (0 for success)
5037 static int rpc_file_user(int argc, const char **argv)
5040 DEBUG(1, ("No username given\n"));
5041 return(rpc_file_usage(argc, argv));
5044 return run_rpc_command(NULL, PI_SRVSVC, 0,
5045 rpc_file_list_internals,
5050 * 'net rpc file' entrypoint.
5051 * @param argc Standard main() style argc
5052 * @param argv Standard main() style argv. Initial components are already
5056 int net_rpc_file(int argc, const char **argv)
5058 struct functable func[] = {
5059 {"close", rpc_file_close},
5060 {"user", rpc_file_user},
5062 {"info", rpc_file_info},
5068 return run_rpc_command(NULL, PI_SRVSVC, 0,
5069 rpc_file_list_internals,
5072 return net_run_function(argc, argv, func, rpc_file_usage);
5076 * ABORT the shutdown of a remote RPC Server over, initshutdown pipe
5078 * All parameters are provided by the run_rpc_command function, except for
5079 * argc, argv which are passed through.
5081 * @param domain_sid The domain sid aquired from the remote server
5082 * @param cli A cli_state connected to the server.
5083 * @param mem_ctx Talloc context, destoyed on compleation of the function.
5084 * @param argc Standard main() style argc
5085 * @param argv Standard main() style argv. Initial components are already
5088 * @return Normal NTSTATUS return.
5091 static NTSTATUS rpc_shutdown_abort_internals(const DOM_SID *domain_sid,
5092 const char *domain_name,
5093 struct cli_state *cli,
5094 struct rpc_pipe_client *pipe_hnd,
5095 TALLOC_CTX *mem_ctx,
5099 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
5101 result = rpccli_initshutdown_Abort(pipe_hnd, mem_ctx, NULL, NULL);
5103 if (NT_STATUS_IS_OK(result)) {
5104 d_printf("\nShutdown successfully aborted\n");
5105 DEBUG(5,("cmd_shutdown_abort: query succeeded\n"));
5107 DEBUG(5,("cmd_shutdown_abort: query failed\n"));
5113 * ABORT the shutdown of a remote RPC Server, over winreg pipe
5115 * All parameters are provided by the run_rpc_command function, except for
5116 * argc, argv which are passed through.
5118 * @param domain_sid The domain sid aquired from the remote server
5119 * @param cli A cli_state connected to the server.
5120 * @param mem_ctx Talloc context, destoyed on compleation of the function.
5121 * @param argc Standard main() style argc
5122 * @param argv Standard main() style argv. Initial components are already
5125 * @return Normal NTSTATUS return.
5128 static NTSTATUS rpc_reg_shutdown_abort_internals(const DOM_SID *domain_sid,
5129 const char *domain_name,
5130 struct cli_state *cli,
5131 struct rpc_pipe_client *pipe_hnd,
5132 TALLOC_CTX *mem_ctx,
5136 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
5138 result = rpccli_winreg_AbortSystemShutdown(pipe_hnd, mem_ctx, NULL, NULL);
5140 if (NT_STATUS_IS_OK(result)) {
5141 d_printf("\nShutdown successfully aborted\n");
5142 DEBUG(5,("cmd_reg_abort_shutdown: query succeeded\n"));
5144 DEBUG(5,("cmd_reg_abort_shutdown: query failed\n"));
5150 * ABORT the Shut down of a remote RPC server
5152 * @param argc Standard main() style argc
5153 * @param argv Standard main() style argv. Initial components are already
5156 * @return A shell status integer (0 for success)
5159 static int rpc_shutdown_abort(int argc, const char **argv)
5161 int rc = run_rpc_command(NULL, PI_INITSHUTDOWN, 0,
5162 rpc_shutdown_abort_internals,
5168 DEBUG(1, ("initshutdown pipe didn't work, trying winreg pipe\n"));
5170 return run_rpc_command(NULL, PI_WINREG, 0,
5171 rpc_reg_shutdown_abort_internals,
5176 * Shut down a remote RPC Server via initshutdown pipe
5178 * All parameters are provided by the run_rpc_command function, except for
5179 * argc, argv which are passes through.
5181 * @param domain_sid The domain sid aquired from the remote server
5182 * @param cli A cli_state connected to the server.
5183 * @param mem_ctx Talloc context, destoyed on compleation of the function.
5184 * @param argc Standard main() style argc
5185 * @param argc Standard main() style argv. Initial components are already
5188 * @return Normal NTSTATUS return.
5191 NTSTATUS rpc_init_shutdown_internals(const DOM_SID *domain_sid,
5192 const char *domain_name,
5193 struct cli_state *cli,
5194 struct rpc_pipe_client *pipe_hnd,
5195 TALLOC_CTX *mem_ctx,
5199 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
5200 const char *msg = "This machine will be shutdown shortly";
5201 uint32 timeout = 20;
5202 struct initshutdown_String msg_string;
5203 struct initshutdown_String_sub s;
5209 timeout = opt_timeout;
5213 msg_string.name = &s;
5215 /* create an entry */
5216 result = rpccli_initshutdown_Init(pipe_hnd, mem_ctx, NULL,
5217 &msg_string, timeout, opt_force, opt_reboot, NULL);
5219 if (NT_STATUS_IS_OK(result)) {
5220 d_printf("\nShutdown of remote machine succeeded\n");
5221 DEBUG(5,("Shutdown of remote machine succeeded\n"));
5223 DEBUG(1,("Shutdown of remote machine failed!\n"));
5229 * Shut down a remote RPC Server via winreg pipe
5231 * All parameters are provided by the run_rpc_command function, except for
5232 * argc, argv which are passes through.
5234 * @param domain_sid The domain sid aquired from the remote server
5235 * @param cli A cli_state connected to the server.
5236 * @param mem_ctx Talloc context, destoyed on compleation of the function.
5237 * @param argc Standard main() style argc
5238 * @param argc Standard main() style argv. Initial components are already
5241 * @return Normal NTSTATUS return.
5244 NTSTATUS rpc_reg_shutdown_internals(const DOM_SID *domain_sid,
5245 const char *domain_name,
5246 struct cli_state *cli,
5247 struct rpc_pipe_client *pipe_hnd,
5248 TALLOC_CTX *mem_ctx,
5252 const char *msg = "This machine will be shutdown shortly";
5253 uint32 timeout = 20;
5254 struct initshutdown_String msg_string;
5255 struct initshutdown_String_sub s;
5263 msg_string.name = &s;
5266 timeout = opt_timeout;
5269 /* create an entry */
5270 result = rpccli_winreg_InitiateSystemShutdown(pipe_hnd, mem_ctx, NULL,
5271 &msg_string, timeout, opt_force, opt_reboot, &werr);
5273 if (NT_STATUS_IS_OK(result)) {
5274 d_printf("\nShutdown of remote machine succeeded\n");
5276 d_fprintf(stderr, "\nShutdown of remote machine failed\n");
5277 if ( W_ERROR_EQUAL(werr, WERR_MACHINE_LOCKED) )
5278 d_fprintf(stderr, "\nMachine locked, use -f switch to force\n");
5280 d_fprintf(stderr, "\nresult was: %s\n", dos_errstr(werr));
5287 * Shut down a remote RPC server
5289 * @param argc Standard main() style argc
5290 * @param argc Standard main() style argv. Initial components are already
5293 * @return A shell status integer (0 for success)
5296 static int rpc_shutdown(int argc, const char **argv)
5298 int rc = run_rpc_command(NULL, PI_INITSHUTDOWN, 0,
5299 rpc_init_shutdown_internals,
5303 DEBUG(1, ("initshutdown pipe failed, trying winreg pipe\n"));
5304 rc = run_rpc_command(NULL, PI_WINREG, 0,
5305 rpc_reg_shutdown_internals, argc, argv);
5311 /***************************************************************************
5312 NT Domain trusts code (i.e. 'net rpc trustdom' functionality)
5314 ***************************************************************************/
5317 * Add interdomain trust account to the RPC server.
5318 * All parameters (except for argc and argv) are passed by run_rpc_command
5321 * @param domain_sid The domain sid acquired from the server
5322 * @param cli A cli_state connected to the server.
5323 * @param mem_ctx Talloc context, destoyed on completion of the function.
5324 * @param argc Standard main() style argc
5325 * @param argc Standard main() style argv. Initial components are already
5328 * @return normal NTSTATUS return code
5331 static NTSTATUS rpc_trustdom_add_internals(const DOM_SID *domain_sid,
5332 const char *domain_name,
5333 struct cli_state *cli,
5334 struct rpc_pipe_client *pipe_hnd,
5335 TALLOC_CTX *mem_ctx,
5339 POLICY_HND connect_pol, domain_pol, user_pol;
5340 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
5343 uint32 unknown, user_rid;
5346 d_printf("Usage: net rpc trustdom add <domain_name> <pw>\n");
5347 return NT_STATUS_INVALID_PARAMETER;
5351 * Make valid trusting domain account (ie. uppercased and with '$' appended)
5354 if (asprintf(&acct_name, "%s$", argv[0]) < 0) {
5355 return NT_STATUS_NO_MEMORY;
5358 strupper_m(acct_name);
5360 /* Get samr policy handle */
5361 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
5363 if (!NT_STATUS_IS_OK(result)) {
5367 /* Get domain policy handle */
5368 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
5369 MAXIMUM_ALLOWED_ACCESS,
5370 domain_sid, &domain_pol);
5371 if (!NT_STATUS_IS_OK(result)) {
5375 /* Create trusting domain's account */
5376 acb_info = ACB_NORMAL;
5377 unknown = 0xe00500b0; /* No idea what this is - a permission mask?
5378 mimir: yes, most probably it is */
5380 result = rpccli_samr_create_dom_user(pipe_hnd, mem_ctx, &domain_pol,
5381 acct_name, acb_info, unknown,
5382 &user_pol, &user_rid);
5383 if (!NT_STATUS_IS_OK(result)) {
5388 SAM_USERINFO_CTR ctr;
5389 SAM_USER_INFO_23 p23;
5395 encode_pw_buffer(pwbuf, argv[1], STR_UNICODE);
5399 ZERO_STRUCT(notime);
5403 memset(hrs.hours, 0xFF, sizeof(hrs.hours));
5404 acb_info = ACB_DOMTRUST;
5406 init_sam_user_info23A(&p23, ¬ime, ¬ime, ¬ime,
5407 ¬ime, ¬ime, ¬ime,
5408 nostr, nostr, nostr, nostr, nostr,
5409 nostr, nostr, nostr, nostr, nostr,
5410 0, 0, acb_info, ACCT_FLAGS, 168, &hrs,
5411 0, 0, (char *)pwbuf);
5412 ctr.switch_value = 23;
5413 ctr.info.id23 = &p23;
5414 p23.passmustchange = 0;
5416 result = rpccli_samr_set_userinfo(pipe_hnd, mem_ctx, &user_pol, 23,
5417 &cli->user_session_key, &ctr);
5419 if (!NT_STATUS_IS_OK(result)) {
5420 DEBUG(0,("Could not set trust account password: %s\n",
5421 nt_errstr(result)));
5427 SAFE_FREE(acct_name);
5432 * Create interdomain trust account for a remote domain.
5434 * @param argc standard argc
5435 * @param argv standard argv without initial components
5437 * @return Integer status (0 means success)
5440 static int rpc_trustdom_add(int argc, const char **argv)
5443 return run_rpc_command(NULL, PI_SAMR, 0, rpc_trustdom_add_internals,
5446 d_printf("Usage: net rpc trustdom add <domain>\n");
5453 * Remove interdomain trust account from the RPC server.
5454 * All parameters (except for argc and argv) are passed by run_rpc_command
5457 * @param domain_sid The domain sid acquired from the server
5458 * @param cli A cli_state connected to the server.
5459 * @param mem_ctx Talloc context, destoyed on completion of the function.
5460 * @param argc Standard main() style argc
5461 * @param argc Standard main() style argv. Initial components are already
5464 * @return normal NTSTATUS return code
5467 static NTSTATUS rpc_trustdom_del_internals(const DOM_SID *domain_sid,
5468 const char *domain_name,
5469 struct cli_state *cli,
5470 struct rpc_pipe_client *pipe_hnd,
5471 TALLOC_CTX *mem_ctx,
5475 POLICY_HND connect_pol, domain_pol, user_pol;
5476 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
5479 DOM_SID trust_acct_sid;
5480 uint32 *user_rids, num_rids, *name_types;
5481 uint32 flags = 0x000003e8; /* Unknown */
5484 d_printf("Usage: net rpc trustdom del <domain_name>\n");
5485 return NT_STATUS_INVALID_PARAMETER;
5489 * Make valid trusting domain account (ie. uppercased and with '$' appended)
5491 acct_name = talloc_asprintf(mem_ctx, "%s$", argv[0]);
5493 if (acct_name == NULL)
5494 return NT_STATUS_NO_MEMORY;
5496 strupper_m(acct_name);
5498 if ((names = TALLOC_ARRAY(mem_ctx, const char *, 1)) == NULL) {
5499 return NT_STATUS_NO_MEMORY;
5501 names[0] = acct_name;
5504 /* Get samr policy handle */
5505 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
5507 if (!NT_STATUS_IS_OK(result)) {
5511 /* Get domain policy handle */
5512 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
5513 MAXIMUM_ALLOWED_ACCESS,
5514 domain_sid, &domain_pol);
5515 if (!NT_STATUS_IS_OK(result)) {
5519 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, flags, 1,
5521 &user_rids, &name_types);
5523 if (!NT_STATUS_IS_OK(result)) {
5527 result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
5528 MAXIMUM_ALLOWED_ACCESS,
5529 user_rids[0], &user_pol);
5531 if (!NT_STATUS_IS_OK(result)) {
5535 /* append the rid to the domain sid */
5536 sid_copy(&trust_acct_sid, domain_sid);
5537 if (!sid_append_rid(&trust_acct_sid, user_rids[0])) {
5541 /* remove the sid */
5543 result = rpccli_samr_remove_sid_foreign_domain(pipe_hnd, mem_ctx, &user_pol,
5546 if (!NT_STATUS_IS_OK(result)) {
5552 result = rpccli_samr_delete_dom_user(pipe_hnd, mem_ctx, &user_pol);
5554 if (!NT_STATUS_IS_OK(result)) {
5558 if (!NT_STATUS_IS_OK(result)) {
5559 DEBUG(0,("Could not set trust account password: %s\n",
5560 nt_errstr(result)));
5569 * Delete interdomain trust account for a remote domain.
5571 * @param argc standard argc
5572 * @param argv standard argv without initial components
5574 * @return Integer status (0 means success)
5577 static int rpc_trustdom_del(int argc, const char **argv)
5580 return run_rpc_command(NULL, PI_SAMR, 0, rpc_trustdom_del_internals,
5583 d_printf("Usage: net rpc trustdom del <domain>\n");
5590 * Establish trust relationship to a trusting domain.
5591 * Interdomain account must already be created on remote PDC.
5593 * @param argc standard argc
5594 * @param argv standard argv without initial components
5596 * @return Integer status (0 means success)
5599 static int rpc_trustdom_establish(int argc, const char **argv)
5601 struct cli_state *cli = NULL;
5602 struct sockaddr_storage server_ss;
5603 struct rpc_pipe_client *pipe_hnd = NULL;
5604 POLICY_HND connect_hnd;
5605 TALLOC_CTX *mem_ctx;
5607 DOM_SID *domain_sid;
5610 char* domain_name_pol;
5616 * Connect to \\server\ipc$ as 'our domain' account with password
5620 d_printf("Usage: net rpc trustdom establish <domain_name>\n");
5624 domain_name = smb_xstrdup(argv[0]);
5625 strupper_m(domain_name);
5627 /* account name used at first is our domain's name with '$' */
5628 asprintf(&acct_name, "%s$", lp_workgroup());
5629 strupper_m(acct_name);
5632 * opt_workgroup will be used by connection functions further,
5633 * hence it should be set to remote domain name instead of ours
5635 if (opt_workgroup) {
5636 opt_workgroup = smb_xstrdup(domain_name);
5639 opt_user_name = acct_name;
5641 /* find the domain controller */
5642 if (!net_find_pdc(&server_ss, pdc_name, domain_name)) {
5643 DEBUG(0, ("Couldn't find domain controller for domain %s\n", domain_name));
5647 /* connect to ipc$ as username/password */
5648 nt_status = connect_to_ipc(&cli, &server_ss, pdc_name);
5649 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT)) {
5651 /* Is it trusting domain account for sure ? */
5652 DEBUG(0, ("Couldn't verify trusting domain account. Error was %s\n",
5653 nt_errstr(nt_status)));
5657 /* store who we connected to */
5659 saf_store( domain_name, pdc_name );
5662 * Connect to \\server\ipc$ again (this time anonymously)
5665 nt_status = connect_to_ipc_anonymous(&cli, &server_ss, (char*)pdc_name);
5667 if (NT_STATUS_IS_ERR(nt_status)) {
5668 DEBUG(0, ("Couldn't connect to domain %s controller. Error was %s.\n",
5669 domain_name, nt_errstr(nt_status)));
5674 * Use NetServerEnum2 to make sure we're talking to a proper server
5677 if (!cli_get_pdc_name(cli, domain_name, &dc_name)) {
5678 DEBUG(0, ("NetServerEnum2 error: Couldn't find primary domain controller\
5679 for domain %s\n", domain_name));
5685 if (!(mem_ctx = talloc_init("establishing trust relationship to "
5686 "domain %s", domain_name))) {
5687 DEBUG(0, ("talloc_init() failed\n"));
5693 * Call LsaOpenPolicy and LsaQueryInfo
5696 pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_LSARPC, &nt_status);
5698 DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n", nt_errstr(nt_status) ));
5700 talloc_destroy(mem_ctx);
5704 nt_status = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, True, SEC_RIGHTS_QUERY_VALUE,
5706 if (NT_STATUS_IS_ERR(nt_status)) {
5707 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
5708 nt_errstr(nt_status)));
5710 talloc_destroy(mem_ctx);
5714 /* Querying info level 5 */
5716 nt_status = rpccli_lsa_query_info_policy(pipe_hnd, mem_ctx, &connect_hnd,
5718 &domain_name_pol, &domain_sid);
5719 if (NT_STATUS_IS_ERR(nt_status)) {
5720 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
5721 nt_errstr(nt_status)));
5723 talloc_destroy(mem_ctx);
5727 /* There should be actually query info level 3 (following nt serv behaviour),
5728 but I still don't know if it's _really_ necessary */
5731 * Store the password in secrets db
5734 if (!pdb_set_trusteddom_pw(domain_name, opt_password, domain_sid)) {
5735 DEBUG(0, ("Storing password for trusted domain failed.\n"));
5737 talloc_destroy(mem_ctx);
5742 * Close the pipes and clean up
5745 nt_status = rpccli_lsa_Close(pipe_hnd, mem_ctx, &connect_hnd);
5746 if (NT_STATUS_IS_ERR(nt_status)) {
5747 DEBUG(0, ("Couldn't close LSA pipe. Error was %s\n",
5748 nt_errstr(nt_status)));
5750 talloc_destroy(mem_ctx);
5756 talloc_destroy(mem_ctx);
5758 d_printf("Trust to domain %s established\n", domain_name);
5763 * Revoke trust relationship to the remote domain
5765 * @param argc standard argc
5766 * @param argv standard argv without initial components
5768 * @return Integer status (0 means success)
5771 static int rpc_trustdom_revoke(int argc, const char **argv)
5776 if (argc < 1) return -1;
5778 /* generate upper cased domain name */
5779 domain_name = smb_xstrdup(argv[0]);
5780 strupper_m(domain_name);
5782 /* delete password of the trust */
5783 if (!pdb_del_trusteddom_pw(domain_name)) {
5784 DEBUG(0, ("Failed to revoke relationship to the trusted domain %s\n",
5791 SAFE_FREE(domain_name);
5796 * Usage for 'net rpc trustdom' command
5798 * @param argc standard argc
5799 * @param argv standard argv without inital components
5801 * @return Integer status returned to shell
5804 static int rpc_trustdom_usage(int argc, const char **argv)
5806 d_printf(" net rpc trustdom add \t\t add trusting domain's account\n");
5807 d_printf(" net rpc trustdom del \t\t delete trusting domain's account\n");
5808 d_printf(" net rpc trustdom establish \t establish relationship to trusted domain\n");
5809 d_printf(" net rpc trustdom revoke \t abandon relationship to trusted domain\n");
5810 d_printf(" net rpc trustdom list \t show current interdomain trust relationships\n");
5811 d_printf(" net rpc trustdom vampire \t vampire interdomain trust relationships from remote server\n");
5816 static NTSTATUS rpc_query_domain_sid(const DOM_SID *domain_sid,
5817 const char *domain_name,
5818 struct cli_state *cli,
5819 struct rpc_pipe_client *pipe_hnd,
5820 TALLOC_CTX *mem_ctx,
5825 sid_to_fstring(str_sid, domain_sid);
5826 d_printf("%s\n", str_sid);
5827 return NT_STATUS_OK;
5830 static void print_trusted_domain(DOM_SID *dom_sid, const char *trusted_dom_name)
5832 fstring ascii_sid, padding;
5833 int pad_len, col_len = 20;
5835 /* convert sid into ascii string */
5836 sid_to_fstring(ascii_sid, dom_sid);
5838 /* calculate padding space for d_printf to look nicer */
5839 pad_len = col_len - strlen(trusted_dom_name);
5840 padding[pad_len] = 0;
5841 do padding[--pad_len] = ' '; while (pad_len);
5843 d_printf("%s%s%s\n", trusted_dom_name, padding, ascii_sid);
5846 static NTSTATUS vampire_trusted_domain(struct rpc_pipe_client *pipe_hnd,
5847 TALLOC_CTX *mem_ctx,
5850 const char *trusted_dom_name)
5853 union lsa_TrustedDomainInfo info;
5854 char *cleartextpwd = NULL;
5857 nt_status = rpccli_lsa_QueryTrustedDomainInfoBySid(pipe_hnd, mem_ctx,
5860 LSA_TRUSTED_DOMAIN_INFO_PASSWORD,
5862 if (NT_STATUS_IS_ERR(nt_status)) {
5863 DEBUG(0,("Could not query trusted domain info. Error was %s\n",
5864 nt_errstr(nt_status)));
5868 data = data_blob(NULL, info.password.password->length);
5871 info.password.password->data,
5872 info.password.password->length);
5873 data.length = info.password.password->length;
5875 cleartextpwd = decrypt_trustdom_secret(pipe_hnd->cli->pwd.password,
5878 if (cleartextpwd == NULL) {
5879 DEBUG(0,("retrieved NULL password\n"));
5880 nt_status = NT_STATUS_UNSUCCESSFUL;
5884 if (!pdb_set_trusteddom_pw(trusted_dom_name, cleartextpwd, &dom_sid)) {
5885 DEBUG(0, ("Storing password for trusted domain failed.\n"));
5886 nt_status = NT_STATUS_UNSUCCESSFUL;
5890 #ifdef DEBUG_PASSWORD
5891 DEBUG(100,("sucessfully vampired trusted domain [%s], sid: [%s], "
5892 "password: [%s]\n", trusted_dom_name,
5893 sid_string_dbg(&dom_sid), cleartextpwd));
5897 SAFE_FREE(cleartextpwd);
5898 data_blob_free(&data);
5903 static int rpc_trustdom_vampire(int argc, const char **argv)
5905 /* common variables */
5906 TALLOC_CTX* mem_ctx;
5907 struct cli_state *cli = NULL;
5908 struct rpc_pipe_client *pipe_hnd = NULL;
5910 const char *domain_name = NULL;
5911 DOM_SID *queried_dom_sid;
5912 POLICY_HND connect_hnd;
5914 /* trusted domains listing variables */
5915 unsigned int num_domains, enum_ctx = 0;
5917 DOM_SID *domain_sids;
5918 char **trusted_dom_names;
5923 * Listing trusted domains (stored in secrets.tdb, if local)
5926 mem_ctx = talloc_init("trust relationships vampire");
5929 * set domain and pdc name to local samba server (default)
5930 * or to remote one given in command line
5933 if (StrCaseCmp(opt_workgroup, lp_workgroup())) {
5934 domain_name = opt_workgroup;
5935 opt_target_workgroup = opt_workgroup;
5937 fstrcpy(pdc_name, global_myname());
5938 domain_name = talloc_strdup(mem_ctx, lp_workgroup());
5939 opt_target_workgroup = domain_name;
5942 /* open \PIPE\lsarpc and open policy handle */
5943 nt_status = net_make_ipc_connection(NET_FLAGS_PDC, &cli);
5944 if (!NT_STATUS_IS_OK(nt_status)) {
5945 DEBUG(0, ("Couldn't connect to domain controller: %s\n",
5946 nt_errstr(nt_status)));
5947 talloc_destroy(mem_ctx);
5951 pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_LSARPC, &nt_status);
5953 DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n",
5954 nt_errstr(nt_status) ));
5956 talloc_destroy(mem_ctx);
5960 nt_status = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, False, SEC_RIGHTS_QUERY_VALUE,
5962 if (NT_STATUS_IS_ERR(nt_status)) {
5963 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
5964 nt_errstr(nt_status)));
5966 talloc_destroy(mem_ctx);
5970 /* query info level 5 to obtain sid of a domain being queried */
5971 nt_status = rpccli_lsa_query_info_policy(
5972 pipe_hnd, mem_ctx, &connect_hnd, 5 /* info level */,
5973 &dummy, &queried_dom_sid);
5975 if (NT_STATUS_IS_ERR(nt_status)) {
5976 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
5977 nt_errstr(nt_status)));
5979 talloc_destroy(mem_ctx);
5984 * Keep calling LsaEnumTrustdom over opened pipe until
5985 * the end of enumeration is reached
5988 d_printf("Vampire trusted domains:\n\n");
5991 nt_status = rpccli_lsa_enum_trust_dom(pipe_hnd, mem_ctx, &connect_hnd, &enum_ctx,
5993 &trusted_dom_names, &domain_sids);
5995 if (NT_STATUS_IS_ERR(nt_status)) {
5996 DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
5997 nt_errstr(nt_status)));
5999 talloc_destroy(mem_ctx);
6003 for (i = 0; i < num_domains; i++) {
6005 print_trusted_domain(&(domain_sids[i]), trusted_dom_names[i]);
6007 nt_status = vampire_trusted_domain(pipe_hnd, mem_ctx, &connect_hnd,
6008 domain_sids[i], trusted_dom_names[i]);
6009 if (!NT_STATUS_IS_OK(nt_status)) {
6011 talloc_destroy(mem_ctx);
6017 * in case of no trusted domains say something rather
6018 * than just display blank line
6020 if (!num_domains) d_printf("none\n");
6022 } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
6024 /* close this connection before doing next one */
6025 nt_status = rpccli_lsa_Close(pipe_hnd, mem_ctx, &connect_hnd);
6026 if (NT_STATUS_IS_ERR(nt_status)) {
6027 DEBUG(0, ("Couldn't properly close lsa policy handle. Error was %s\n",
6028 nt_errstr(nt_status)));
6030 talloc_destroy(mem_ctx);
6034 /* close lsarpc pipe and connection to IPC$ */
6037 talloc_destroy(mem_ctx);
6041 static int rpc_trustdom_list(int argc, const char **argv)
6043 /* common variables */
6044 TALLOC_CTX* mem_ctx;
6045 struct cli_state *cli = NULL, *remote_cli = NULL;
6046 struct rpc_pipe_client *pipe_hnd = NULL;
6048 const char *domain_name = NULL;
6049 DOM_SID *queried_dom_sid;
6051 int ascii_dom_name_len;
6052 POLICY_HND connect_hnd;
6054 /* trusted domains listing variables */
6055 unsigned int num_domains, enum_ctx = 0;
6056 int i, pad_len, col_len = 20;
6057 DOM_SID *domain_sids;
6058 char **trusted_dom_names;
6062 /* trusting domains listing variables */
6063 POLICY_HND domain_hnd;
6064 char **trusting_dom_names;
6065 uint32 *trusting_dom_rids;
6068 * Listing trusted domains (stored in secrets.tdb, if local)
6071 mem_ctx = talloc_init("trust relationships listing");
6074 * set domain and pdc name to local samba server (default)
6075 * or to remote one given in command line
6078 if (StrCaseCmp(opt_workgroup, lp_workgroup())) {
6079 domain_name = opt_workgroup;
6080 opt_target_workgroup = opt_workgroup;
6082 fstrcpy(pdc_name, global_myname());
6083 domain_name = talloc_strdup(mem_ctx, lp_workgroup());
6084 opt_target_workgroup = domain_name;
6087 /* open \PIPE\lsarpc and open policy handle */
6088 nt_status = net_make_ipc_connection(NET_FLAGS_PDC, &cli);
6089 if (!NT_STATUS_IS_OK(nt_status)) {
6090 DEBUG(0, ("Couldn't connect to domain controller: %s\n",
6091 nt_errstr(nt_status)));
6092 talloc_destroy(mem_ctx);
6096 pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_LSARPC, &nt_status);
6098 DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n",
6099 nt_errstr(nt_status) ));
6101 talloc_destroy(mem_ctx);
6105 nt_status = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, False, SEC_RIGHTS_QUERY_VALUE,
6107 if (NT_STATUS_IS_ERR(nt_status)) {
6108 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
6109 nt_errstr(nt_status)));
6111 talloc_destroy(mem_ctx);
6115 /* query info level 5 to obtain sid of a domain being queried */
6116 nt_status = rpccli_lsa_query_info_policy(
6117 pipe_hnd, mem_ctx, &connect_hnd, 5 /* info level */,
6118 &dummy, &queried_dom_sid);
6120 if (NT_STATUS_IS_ERR(nt_status)) {
6121 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
6122 nt_errstr(nt_status)));
6124 talloc_destroy(mem_ctx);
6129 * Keep calling LsaEnumTrustdom over opened pipe until
6130 * the end of enumeration is reached
6133 d_printf("Trusted domains list:\n\n");
6136 nt_status = rpccli_lsa_enum_trust_dom(pipe_hnd, mem_ctx, &connect_hnd, &enum_ctx,
6138 &trusted_dom_names, &domain_sids);
6140 if (NT_STATUS_IS_ERR(nt_status)) {
6141 DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
6142 nt_errstr(nt_status)));
6144 talloc_destroy(mem_ctx);
6148 for (i = 0; i < num_domains; i++) {
6149 print_trusted_domain(&(domain_sids[i]), trusted_dom_names[i]);
6153 * in case of no trusted domains say something rather
6154 * than just display blank line
6156 if (!num_domains) d_printf("none\n");
6158 } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
6160 /* close this connection before doing next one */
6161 nt_status = rpccli_lsa_Close(pipe_hnd, mem_ctx, &connect_hnd);
6162 if (NT_STATUS_IS_ERR(nt_status)) {
6163 DEBUG(0, ("Couldn't properly close lsa policy handle. Error was %s\n",
6164 nt_errstr(nt_status)));
6166 talloc_destroy(mem_ctx);
6170 cli_rpc_pipe_close(pipe_hnd);
6173 * Listing trusting domains (stored in passdb backend, if local)
6176 d_printf("\nTrusting domains list:\n\n");
6179 * Open \PIPE\samr and get needed policy handles
6181 pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SAMR, &nt_status);
6183 DEBUG(0, ("Could not initialise samr pipe. Error was %s\n", nt_errstr(nt_status)));
6185 talloc_destroy(mem_ctx);
6190 nt_status = rpccli_samr_connect(pipe_hnd, mem_ctx, SA_RIGHT_SAM_OPEN_DOMAIN,
6192 if (!NT_STATUS_IS_OK(nt_status)) {
6193 DEBUG(0, ("Couldn't open SAMR policy handle. Error was %s\n",
6194 nt_errstr(nt_status)));
6196 talloc_destroy(mem_ctx);
6200 /* SamrOpenDomain - we have to open domain policy handle in order to be
6201 able to enumerate accounts*/
6202 nt_status = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_hnd,
6203 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
6204 queried_dom_sid, &domain_hnd);
6205 if (!NT_STATUS_IS_OK(nt_status)) {
6206 DEBUG(0, ("Couldn't open domain object. Error was %s\n",
6207 nt_errstr(nt_status)));
6209 talloc_destroy(mem_ctx);
6214 * perform actual enumeration
6217 enum_ctx = 0; /* reset enumeration context from last enumeration */
6220 nt_status = rpccli_samr_enum_dom_users(pipe_hnd, mem_ctx, &domain_hnd,
6221 &enum_ctx, ACB_DOMTRUST, 0xffff,
6222 &trusting_dom_names, &trusting_dom_rids,
6224 if (NT_STATUS_IS_ERR(nt_status)) {
6225 DEBUG(0, ("Couldn't enumerate accounts. Error was: %s\n",
6226 nt_errstr(nt_status)));
6228 talloc_destroy(mem_ctx);
6232 for (i = 0; i < num_domains; i++) {
6235 * get each single domain's sid (do we _really_ need this ?):
6236 * 1) connect to domain's pdc
6237 * 2) query the pdc for domain's sid
6240 /* get rid of '$' tail */
6241 ascii_dom_name_len = strlen(trusting_dom_names[i]);
6242 if (ascii_dom_name_len && ascii_dom_name_len < FSTRING_LEN)
6243 trusting_dom_names[i][ascii_dom_name_len - 1] = '\0';
6245 /* calculate padding space for d_printf to look nicer */
6246 pad_len = col_len - strlen(trusting_dom_names[i]);
6247 padding[pad_len] = 0;
6248 do padding[--pad_len] = ' '; while (pad_len);
6250 /* set opt_* variables to remote domain */
6251 strupper_m(trusting_dom_names[i]);
6252 opt_workgroup = talloc_strdup(mem_ctx, trusting_dom_names[i]);
6253 opt_target_workgroup = opt_workgroup;
6255 d_printf("%s%s", trusting_dom_names[i], padding);
6257 /* connect to remote domain controller */
6258 nt_status = net_make_ipc_connection(
6259 NET_FLAGS_PDC | NET_FLAGS_ANONYMOUS,
6261 if (NT_STATUS_IS_OK(nt_status)) {
6262 /* query for domain's sid */
6263 if (run_rpc_command(remote_cli, PI_LSARPC, 0, rpc_query_domain_sid, argc, argv))
6264 d_fprintf(stderr, "couldn't get domain's sid\n");
6266 cli_shutdown(remote_cli);
6269 d_fprintf(stderr, "domain controller is not "
6271 nt_errstr(nt_status));
6275 if (!num_domains) d_printf("none\n");
6277 } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
6279 /* close opened samr and domain policy handles */
6280 nt_status = rpccli_samr_close(pipe_hnd, mem_ctx, &domain_hnd);
6281 if (!NT_STATUS_IS_OK(nt_status)) {
6282 DEBUG(0, ("Couldn't properly close domain policy handle for domain %s\n", domain_name));
6285 nt_status = rpccli_samr_close(pipe_hnd, mem_ctx, &connect_hnd);
6286 if (!NT_STATUS_IS_OK(nt_status)) {
6287 DEBUG(0, ("Couldn't properly close samr policy handle for domain %s\n", domain_name));
6290 /* close samr pipe and connection to IPC$ */
6293 talloc_destroy(mem_ctx);
6298 * Entrypoint for 'net rpc trustdom' code
6300 * @param argc standard argc
6301 * @param argv standard argv without initial components
6303 * @return Integer status (0 means success)
6306 static int rpc_trustdom(int argc, const char **argv)
6308 struct functable func[] = {
6309 {"add", rpc_trustdom_add},
6310 {"del", rpc_trustdom_del},
6311 {"establish", rpc_trustdom_establish},
6312 {"revoke", rpc_trustdom_revoke},
6313 {"help", rpc_trustdom_usage},
6314 {"list", rpc_trustdom_list},
6315 {"vampire", rpc_trustdom_vampire},
6320 rpc_trustdom_usage(argc, argv);
6324 return (net_run_function(argc, argv, func, rpc_user_usage));
6328 * Check if a server will take rpc commands
6329 * @param flags Type of server to connect to (PDC, DMB, localhost)
6330 * if the host is not explicitly specified
6331 * @return bool (true means rpc supported)
6333 bool net_rpc_check(unsigned flags)
6335 struct cli_state *cli;
6337 struct sockaddr_storage server_ss;
6338 char *server_name = NULL;
6341 /* flags (i.e. server type) may depend on command */
6342 if (!net_find_server(NULL, flags, &server_ss, &server_name))
6345 if ((cli = cli_initialise()) == NULL) {
6349 status = cli_connect(cli, server_name, &server_ss);
6350 if (!NT_STATUS_IS_OK(status))
6352 if (!attempt_netbios_session_request(&cli, global_myname(),
6353 server_name, &server_ss))
6355 if (!cli_negprot(cli))
6357 if (cli->protocol < PROTOCOL_NT1)
6366 /* dump sam database via samsync rpc calls */
6367 static int rpc_samdump(int argc, const char **argv) {
6368 return run_rpc_command(NULL, PI_NETLOGON, NET_FLAGS_ANONYMOUS, rpc_samdump_internals,
6372 /* syncronise sam database via samsync rpc calls */
6373 static int rpc_vampire(int argc, const char **argv) {
6374 return run_rpc_command(NULL, PI_NETLOGON, NET_FLAGS_ANONYMOUS, rpc_vampire_internals,
6379 * Migrate everything from a print-server
6381 * @param argc Standard main() style argc
6382 * @param argv Standard main() style argv. Initial components are already
6385 * @return A shell status integer (0 for success)
6387 * The order is important !
6388 * To successfully add drivers the print-queues have to exist !
6389 * Applying ACLs should be the last step, because you're easily locked out
6392 static int rpc_printer_migrate_all(int argc, const char **argv)
6397 printf("no server to migrate\n");
6401 ret = run_rpc_command(NULL, PI_SPOOLSS, 0, rpc_printer_migrate_printers_internals, argc, argv);
6405 ret = run_rpc_command(NULL, PI_SPOOLSS, 0, rpc_printer_migrate_drivers_internals, argc, argv);
6409 ret = run_rpc_command(NULL, PI_SPOOLSS, 0, rpc_printer_migrate_forms_internals, argc, argv);
6413 ret = run_rpc_command(NULL, PI_SPOOLSS, 0, rpc_printer_migrate_settings_internals, argc, argv);
6417 return run_rpc_command(NULL, PI_SPOOLSS, 0, rpc_printer_migrate_security_internals, argc, argv);
6422 * Migrate print-drivers from a print-server
6424 * @param argc Standard main() style argc
6425 * @param argv Standard main() style argv. Initial components are already
6428 * @return A shell status integer (0 for success)
6430 static int rpc_printer_migrate_drivers(int argc, const char **argv)
6433 printf("no server to migrate\n");
6437 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6438 rpc_printer_migrate_drivers_internals,
6443 * Migrate print-forms from a print-server
6445 * @param argc Standard main() style argc
6446 * @param argv Standard main() style argv. Initial components are already
6449 * @return A shell status integer (0 for success)
6451 static int rpc_printer_migrate_forms(int argc, const char **argv)
6454 printf("no server to migrate\n");
6458 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6459 rpc_printer_migrate_forms_internals,
6464 * Migrate printers from a print-server
6466 * @param argc Standard main() style argc
6467 * @param argv Standard main() style argv. Initial components are already
6470 * @return A shell status integer (0 for success)
6472 static int rpc_printer_migrate_printers(int argc, const char **argv)
6475 printf("no server to migrate\n");
6479 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6480 rpc_printer_migrate_printers_internals,
6485 * Migrate printer-ACLs from a print-server
6487 * @param argc Standard main() style argc
6488 * @param argv Standard main() style argv. Initial components are already
6491 * @return A shell status integer (0 for success)
6493 static int rpc_printer_migrate_security(int argc, const char **argv)
6496 printf("no server to migrate\n");
6500 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6501 rpc_printer_migrate_security_internals,
6506 * Migrate printer-settings from a print-server
6508 * @param argc Standard main() style argc
6509 * @param argv Standard main() style argv. Initial components are already
6512 * @return A shell status integer (0 for success)
6514 static int rpc_printer_migrate_settings(int argc, const char **argv)
6517 printf("no server to migrate\n");
6521 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6522 rpc_printer_migrate_settings_internals,
6527 * 'net rpc printer' entrypoint.
6528 * @param argc Standard main() style argc
6529 * @param argv Standard main() style argv. Initial components are already
6533 int rpc_printer_migrate(int argc, const char **argv)
6536 /* ouch: when addriver and setdriver are called from within
6537 rpc_printer_migrate_drivers_internals, the printer-queue already
6540 struct functable func[] = {
6541 {"all", rpc_printer_migrate_all},
6542 {"drivers", rpc_printer_migrate_drivers},
6543 {"forms", rpc_printer_migrate_forms},
6544 {"help", rpc_printer_usage},
6545 {"printers", rpc_printer_migrate_printers},
6546 {"security", rpc_printer_migrate_security},
6547 {"settings", rpc_printer_migrate_settings},
6551 return net_run_function(argc, argv, func, rpc_printer_usage);
6556 * List printers on a remote RPC server
6558 * @param argc Standard main() style argc
6559 * @param argv Standard main() style argv. Initial components are already
6562 * @return A shell status integer (0 for success)
6564 static int rpc_printer_list(int argc, const char **argv)
6567 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6568 rpc_printer_list_internals,
6573 * List printer-drivers on a remote RPC server
6575 * @param argc Standard main() style argc
6576 * @param argv Standard main() style argv. Initial components are already
6579 * @return A shell status integer (0 for success)
6581 static int rpc_printer_driver_list(int argc, const char **argv)
6584 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6585 rpc_printer_driver_list_internals,
6590 * Publish printer in ADS via MSRPC
6592 * @param argc Standard main() style argc
6593 * @param argv Standard main() style argv. Initial components are already
6596 * @return A shell status integer (0 for success)
6598 static int rpc_printer_publish_publish(int argc, const char **argv)
6601 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6602 rpc_printer_publish_publish_internals,
6607 * Update printer in ADS via MSRPC
6609 * @param argc Standard main() style argc
6610 * @param argv Standard main() style argv. Initial components are already
6613 * @return A shell status integer (0 for success)
6615 static int rpc_printer_publish_update(int argc, const char **argv)
6618 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6619 rpc_printer_publish_update_internals,
6624 * UnPublish printer in ADS via MSRPC
6626 * @param argc Standard main() style argc
6627 * @param argv Standard main() style argv. Initial components are already
6630 * @return A shell status integer (0 for success)
6632 static int rpc_printer_publish_unpublish(int argc, const char **argv)
6635 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6636 rpc_printer_publish_unpublish_internals,
6641 * List published printers via MSRPC
6643 * @param argc Standard main() style argc
6644 * @param argv Standard main() style argv. Initial components are already
6647 * @return A shell status integer (0 for success)
6649 static int rpc_printer_publish_list(int argc, const char **argv)
6652 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6653 rpc_printer_publish_list_internals,
6659 * Publish printer in ADS
6661 * @param argc Standard main() style argc
6662 * @param argv Standard main() style argv. Initial components are already
6665 * @return A shell status integer (0 for success)
6667 static int rpc_printer_publish(int argc, const char **argv)
6670 struct functable func[] = {
6671 {"publish", rpc_printer_publish_publish},
6672 {"update", rpc_printer_publish_update},
6673 {"unpublish", rpc_printer_publish_unpublish},
6674 {"list", rpc_printer_publish_list},
6675 {"help", rpc_printer_usage},
6680 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6681 rpc_printer_publish_list_internals,
6684 return net_run_function(argc, argv, func, rpc_printer_usage);
6690 * Display rpc printer help page.
6691 * @param argc Standard main() style argc
6692 * @param argv Standard main() style argv. Initial components are already
6695 int rpc_printer_usage(int argc, const char **argv)
6697 return net_help_printer(argc, argv);
6701 * 'net rpc printer' entrypoint.
6702 * @param argc Standard main() style argc
6703 * @param argv Standard main() style argv. Initial components are already
6706 int net_rpc_printer(int argc, const char **argv)
6708 struct functable func[] = {
6709 {"list", rpc_printer_list},
6710 {"migrate", rpc_printer_migrate},
6711 {"driver", rpc_printer_driver_list},
6712 {"publish", rpc_printer_publish},
6717 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6718 rpc_printer_list_internals,
6721 return net_run_function(argc, argv, func, rpc_printer_usage);
6724 /****************************************************************************/
6728 * Basic usage function for 'net rpc'
6729 * @param argc Standard main() style argc
6730 * @param argv Standard main() style argv. Initial components are already
6734 int net_rpc_usage(int argc, const char **argv)
6736 d_printf(" net rpc info \t\t\tshow basic info about a domain \n");
6737 d_printf(" net rpc join \t\t\tto join a domain \n");
6738 d_printf(" net rpc oldjoin \t\tto join a domain created in server manager\n");
6739 d_printf(" net rpc testjoin \t\ttests that a join is valid\n");
6740 d_printf(" net rpc user \t\t\tto add, delete and list users\n");
6741 d_printf(" net rpc password <username> [<password>] -Uadmin_username%%admin_pass\n");
6742 d_printf(" net rpc group \t\tto list groups\n");
6743 d_printf(" net rpc share \t\tto add, delete, list and migrate shares\n");
6744 d_printf(" net rpc printer \t\tto list and migrate printers\n");
6745 d_printf(" net rpc file \t\t\tto list open files\n");
6746 d_printf(" net rpc changetrustpw \tto change the trust account password\n");
6747 d_printf(" net rpc getsid \t\tfetch the domain sid into the local secrets.tdb\n");
6748 d_printf(" net rpc vampire \t\tsyncronise an NT PDC's users and groups into the local passdb\n");
6749 d_printf(" net rpc samdump \t\tdisplay an NT PDC's users, groups and other data\n");
6750 d_printf(" net rpc trustdom \t\tto create trusting domain's account or establish trust\n");
6751 d_printf(" net rpc abortshutdown \tto abort the shutdown of a remote server\n");
6752 d_printf(" net rpc shutdown \t\tto shutdown a remote server\n");
6753 d_printf(" net rpc rights\t\tto manage privileges assigned to SIDs\n");
6754 d_printf(" net rpc registry\t\tto manage registry hives\n");
6755 d_printf(" net rpc service\t\tto start, stop and query services\n");
6756 d_printf(" net rpc audit\t\t\tto modify global auditing settings\n");
6757 d_printf(" net rpc shell\t\t\tto open an interactive shell for remote server/account management\n");
6759 d_printf("'net rpc shutdown' also accepts the following miscellaneous options:\n"); /* misc options */
6760 d_printf("\t-r or --reboot\trequest remote server reboot on shutdown\n");
6761 d_printf("\t-f or --force\trequest the remote server force its shutdown\n");
6762 d_printf("\t-t or --timeout=<timeout>\tnumber of seconds before shutdown\n");
6763 d_printf("\t-C or --comment=<message>\ttext message to display on impending shutdown\n");
6769 * Help function for 'net rpc'. Calls command specific help if requested
6770 * or displays usage of net rpc
6771 * @param argc Standard main() style argc
6772 * @param argv Standard main() style argv. Initial components are already
6776 int net_rpc_help(int argc, const char **argv)
6778 struct functable func[] = {
6779 {"join", rpc_join_usage},
6780 {"user", rpc_user_usage},
6781 {"group", rpc_group_usage},
6782 {"share", rpc_share_usage},
6783 /*{"changetrustpw", rpc_changetrustpw_usage}, */
6784 {"trustdom", rpc_trustdom_usage},
6785 /*{"abortshutdown", rpc_shutdown_abort_usage},*/
6786 /*{"shutdown", rpc_shutdown_usage}, */
6787 {"vampire", rpc_vampire_usage},
6792 net_rpc_usage(argc, argv);
6796 return (net_run_function(argc, argv, func, rpc_user_usage));
6800 * 'net rpc' entrypoint.
6801 * @param argc Standard main() style argc
6802 * @param argv Standard main() style argv. Initial components are already
6806 int net_rpc(int argc, const char **argv)
6808 struct functable func[] = {
6809 {"audit", net_rpc_audit},
6810 {"info", net_rpc_info},
6811 {"join", net_rpc_join},
6812 {"oldjoin", net_rpc_oldjoin},
6813 {"testjoin", net_rpc_testjoin},
6814 {"user", net_rpc_user},
6815 {"password", rpc_user_password},
6816 {"group", net_rpc_group},
6817 {"share", net_rpc_share},
6818 {"file", net_rpc_file},
6819 {"printer", net_rpc_printer},
6820 {"changetrustpw", net_rpc_changetrustpw},
6821 {"trustdom", rpc_trustdom},
6822 {"abortshutdown", rpc_shutdown_abort},
6823 {"shutdown", rpc_shutdown},
6824 {"samdump", rpc_samdump},
6825 {"vampire", rpc_vampire},
6826 {"getsid", net_rpc_getsid},
6827 {"rights", net_rpc_rights},
6828 {"service", net_rpc_service},
6829 {"registry", net_rpc_registry},
6830 {"shell", net_rpc_shell},
6831 {"help", net_rpc_help},
6834 return net_run_function(argc, argv, func, net_rpc_usage);