2 Samba Unix/Linux SMB client library
3 Distributed SMB/CIFS Server Management Utility
4 Copyright (C) 2001 Andrew Bartlett (abartlet@samba.org)
5 Copyright (C) 2002 Jim McDonough (jmcd@us.ibm.com)
6 Copyright (C) 2004 Guenther Deschner (gd@samba.org)
7 Copyright (C) 2005 Jeremy Allison (jra@samba.org)
8 Copyright (C) 2006 Jelmer Vernooij (jelmer@samba.org)
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>. */
24 #include "utils/net.h"
26 static int net_mode_share;
27 static bool sync_files(struct copy_clistate *cp_clistate, const char *mask);
32 * @brief RPC based subcommands for the 'net' utility.
34 * This file should contain much of the functionality that used to
35 * be found in rpcclient, execpt that the commands should change
36 * less often, and the fucntionality should be sane (the user is not
37 * expected to know a rid/sid before they conduct an operation etc.)
39 * @todo Perhaps eventually these should be split out into a number
40 * of files, as this could get quite big.
45 * Many of the RPC functions need the domain sid. This function gets
46 * it at the start of every run
48 * @param cli A cli_state already connected to the remote machine
50 * @return The Domain SID of the remote machine.
53 NTSTATUS net_get_remote_domain_sid(struct cli_state *cli, TALLOC_CTX *mem_ctx,
55 const char **domain_name)
57 struct rpc_pipe_client *lsa_pipe;
59 NTSTATUS result = NT_STATUS_OK;
60 uint32 info_class = 5;
62 lsa_pipe = cli_rpc_pipe_open_noauth(cli, PI_LSARPC, &result);
64 d_fprintf(stderr, "Could not initialise lsa pipe\n");
68 result = rpccli_lsa_open_policy(lsa_pipe, mem_ctx, False,
69 SEC_RIGHTS_MAXIMUM_ALLOWED,
71 if (!NT_STATUS_IS_OK(result)) {
72 d_fprintf(stderr, "open_policy failed: %s\n",
77 result = rpccli_lsa_query_info_policy(lsa_pipe, mem_ctx, &pol,
78 info_class, domain_name,
80 if (!NT_STATUS_IS_OK(result)) {
81 d_fprintf(stderr, "lsaquery failed: %s\n",
86 rpccli_lsa_Close(lsa_pipe, mem_ctx, &pol);
87 cli_rpc_pipe_close(lsa_pipe);
93 * Run a single RPC command, from start to finish.
95 * @param pipe_name the pipe to connect to (usually a PIPE_ constant)
96 * @param conn_flag a NET_FLAG_ combination. Passed to
97 * net_make_ipc_connection.
98 * @param argc Standard main() style argc
99 * @param argc Standard main() style argv. Initial components are already
101 * @return A shell status integer (0 for success)
104 int run_rpc_command(struct cli_state *cli_arg,
111 struct cli_state *cli = NULL;
112 struct rpc_pipe_client *pipe_hnd = NULL;
116 const char *domain_name;
118 /* make use of cli_state handed over as an argument, if possible */
120 nt_status = net_make_ipc_connection(conn_flags, &cli);
121 if (!NT_STATUS_IS_OK(nt_status)) {
122 DEBUG(1, ("failed to make ipc connection: %s\n",
123 nt_errstr(nt_status)));
136 if (!(mem_ctx = talloc_init("run_rpc_command"))) {
137 DEBUG(0, ("talloc_init() failed\n"));
142 nt_status = net_get_remote_domain_sid(cli, mem_ctx, &domain_sid,
144 if (!NT_STATUS_IS_OK(nt_status)) {
149 if (!(conn_flags & NET_FLAGS_NO_PIPE)) {
150 if (lp_client_schannel() && (pipe_idx == PI_NETLOGON)) {
151 /* Always try and create an schannel netlogon pipe. */
152 pipe_hnd = cli_rpc_pipe_open_schannel(cli, pipe_idx,
153 PIPE_AUTH_LEVEL_PRIVACY,
157 DEBUG(0, ("Could not initialise schannel netlogon pipe. Error was %s\n",
158 nt_errstr(nt_status) ));
163 pipe_hnd = cli_rpc_pipe_open_noauth(cli, pipe_idx, &nt_status);
165 DEBUG(0, ("Could not initialise pipe %s. Error was %s\n",
166 cli_get_pipe_name(pipe_idx),
167 nt_errstr(nt_status) ));
174 nt_status = fn(domain_sid, domain_name, cli, pipe_hnd, mem_ctx, argc, argv);
176 if (!NT_STATUS_IS_OK(nt_status)) {
177 DEBUG(1, ("rpc command function failed! (%s)\n", nt_errstr(nt_status)));
179 DEBUG(5, ("rpc command function succedded\n"));
182 if (!(conn_flags & NET_FLAGS_NO_PIPE)) {
184 cli_rpc_pipe_close(pipe_hnd);
188 /* close the connection only if it was opened here */
193 talloc_destroy(mem_ctx);
194 return (!NT_STATUS_IS_OK(nt_status));
198 * Force a change of the trust acccount password.
200 * All parameters are provided by the run_rpc_command function, except for
201 * argc, argv which are passes through.
203 * @param domain_sid The domain sid aquired from the remote server
204 * @param cli A cli_state connected to the server.
205 * @param mem_ctx Talloc context, destoyed on compleation of the function.
206 * @param argc Standard main() style argc
207 * @param argc Standard main() style argv. Initial components are already
210 * @return Normal NTSTATUS return.
213 static NTSTATUS rpc_changetrustpw_internals(const DOM_SID *domain_sid,
214 const char *domain_name,
215 struct cli_state *cli,
216 struct rpc_pipe_client *pipe_hnd,
222 return trust_pw_find_change_and_store_it(pipe_hnd, mem_ctx, opt_target_workgroup);
226 * Force a change of the trust acccount password.
228 * @param argc Standard main() style argc
229 * @param argc Standard main() style argv. Initial components are already
232 * @return A shell status integer (0 for success)
235 int net_rpc_changetrustpw(int argc, const char **argv)
237 return run_rpc_command(NULL, PI_NETLOGON, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC,
238 rpc_changetrustpw_internals,
243 * Join a domain, the old way.
245 * This uses 'machinename' as the inital password, and changes it.
247 * The password should be created with 'server manager' or equiv first.
249 * All parameters are provided by the run_rpc_command function, except for
250 * argc, argv which are passes through.
252 * @param domain_sid The domain sid aquired from the remote server
253 * @param cli A cli_state connected to the server.
254 * @param mem_ctx Talloc context, destoyed on compleation of the function.
255 * @param argc Standard main() style argc
256 * @param argc Standard main() style argv. Initial components are already
259 * @return Normal NTSTATUS return.
262 static NTSTATUS rpc_oldjoin_internals(const DOM_SID *domain_sid,
263 const char *domain_name,
264 struct cli_state *cli,
265 struct rpc_pipe_client *pipe_hnd,
271 fstring trust_passwd;
272 unsigned char orig_trust_passwd_hash[16];
274 uint32 sec_channel_type;
276 pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_NETLOGON, &result);
278 DEBUG(0,("rpc_oldjoin_internals: netlogon pipe open to machine %s failed. "
281 nt_errstr(result) ));
286 check what type of join - if the user want's to join as
287 a BDC, the server must agree that we are a BDC.
290 sec_channel_type = get_sec_channel_type(argv[0]);
292 sec_channel_type = get_sec_channel_type(NULL);
295 fstrcpy(trust_passwd, global_myname());
296 strlower_m(trust_passwd);
299 * Machine names can be 15 characters, but the max length on
300 * a password is 14. --jerry
303 trust_passwd[14] = '\0';
305 E_md4hash(trust_passwd, orig_trust_passwd_hash);
307 result = trust_pw_change_and_store_it(pipe_hnd, mem_ctx, opt_target_workgroup,
308 orig_trust_passwd_hash,
311 if (NT_STATUS_IS_OK(result))
312 printf("Joined domain %s.\n",opt_target_workgroup);
315 if (!secrets_store_domain_sid(opt_target_workgroup, domain_sid)) {
316 DEBUG(0, ("error storing domain sid for %s\n", opt_target_workgroup));
317 result = NT_STATUS_UNSUCCESSFUL;
324 * Join a domain, the old way.
326 * @param argc Standard main() style argc
327 * @param argc Standard main() style argv. Initial components are already
330 * @return A shell status integer (0 for success)
333 static int net_rpc_perform_oldjoin(int argc, const char **argv)
335 return run_rpc_command(NULL, PI_NETLOGON,
336 NET_FLAGS_NO_PIPE | NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC,
337 rpc_oldjoin_internals,
342 * Join a domain, the old way. This function exists to allow
343 * the message to be displayed when oldjoin was explicitly
344 * requested, but not when it was implied by "net rpc join"
346 * @param argc Standard main() style argc
347 * @param argc Standard main() style argv. Initial components are already
350 * @return A shell status integer (0 for success)
353 static int net_rpc_oldjoin(int argc, const char **argv)
355 int rc = net_rpc_perform_oldjoin(argc, argv);
358 d_fprintf(stderr, "Failed to join domain\n");
365 * Basic usage function for 'net rpc join'
366 * @param argc Standard main() style argc
367 * @param argc Standard main() style argv. Initial components are already
371 static int rpc_join_usage(int argc, const char **argv)
373 d_printf("net rpc join -U <username>[%%password] <type>[options]\n"\
374 "\t to join a domain with admin username & password\n"\
375 "\t\t password will be prompted if needed and none is specified\n"\
376 "\t <type> can be (default MEMBER)\n"\
377 "\t\t BDC - Join as a BDC\n"\
378 "\t\t PDC - Join as a PDC\n"\
379 "\t\t MEMBER - Join as a MEMBER server\n");
381 net_common_flags_usage(argc, argv);
386 * 'net rpc join' entrypoint.
387 * @param argc Standard main() style argc
388 * @param argc Standard main() style argv. Initial components are already
391 * Main 'net_rpc_join()' (where the admain username/password is used) is
393 * Try to just change the password, but if that doesn't work, use/prompt
394 * for a username/password.
397 int net_rpc_join(int argc, const char **argv)
399 if (lp_server_role() == ROLE_STANDALONE) {
400 d_printf("cannot join as standalone machine\n");
404 if (strlen(global_myname()) > 15) {
405 d_printf("Our netbios name can be at most 15 chars long, "
406 "\"%s\" is %u chars long\n",
407 global_myname(), (unsigned int)strlen(global_myname()));
411 if ((net_rpc_perform_oldjoin(argc, argv) == 0))
414 return net_rpc_join_newstyle(argc, argv);
418 * display info about a rpc domain
420 * All parameters are provided by the run_rpc_command function, except for
421 * argc, argv which are passed through.
423 * @param domain_sid The domain sid acquired from the remote server
424 * @param cli A cli_state connected to the server.
425 * @param mem_ctx Talloc context, destoyed on completion of the function.
426 * @param argc Standard main() style argc
427 * @param argv Standard main() style argv. Initial components are already
430 * @return Normal NTSTATUS return.
433 NTSTATUS rpc_info_internals(const DOM_SID *domain_sid,
434 const char *domain_name,
435 struct cli_state *cli,
436 struct rpc_pipe_client *pipe_hnd,
441 POLICY_HND connect_pol, domain_pol;
442 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
446 sid_to_fstring(sid_str, domain_sid);
448 /* Get sam policy handle */
449 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
451 if (!NT_STATUS_IS_OK(result)) {
452 d_fprintf(stderr, "Could not connect to SAM: %s\n", nt_errstr(result));
456 /* Get domain policy handle */
457 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
458 MAXIMUM_ALLOWED_ACCESS,
459 domain_sid, &domain_pol);
460 if (!NT_STATUS_IS_OK(result)) {
461 d_fprintf(stderr, "Could not open domain: %s\n", nt_errstr(result));
466 result = rpccli_samr_query_dom_info(pipe_hnd, mem_ctx, &domain_pol,
468 if (NT_STATUS_IS_OK(result)) {
469 TALLOC_CTX *ctx = talloc_init("rpc_info_internals");
470 d_printf("Domain Name: %s\n", unistr2_to_ascii_talloc(ctx, &ctr.info.inf2.uni_domain));
471 d_printf("Domain SID: %s\n", sid_str);
472 d_printf("Sequence number: %llu\n", (unsigned long long)ctr.info.inf2.seq_num);
473 d_printf("Num users: %u\n", ctr.info.inf2.num_domain_usrs);
474 d_printf("Num domain groups: %u\n", ctr.info.inf2.num_domain_grps);
475 d_printf("Num local groups: %u\n", ctr.info.inf2.num_local_grps);
484 * 'net rpc info' entrypoint.
485 * @param argc Standard main() style argc
486 * @param argc Standard main() style argv. Initial components are already
490 int net_rpc_info(int argc, const char **argv)
492 return run_rpc_command(NULL, PI_SAMR, NET_FLAGS_PDC,
498 * Fetch domain SID into the local secrets.tdb
500 * All parameters are provided by the run_rpc_command function, except for
501 * argc, argv which are passes through.
503 * @param domain_sid The domain sid acquired from the remote server
504 * @param cli A cli_state connected to the server.
505 * @param mem_ctx Talloc context, destoyed on completion of the function.
506 * @param argc Standard main() style argc
507 * @param argv Standard main() style argv. Initial components are already
510 * @return Normal NTSTATUS return.
513 static NTSTATUS rpc_getsid_internals(const DOM_SID *domain_sid,
514 const char *domain_name,
515 struct cli_state *cli,
516 struct rpc_pipe_client *pipe_hnd,
523 sid_to_fstring(sid_str, domain_sid);
524 d_printf("Storing SID %s for Domain %s in secrets.tdb\n",
525 sid_str, domain_name);
527 if (!secrets_store_domain_sid(domain_name, domain_sid)) {
528 DEBUG(0,("Can't store domain SID\n"));
529 return NT_STATUS_UNSUCCESSFUL;
536 * 'net rpc getsid' entrypoint.
537 * @param argc Standard main() style argc
538 * @param argc Standard main() style argv. Initial components are already
542 int net_rpc_getsid(int argc, const char **argv)
544 return run_rpc_command(NULL, PI_SAMR, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC,
545 rpc_getsid_internals,
549 /****************************************************************************/
552 * Basic usage function for 'net rpc user'
553 * @param argc Standard main() style argc.
554 * @param argv Standard main() style argv. Initial components are already
558 static int rpc_user_usage(int argc, const char **argv)
560 return net_help_user(argc, argv);
564 * Add a new user to a remote RPC server
566 * All parameters are provided by the run_rpc_command function, except for
567 * argc, argv which are passes through.
569 * @param domain_sid The domain sid acquired from the remote server
570 * @param cli A cli_state connected to the server.
571 * @param mem_ctx Talloc context, destoyed on completion of the function.
572 * @param argc Standard main() style argc
573 * @param argv Standard main() style argv. Initial components are already
576 * @return Normal NTSTATUS return.
579 static NTSTATUS rpc_user_add_internals(const DOM_SID *domain_sid,
580 const char *domain_name,
581 struct cli_state *cli,
582 struct rpc_pipe_client *pipe_hnd,
584 int argc, const char **argv)
587 POLICY_HND connect_pol, domain_pol, user_pol;
588 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
589 const char *acct_name;
591 uint32 acct_flags, user_rid;
594 d_printf("User must be specified\n");
595 rpc_user_usage(argc, argv);
601 /* Get sam policy handle */
603 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
605 if (!NT_STATUS_IS_OK(result)) {
609 /* Get domain policy handle */
611 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
612 MAXIMUM_ALLOWED_ACCESS,
613 domain_sid, &domain_pol);
614 if (!NT_STATUS_IS_OK(result)) {
618 /* Create domain user */
620 acb_info = ACB_NORMAL;
621 acct_flags = SAMR_GENERIC_READ | SAMR_GENERIC_WRITE |
622 SAMR_GENERIC_EXECUTE | SAMR_STANDARD_WRITEDAC |
623 SAMR_STANDARD_DELETE | SAMR_USER_SETPASS | SAMR_USER_GETATTR |
626 result = rpccli_samr_create_dom_user(pipe_hnd, mem_ctx, &domain_pol,
627 acct_name, acb_info, acct_flags,
628 &user_pol, &user_rid);
629 if (!NT_STATUS_IS_OK(result)) {
635 uint32 *user_rids, num_rids, *name_types;
636 uint32 flags = 0x000003e8; /* Unknown */
637 SAM_USERINFO_CTR ctr;
638 SAM_USER_INFO_24 p24;
641 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol,
642 flags, 1, &acct_name,
643 &num_rids, &user_rids,
646 if (!NT_STATUS_IS_OK(result)) {
650 result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
651 MAXIMUM_ALLOWED_ACCESS,
652 user_rids[0], &user_pol);
654 if (!NT_STATUS_IS_OK(result)) {
658 /* Set password on account */
663 encode_pw_buffer(pwbuf, argv[1], STR_UNICODE);
665 init_sam_user_info24(&p24, (char *)pwbuf,24);
667 ctr.switch_value = 24;
668 ctr.info.id24 = &p24;
670 result = rpccli_samr_set_userinfo(pipe_hnd, mem_ctx, &user_pol, 24,
671 &cli->user_session_key, &ctr);
673 if (!NT_STATUS_IS_OK(result)) {
674 d_fprintf(stderr, "Failed to set password for user %s - %s\n",
675 acct_name, nt_errstr(result));
677 result = rpccli_samr_delete_dom_user(pipe_hnd, mem_ctx, &user_pol);
679 if (!NT_STATUS_IS_OK(result)) {
680 d_fprintf(stderr, "Failed to delete user %s - %s\n",
681 acct_name, nt_errstr(result));
688 if (!NT_STATUS_IS_OK(result)) {
689 d_fprintf(stderr, "Failed to add user '%s' with %s.\n",
690 acct_name, nt_errstr(result));
692 d_printf("Added user '%s'.\n", acct_name);
698 * Add a new user to a remote RPC server
700 * @param argc Standard main() style argc
701 * @param argv Standard main() style argv. Initial components are already
704 * @return A shell status integer (0 for success)
707 static int rpc_user_add(int argc, const char **argv)
709 return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_add_internals,
714 * Delete a user from a remote RPC server
716 * All parameters are provided by the run_rpc_command function, except for
717 * argc, argv which are passes through.
719 * @param domain_sid The domain sid acquired from the remote server
720 * @param cli A cli_state connected to the server.
721 * @param mem_ctx Talloc context, destoyed on completion of the function.
722 * @param argc Standard main() style argc
723 * @param argv Standard main() style argv. Initial components are already
726 * @return Normal NTSTATUS return.
729 static NTSTATUS rpc_user_del_internals(const DOM_SID *domain_sid,
730 const char *domain_name,
731 struct cli_state *cli,
732 struct rpc_pipe_client *pipe_hnd,
737 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
738 POLICY_HND connect_pol, domain_pol, user_pol;
739 const char *acct_name;
742 d_printf("User must be specified\n");
743 rpc_user_usage(argc, argv);
749 /* Get sam policy and domain handles */
751 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
754 if (!NT_STATUS_IS_OK(result)) {
758 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
759 MAXIMUM_ALLOWED_ACCESS,
760 domain_sid, &domain_pol);
762 if (!NT_STATUS_IS_OK(result)) {
766 /* Get handle on user */
769 uint32 *user_rids, num_rids, *name_types;
770 uint32 flags = 0x000003e8; /* Unknown */
772 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol,
773 flags, 1, &acct_name,
774 &num_rids, &user_rids,
777 if (!NT_STATUS_IS_OK(result)) {
781 result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
782 MAXIMUM_ALLOWED_ACCESS,
783 user_rids[0], &user_pol);
785 if (!NT_STATUS_IS_OK(result)) {
792 result = rpccli_samr_delete_dom_user(pipe_hnd, mem_ctx, &user_pol);
794 if (!NT_STATUS_IS_OK(result)) {
799 if (!NT_STATUS_IS_OK(result)) {
800 d_fprintf(stderr, "Failed to delete user '%s' with %s.\n",
801 acct_name, nt_errstr(result));
803 d_printf("Deleted user '%s'.\n", acct_name);
810 * Rename a user on a remote RPC server
812 * All parameters are provided by the run_rpc_command function, except for
813 * argc, argv which are passes through.
815 * @param domain_sid The domain sid acquired from the remote server
816 * @param cli A cli_state connected to the server.
817 * @param mem_ctx Talloc context, destoyed on completion of the function.
818 * @param argc Standard main() style argc
819 * @param argv Standard main() style argv. Initial components are already
822 * @return Normal NTSTATUS return.
825 static NTSTATUS rpc_user_rename_internals(const DOM_SID *domain_sid,
826 const char *domain_name,
827 struct cli_state *cli,
828 struct rpc_pipe_client *pipe_hnd,
833 POLICY_HND connect_pol, domain_pol, user_pol;
834 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
835 uint32 info_level = 7;
836 const char *old_name, *new_name;
838 uint32 flags = 0x000003e8; /* Unknown */
839 uint32 num_rids, *name_types;
840 uint32 num_names = 1;
842 SAM_USERINFO_CTR *user_ctr;
843 SAM_USERINFO_CTR ctr;
844 SAM_USER_INFO_7 info7;
847 d_printf("Old and new username must be specified\n");
848 rpc_user_usage(argc, argv);
856 ZERO_STRUCT(user_ctr);
858 /* Get sam policy handle */
860 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
862 if (!NT_STATUS_IS_OK(result)) {
866 /* Get domain policy handle */
868 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
869 MAXIMUM_ALLOWED_ACCESS,
870 domain_sid, &domain_pol);
871 if (!NT_STATUS_IS_OK(result)) {
875 if ((names = TALLOC_ARRAY(mem_ctx, const char *, num_names)) == NULL) {
876 result = NT_STATUS_NO_MEMORY;
880 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol,
881 flags, num_names, names,
882 &num_rids, &user_rid, &name_types);
883 if (!NT_STATUS_IS_OK(result)) {
887 /* Open domain user */
888 result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
889 MAXIMUM_ALLOWED_ACCESS, user_rid[0], &user_pol);
891 if (!NT_STATUS_IS_OK(result)) {
895 /* Query user info */
896 result = rpccli_samr_query_userinfo(pipe_hnd, mem_ctx, &user_pol,
897 info_level, &user_ctr);
899 if (!NT_STATUS_IS_OK(result)) {
903 ctr.switch_value = info_level;
904 ctr.info.id7 = &info7;
906 init_sam_user_info7(&info7, new_name);
909 result = rpccli_samr_set_userinfo(pipe_hnd, mem_ctx, &user_pol,
910 info_level, &cli->user_session_key, &ctr);
912 if (!NT_STATUS_IS_OK(result)) {
917 if (!NT_STATUS_IS_OK(result)) {
918 d_fprintf(stderr, "Failed to rename user from %s to %s - %s\n", old_name, new_name,
921 d_printf("Renamed user from %s to %s\n", old_name, new_name);
927 * Rename a user on a remote RPC server
929 * @param argc Standard main() style argc
930 * @param argv Standard main() style argv. Initial components are already
933 * @return A shell status integer (0 for success)
936 static int rpc_user_rename(int argc, const char **argv)
938 return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_rename_internals,
943 * Delete a user from a remote RPC server
945 * @param argc Standard main() style argc
946 * @param argv Standard main() style argv. Initial components are already
949 * @return A shell status integer (0 for success)
952 static int rpc_user_delete(int argc, const char **argv)
954 return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_del_internals,
959 * Set a password for a user on a remote RPC server
961 * All parameters are provided by the run_rpc_command function, except for
962 * argc, argv which are passes through.
964 * @param domain_sid The domain sid acquired from the remote server
965 * @param cli A cli_state connected to the server.
966 * @param mem_ctx Talloc context, destoyed on completion of the function.
967 * @param argc Standard main() style argc
968 * @param argv Standard main() style argv. Initial components are already
971 * @return Normal NTSTATUS return.
974 static NTSTATUS rpc_user_password_internals(const DOM_SID *domain_sid,
975 const char *domain_name,
976 struct cli_state *cli,
977 struct rpc_pipe_client *pipe_hnd,
982 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
983 POLICY_HND connect_pol, domain_pol, user_pol;
984 SAM_USERINFO_CTR ctr;
985 SAM_USER_INFO_24 p24;
988 const char *new_password;
992 d_printf("User must be specified\n");
993 rpc_user_usage(argc, argv);
1000 new_password = argv[1];
1002 asprintf(&prompt, "Enter new password for %s:", user);
1003 new_password = getpass(prompt);
1007 /* Get sam policy and domain handles */
1009 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1012 if (!NT_STATUS_IS_OK(result)) {
1016 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
1017 MAXIMUM_ALLOWED_ACCESS,
1018 domain_sid, &domain_pol);
1020 if (!NT_STATUS_IS_OK(result)) {
1024 /* Get handle on user */
1027 uint32 *user_rids, num_rids, *name_types;
1028 uint32 flags = 0x000003e8; /* Unknown */
1030 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol,
1032 &num_rids, &user_rids,
1035 if (!NT_STATUS_IS_OK(result)) {
1039 result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
1040 MAXIMUM_ALLOWED_ACCESS,
1041 user_rids[0], &user_pol);
1043 if (!NT_STATUS_IS_OK(result)) {
1048 /* Set password on account */
1053 encode_pw_buffer(pwbuf, new_password, STR_UNICODE);
1055 init_sam_user_info24(&p24, (char *)pwbuf,24);
1057 ctr.switch_value = 24;
1058 ctr.info.id24 = &p24;
1060 result = rpccli_samr_set_userinfo(pipe_hnd, mem_ctx, &user_pol, 24,
1061 &cli->user_session_key, &ctr);
1063 if (!NT_STATUS_IS_OK(result)) {
1067 /* Display results */
1075 * Set a user's password on a remote RPC server
1077 * @param argc Standard main() style argc
1078 * @param argv Standard main() style argv. Initial components are already
1081 * @return A shell status integer (0 for success)
1084 static int rpc_user_password(int argc, const char **argv)
1086 return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_password_internals,
1091 * List user's groups on a remote RPC server
1093 * All parameters are provided by the run_rpc_command function, except for
1094 * argc, argv which are passes through.
1096 * @param domain_sid The domain sid acquired from the remote server
1097 * @param cli A cli_state connected to the server.
1098 * @param mem_ctx Talloc context, destoyed on completion of the function.
1099 * @param argc Standard main() style argc
1100 * @param argv Standard main() style argv. Initial components are already
1103 * @return Normal NTSTATUS return.
1106 static NTSTATUS rpc_user_info_internals(const DOM_SID *domain_sid,
1107 const char *domain_name,
1108 struct cli_state *cli,
1109 struct rpc_pipe_client *pipe_hnd,
1110 TALLOC_CTX *mem_ctx,
1114 POLICY_HND connect_pol, domain_pol, user_pol;
1115 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1116 uint32 *rids, num_rids, *name_types, num_names;
1117 uint32 flags = 0x000003e8; /* Unknown */
1123 d_printf("User must be specified\n");
1124 rpc_user_usage(argc, argv);
1125 return NT_STATUS_OK;
1127 /* Get sam policy handle */
1129 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1131 if (!NT_STATUS_IS_OK(result)) goto done;
1133 /* Get domain policy handle */
1135 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
1136 MAXIMUM_ALLOWED_ACCESS,
1137 domain_sid, &domain_pol);
1138 if (!NT_STATUS_IS_OK(result)) goto done;
1140 /* Get handle on user */
1142 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol,
1144 &num_rids, &rids, &name_types);
1146 if (!NT_STATUS_IS_OK(result)) goto done;
1148 result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
1149 MAXIMUM_ALLOWED_ACCESS,
1150 rids[0], &user_pol);
1151 if (!NT_STATUS_IS_OK(result)) goto done;
1153 result = rpccli_samr_query_usergroups(pipe_hnd, mem_ctx, &user_pol,
1154 &num_rids, &user_gids);
1156 if (!NT_STATUS_IS_OK(result)) goto done;
1161 if ((rids = TALLOC_ARRAY(mem_ctx, uint32, num_rids)) == NULL) {
1162 result = NT_STATUS_NO_MEMORY;
1166 for (i = 0; i < num_rids; i++)
1167 rids[i] = user_gids[i].g_rid;
1169 result = rpccli_samr_lookup_rids(pipe_hnd, mem_ctx, &domain_pol,
1171 &num_names, &names, &name_types);
1173 if (!NT_STATUS_IS_OK(result)) {
1177 /* Display results */
1179 for (i = 0; i < num_names; i++)
1180 printf("%s\n", names[i]);
1187 * List a user's groups from a remote RPC server
1189 * @param argc Standard main() style argc
1190 * @param argv Standard main() style argv. Initial components are already
1193 * @return A shell status integer (0 for success)
1196 static int rpc_user_info(int argc, const char **argv)
1198 return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_info_internals,
1203 * List users on a remote RPC server
1205 * All parameters are provided by the run_rpc_command function, except for
1206 * argc, argv which are passes through.
1208 * @param domain_sid The domain sid acquired from the remote server
1209 * @param cli A cli_state connected to the server.
1210 * @param mem_ctx Talloc context, destoyed on completion of the function.
1211 * @param argc Standard main() style argc
1212 * @param argv Standard main() style argv. Initial components are already
1215 * @return Normal NTSTATUS return.
1218 static NTSTATUS rpc_user_list_internals(const DOM_SID *domain_sid,
1219 const char *domain_name,
1220 struct cli_state *cli,
1221 struct rpc_pipe_client *pipe_hnd,
1222 TALLOC_CTX *mem_ctx,
1226 POLICY_HND connect_pol, domain_pol;
1227 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1228 uint32 start_idx=0, num_entries, i, loop_count = 0;
1229 SAM_DISPINFO_CTR ctr;
1230 SAM_DISPINFO_1 info1;
1232 /* Get sam policy handle */
1234 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1236 if (!NT_STATUS_IS_OK(result)) {
1240 /* Get domain policy handle */
1242 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
1243 MAXIMUM_ALLOWED_ACCESS,
1244 domain_sid, &domain_pol);
1245 if (!NT_STATUS_IS_OK(result)) {
1249 /* Query domain users */
1252 ctr.sam.info1 = &info1;
1253 if (opt_long_list_entries)
1254 d_printf("\nUser name Comment"\
1255 "\n-----------------------------\n");
1258 uint32 max_entries, max_size;
1260 get_query_dispinfo_params(
1261 loop_count, &max_entries, &max_size);
1263 result = rpccli_samr_query_dispinfo(pipe_hnd, mem_ctx, &domain_pol,
1264 &start_idx, 1, &num_entries,
1265 max_entries, max_size, &ctr);
1268 for (i = 0; i < num_entries; i++) {
1269 unistr2_to_ascii(user, &(&ctr.sam.info1->str[i])->uni_acct_name, sizeof(user));
1270 if (opt_long_list_entries)
1271 unistr2_to_ascii(desc, &(&ctr.sam.info1->str[i])->uni_acct_desc, sizeof(desc));
1273 if (opt_long_list_entries)
1274 printf("%-21.21s %s\n", user, desc);
1276 printf("%s\n", user);
1278 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
1285 * 'net rpc user' entrypoint.
1286 * @param argc Standard main() style argc
1287 * @param argc Standard main() style argv. Initial components are already
1291 int net_rpc_user(int argc, const char **argv)
1293 struct functable func[] = {
1294 {"add", rpc_user_add},
1295 {"info", rpc_user_info},
1296 {"delete", rpc_user_delete},
1297 {"password", rpc_user_password},
1298 {"rename", rpc_user_rename},
1303 return run_rpc_command(NULL,PI_SAMR, 0,
1304 rpc_user_list_internals,
1308 return net_run_function(argc, argv, func, rpc_user_usage);
1311 static NTSTATUS rpc_sh_user_list(TALLOC_CTX *mem_ctx,
1312 struct rpc_sh_ctx *ctx,
1313 struct rpc_pipe_client *pipe_hnd,
1314 int argc, const char **argv)
1316 return rpc_user_list_internals(ctx->domain_sid, ctx->domain_name,
1317 ctx->cli, pipe_hnd, mem_ctx,
1321 static NTSTATUS rpc_sh_user_info(TALLOC_CTX *mem_ctx,
1322 struct rpc_sh_ctx *ctx,
1323 struct rpc_pipe_client *pipe_hnd,
1324 int argc, const char **argv)
1326 return rpc_user_info_internals(ctx->domain_sid, ctx->domain_name,
1327 ctx->cli, pipe_hnd, mem_ctx,
1331 static NTSTATUS rpc_sh_handle_user(TALLOC_CTX *mem_ctx,
1332 struct rpc_sh_ctx *ctx,
1333 struct rpc_pipe_client *pipe_hnd,
1334 int argc, const char **argv,
1336 TALLOC_CTX *mem_ctx,
1337 struct rpc_sh_ctx *ctx,
1338 struct rpc_pipe_client *pipe_hnd,
1339 const POLICY_HND *user_hnd,
1340 int argc, const char **argv))
1343 POLICY_HND connect_pol, domain_pol, user_pol;
1344 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1347 enum lsa_SidType type;
1350 d_fprintf(stderr, "usage: %s <username>\n", ctx->whoami);
1351 return NT_STATUS_INVALID_PARAMETER;
1354 ZERO_STRUCT(connect_pol);
1355 ZERO_STRUCT(domain_pol);
1356 ZERO_STRUCT(user_pol);
1358 result = net_rpc_lookup_name(mem_ctx, pipe_hnd->cli, argv[0],
1359 NULL, NULL, &sid, &type);
1360 if (!NT_STATUS_IS_OK(result)) {
1361 d_fprintf(stderr, "Could not lookup %s: %s\n", argv[0],
1366 if (type != SID_NAME_USER) {
1367 d_fprintf(stderr, "%s is a %s, not a user\n", argv[0],
1368 sid_type_lookup(type));
1369 result = NT_STATUS_NO_SUCH_USER;
1373 if (!sid_peek_check_rid(ctx->domain_sid, &sid, &rid)) {
1374 d_fprintf(stderr, "%s is not in our domain\n", argv[0]);
1375 result = NT_STATUS_NO_SUCH_USER;
1379 result = rpccli_samr_connect(pipe_hnd, mem_ctx,
1380 MAXIMUM_ALLOWED_ACCESS, &connect_pol);
1381 if (!NT_STATUS_IS_OK(result)) {
1385 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
1386 MAXIMUM_ALLOWED_ACCESS,
1387 ctx->domain_sid, &domain_pol);
1388 if (!NT_STATUS_IS_OK(result)) {
1392 result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
1393 MAXIMUM_ALLOWED_ACCESS,
1395 if (!NT_STATUS_IS_OK(result)) {
1399 result = fn(mem_ctx, ctx, pipe_hnd, &user_pol, argc-1, argv+1);
1402 if (is_valid_policy_hnd(&user_pol)) {
1403 rpccli_samr_close(pipe_hnd, mem_ctx, &user_pol);
1405 if (is_valid_policy_hnd(&domain_pol)) {
1406 rpccli_samr_close(pipe_hnd, mem_ctx, &domain_pol);
1408 if (is_valid_policy_hnd(&connect_pol)) {
1409 rpccli_samr_close(pipe_hnd, mem_ctx, &connect_pol);
1414 static NTSTATUS rpc_sh_user_show_internals(TALLOC_CTX *mem_ctx,
1415 struct rpc_sh_ctx *ctx,
1416 struct rpc_pipe_client *pipe_hnd,
1417 const POLICY_HND *user_hnd,
1418 int argc, const char **argv)
1421 SAM_USERINFO_CTR *ctr;
1422 SAM_USER_INFO_21 *info;
1425 d_fprintf(stderr, "usage: %s show <username>\n", ctx->whoami);
1426 return NT_STATUS_INVALID_PARAMETER;
1429 result = rpccli_samr_query_userinfo(pipe_hnd, mem_ctx, user_hnd,
1431 if (!NT_STATUS_IS_OK(result)) {
1435 info = ctr->info.id21;
1437 d_printf("user rid: %d, group rid: %d\n", info->user_rid,
1443 static NTSTATUS rpc_sh_user_show(TALLOC_CTX *mem_ctx,
1444 struct rpc_sh_ctx *ctx,
1445 struct rpc_pipe_client *pipe_hnd,
1446 int argc, const char **argv)
1448 return rpc_sh_handle_user(mem_ctx, ctx, pipe_hnd, argc, argv,
1449 rpc_sh_user_show_internals);
1452 #define FETCHSTR(name, rec) \
1453 do { if (strequal(ctx->thiscmd, name)) { \
1454 oldval = rpcstr_pull_unistr2_talloc(mem_ctx, &usr->uni_##rec); } \
1457 #define SETSTR(name, rec, flag) \
1458 do { if (strequal(ctx->thiscmd, name)) { \
1459 init_unistr2(&usr->uni_##rec, argv[0], UNI_STR_TERMINATE); \
1460 init_uni_hdr(&usr->hdr_##rec, &usr->uni_##rec); \
1461 usr->fields_present |= ACCT_##flag; } \
1464 static NTSTATUS rpc_sh_user_str_edit_internals(TALLOC_CTX *mem_ctx,
1465 struct rpc_sh_ctx *ctx,
1466 struct rpc_pipe_client *pipe_hnd,
1467 const POLICY_HND *user_hnd,
1468 int argc, const char **argv)
1471 SAM_USERINFO_CTR *ctr;
1472 SAM_USER_INFO_21 *usr;
1473 const char *username;
1474 const char *oldval = "";
1477 d_fprintf(stderr, "usage: %s <username> [new value|NULL]\n",
1479 return NT_STATUS_INVALID_PARAMETER;
1482 result = rpccli_samr_query_userinfo(pipe_hnd, mem_ctx, user_hnd,
1484 if (!NT_STATUS_IS_OK(result)) {
1488 usr = ctr->info.id21;
1490 username = rpcstr_pull_unistr2_talloc(mem_ctx, &usr->uni_user_name);
1492 FETCHSTR("fullname", full_name);
1493 FETCHSTR("homedir", home_dir);
1494 FETCHSTR("homedrive", dir_drive);
1495 FETCHSTR("logonscript", logon_script);
1496 FETCHSTR("profilepath", profile_path);
1497 FETCHSTR("description", acct_desc);
1500 d_printf("%s's %s: [%s]\n", username, ctx->thiscmd, oldval);
1506 if (strcmp(argv[0], "NULL") == 0) {
1510 SETSTR("fullname", full_name, FULL_NAME);
1511 SETSTR("homedir", home_dir, HOME_DIR);
1512 SETSTR("homedrive", dir_drive, HOME_DRIVE);
1513 SETSTR("logonscript", logon_script, LOGON_SCRIPT);
1514 SETSTR("profilepath", profile_path, PROFILE);
1515 SETSTR("description", acct_desc, DESCRIPTION);
1517 result = rpccli_samr_set_userinfo2(
1518 pipe_hnd, mem_ctx, user_hnd, 21,
1519 &pipe_hnd->cli->user_session_key, ctr);
1521 d_printf("Set %s's %s from [%s] to [%s]\n", username,
1522 ctx->thiscmd, oldval, argv[0]);
1529 #define HANDLEFLG(name, rec) \
1530 do { if (strequal(ctx->thiscmd, name)) { \
1531 oldval = (oldflags & ACB_##rec) ? "yes" : "no"; \
1533 newflags = oldflags | ACB_##rec; \
1535 newflags = oldflags & ~ACB_##rec; \
1538 static NTSTATUS rpc_sh_user_str_edit(TALLOC_CTX *mem_ctx,
1539 struct rpc_sh_ctx *ctx,
1540 struct rpc_pipe_client *pipe_hnd,
1541 int argc, const char **argv)
1543 return rpc_sh_handle_user(mem_ctx, ctx, pipe_hnd, argc, argv,
1544 rpc_sh_user_str_edit_internals);
1547 static NTSTATUS rpc_sh_user_flag_edit_internals(TALLOC_CTX *mem_ctx,
1548 struct rpc_sh_ctx *ctx,
1549 struct rpc_pipe_client *pipe_hnd,
1550 const POLICY_HND *user_hnd,
1551 int argc, const char **argv)
1554 SAM_USERINFO_CTR *ctr;
1555 SAM_USER_INFO_21 *usr;
1556 const char *username;
1557 const char *oldval = "unknown";
1558 uint32 oldflags, newflags;
1562 ((argc == 1) && !strequal(argv[0], "yes") &&
1563 !strequal(argv[0], "no"))) {
1564 d_fprintf(stderr, "usage: %s <username> [yes|no]\n",
1566 return NT_STATUS_INVALID_PARAMETER;
1569 newval = strequal(argv[0], "yes");
1571 result = rpccli_samr_query_userinfo(pipe_hnd, mem_ctx, user_hnd,
1573 if (!NT_STATUS_IS_OK(result)) {
1577 usr = ctr->info.id21;
1579 username = rpcstr_pull_unistr2_talloc(mem_ctx, &usr->uni_user_name);
1580 oldflags = usr->acb_info;
1581 newflags = usr->acb_info;
1583 HANDLEFLG("disabled", DISABLED);
1584 HANDLEFLG("pwnotreq", PWNOTREQ);
1585 HANDLEFLG("autolock", AUTOLOCK);
1586 HANDLEFLG("pwnoexp", PWNOEXP);
1589 d_printf("%s's %s flag: %s\n", username, ctx->thiscmd, oldval);
1595 usr->acb_info = newflags;
1596 usr->fields_present = ACCT_FLAGS;
1598 result = rpccli_samr_set_userinfo2(
1599 pipe_hnd, mem_ctx, user_hnd, 21,
1600 &pipe_hnd->cli->user_session_key, ctr);
1602 if (NT_STATUS_IS_OK(result)) {
1603 d_printf("Set %s's %s flag from [%s] to [%s]\n", username,
1604 ctx->thiscmd, oldval, argv[0]);
1612 static NTSTATUS rpc_sh_user_flag_edit(TALLOC_CTX *mem_ctx,
1613 struct rpc_sh_ctx *ctx,
1614 struct rpc_pipe_client *pipe_hnd,
1615 int argc, const char **argv)
1617 return rpc_sh_handle_user(mem_ctx, ctx, pipe_hnd, argc, argv,
1618 rpc_sh_user_flag_edit_internals);
1621 struct rpc_sh_cmd *net_rpc_user_edit_cmds(TALLOC_CTX *mem_ctx,
1622 struct rpc_sh_ctx *ctx)
1624 static struct rpc_sh_cmd cmds[] = {
1626 { "fullname", NULL, PI_SAMR, rpc_sh_user_str_edit,
1627 "Show/Set a user's full name" },
1629 { "homedir", NULL, PI_SAMR, rpc_sh_user_str_edit,
1630 "Show/Set a user's home directory" },
1632 { "homedrive", NULL, PI_SAMR, rpc_sh_user_str_edit,
1633 "Show/Set a user's home drive" },
1635 { "logonscript", NULL, PI_SAMR, rpc_sh_user_str_edit,
1636 "Show/Set a user's logon script" },
1638 { "profilepath", NULL, PI_SAMR, rpc_sh_user_str_edit,
1639 "Show/Set a user's profile path" },
1641 { "description", NULL, PI_SAMR, rpc_sh_user_str_edit,
1642 "Show/Set a user's description" },
1644 { "disabled", NULL, PI_SAMR, rpc_sh_user_flag_edit,
1645 "Show/Set whether a user is disabled" },
1647 { "autolock", NULL, PI_SAMR, rpc_sh_user_flag_edit,
1648 "Show/Set whether a user locked out" },
1650 { "pwnotreq", NULL, PI_SAMR, rpc_sh_user_flag_edit,
1651 "Show/Set whether a user does not need a password" },
1653 { "pwnoexp", NULL, PI_SAMR, rpc_sh_user_flag_edit,
1654 "Show/Set whether a user's password does not expire" },
1656 { NULL, NULL, 0, NULL, NULL }
1662 struct rpc_sh_cmd *net_rpc_user_cmds(TALLOC_CTX *mem_ctx,
1663 struct rpc_sh_ctx *ctx)
1665 static struct rpc_sh_cmd cmds[] = {
1667 { "list", NULL, PI_SAMR, rpc_sh_user_list,
1668 "List available users" },
1670 { "info", NULL, PI_SAMR, rpc_sh_user_info,
1671 "List the domain groups a user is member of" },
1673 { "show", NULL, PI_SAMR, rpc_sh_user_show,
1674 "Show info about a user" },
1676 { "edit", net_rpc_user_edit_cmds, 0, NULL,
1677 "Show/Modify a user's fields" },
1679 { NULL, NULL, 0, NULL, NULL }
1685 /****************************************************************************/
1688 * Basic usage function for 'net rpc group'
1689 * @param argc Standard main() style argc.
1690 * @param argv Standard main() style argv. Initial components are already
1694 static int rpc_group_usage(int argc, const char **argv)
1696 return net_help_group(argc, argv);
1700 * Delete group on a remote RPC server
1702 * All parameters are provided by the run_rpc_command function, except for
1703 * argc, argv which are passes through.
1705 * @param domain_sid The domain sid acquired from the remote server
1706 * @param cli A cli_state connected to the server.
1707 * @param mem_ctx Talloc context, destoyed on completion of the function.
1708 * @param argc Standard main() style argc
1709 * @param argv Standard main() style argv. Initial components are already
1712 * @return Normal NTSTATUS return.
1715 static NTSTATUS rpc_group_delete_internals(const DOM_SID *domain_sid,
1716 const char *domain_name,
1717 struct cli_state *cli,
1718 struct rpc_pipe_client *pipe_hnd,
1719 TALLOC_CTX *mem_ctx,
1723 POLICY_HND connect_pol, domain_pol, group_pol, user_pol;
1724 bool group_is_primary = False;
1725 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1727 uint32 *group_rids, num_rids, *name_types, num_members,
1728 *group_attrs, group_rid;
1729 uint32 flags = 0x000003e8; /* Unknown */
1732 /* DOM_GID *user_gids; */
1733 SAM_USERINFO_CTR *user_ctr;
1737 d_printf("specify group\n");
1738 rpc_group_usage(argc,argv);
1739 return NT_STATUS_OK; /* ok? */
1742 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1745 if (!NT_STATUS_IS_OK(result)) {
1746 d_fprintf(stderr, "Request samr_connect failed\n");
1750 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
1751 MAXIMUM_ALLOWED_ACCESS,
1752 domain_sid, &domain_pol);
1754 if (!NT_STATUS_IS_OK(result)) {
1755 d_fprintf(stderr, "Request open_domain failed\n");
1759 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol,
1761 &num_rids, &group_rids,
1764 if (!NT_STATUS_IS_OK(result)) {
1765 d_fprintf(stderr, "Lookup of '%s' failed\n",argv[0]);
1769 switch (name_types[0])
1771 case SID_NAME_DOM_GRP:
1772 result = rpccli_samr_open_group(pipe_hnd, mem_ctx, &domain_pol,
1773 MAXIMUM_ALLOWED_ACCESS,
1774 group_rids[0], &group_pol);
1775 if (!NT_STATUS_IS_OK(result)) {
1776 d_fprintf(stderr, "Request open_group failed");
1780 group_rid = group_rids[0];
1782 result = rpccli_samr_query_groupmem(pipe_hnd, mem_ctx, &group_pol,
1783 &num_members, &group_rids,
1786 if (!NT_STATUS_IS_OK(result)) {
1787 d_fprintf(stderr, "Unable to query group members of %s",argv[0]);
1792 d_printf("Domain Group %s (rid: %d) has %d members\n",
1793 argv[0],group_rid,num_members);
1796 /* Check if group is anyone's primary group */
1797 for (i = 0; i < num_members; i++)
1799 result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
1800 MAXIMUM_ALLOWED_ACCESS,
1801 group_rids[i], &user_pol);
1803 if (!NT_STATUS_IS_OK(result)) {
1804 d_fprintf(stderr, "Unable to open group member %d\n",group_rids[i]);
1808 ZERO_STRUCT(user_ctr);
1810 result = rpccli_samr_query_userinfo(pipe_hnd, mem_ctx, &user_pol,
1813 if (!NT_STATUS_IS_OK(result)) {
1814 d_fprintf(stderr, "Unable to lookup userinfo for group member %d\n",group_rids[i]);
1818 if (user_ctr->info.id21->group_rid == group_rid) {
1819 unistr2_to_ascii(temp, &(user_ctr->info.id21)->uni_user_name,
1822 d_printf("Group is primary group of %s\n",temp);
1823 group_is_primary = True;
1826 rpccli_samr_close(pipe_hnd, mem_ctx, &user_pol);
1829 if (group_is_primary) {
1830 d_fprintf(stderr, "Unable to delete group because some "
1831 "of it's members have it as primary group\n");
1832 result = NT_STATUS_MEMBERS_PRIMARY_GROUP;
1836 /* remove all group members */
1837 for (i = 0; i < num_members; i++)
1840 d_printf("Remove group member %d...",group_rids[i]);
1841 result = rpccli_samr_del_groupmem(pipe_hnd, mem_ctx, &group_pol, group_rids[i]);
1843 if (NT_STATUS_IS_OK(result)) {
1848 d_printf("failed\n");
1853 result = rpccli_samr_delete_dom_group(pipe_hnd, mem_ctx, &group_pol);
1856 /* removing a local group is easier... */
1857 case SID_NAME_ALIAS:
1858 result = rpccli_samr_open_alias(pipe_hnd, mem_ctx, &domain_pol,
1859 MAXIMUM_ALLOWED_ACCESS,
1860 group_rids[0], &group_pol);
1862 if (!NT_STATUS_IS_OK(result)) {
1863 d_fprintf(stderr, "Request open_alias failed\n");
1867 result = rpccli_samr_delete_dom_alias(pipe_hnd, mem_ctx, &group_pol);
1870 d_fprintf(stderr, "%s is of type %s. This command is only for deleting local or global groups\n",
1871 argv[0],sid_type_lookup(name_types[0]));
1872 result = NT_STATUS_UNSUCCESSFUL;
1877 if (NT_STATUS_IS_OK(result)) {
1879 d_printf("Deleted %s '%s'\n",sid_type_lookup(name_types[0]),argv[0]);
1881 d_fprintf(stderr, "Deleting of %s failed: %s\n",argv[0],
1882 get_friendly_nt_error_msg(result));
1890 static int rpc_group_delete(int argc, const char **argv)
1892 return run_rpc_command(NULL, PI_SAMR, 0, rpc_group_delete_internals,
1896 static NTSTATUS rpc_group_add_internals(const DOM_SID *domain_sid,
1897 const char *domain_name,
1898 struct cli_state *cli,
1899 struct rpc_pipe_client *pipe_hnd,
1900 TALLOC_CTX *mem_ctx,
1904 POLICY_HND connect_pol, domain_pol, group_pol;
1905 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1906 GROUP_INFO_CTR group_info;
1909 d_printf("Group name must be specified\n");
1910 rpc_group_usage(argc, argv);
1911 return NT_STATUS_OK;
1914 /* Get sam policy handle */
1916 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1918 if (!NT_STATUS_IS_OK(result)) goto done;
1920 /* Get domain policy handle */
1922 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
1923 MAXIMUM_ALLOWED_ACCESS,
1924 domain_sid, &domain_pol);
1925 if (!NT_STATUS_IS_OK(result)) goto done;
1927 /* Create the group */
1929 result = rpccli_samr_create_dom_group(pipe_hnd, mem_ctx, &domain_pol,
1930 argv[0], MAXIMUM_ALLOWED_ACCESS,
1932 if (!NT_STATUS_IS_OK(result)) goto done;
1934 if (strlen(opt_comment) == 0) goto done;
1936 /* We've got a comment to set */
1938 group_info.switch_value1 = 4;
1939 init_samr_group_info4(&group_info.group.info4, opt_comment);
1941 result = rpccli_samr_set_groupinfo(pipe_hnd, mem_ctx, &group_pol, &group_info);
1942 if (!NT_STATUS_IS_OK(result)) goto done;
1945 if (NT_STATUS_IS_OK(result))
1946 DEBUG(5, ("add group succeeded\n"));
1948 d_fprintf(stderr, "add group failed: %s\n", nt_errstr(result));
1953 static NTSTATUS rpc_alias_add_internals(const DOM_SID *domain_sid,
1954 const char *domain_name,
1955 struct cli_state *cli,
1956 struct rpc_pipe_client *pipe_hnd,
1957 TALLOC_CTX *mem_ctx,
1961 POLICY_HND connect_pol, domain_pol, alias_pol;
1962 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1963 ALIAS_INFO_CTR alias_info;
1966 d_printf("Alias name must be specified\n");
1967 rpc_group_usage(argc, argv);
1968 return NT_STATUS_OK;
1971 /* Get sam policy handle */
1973 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1975 if (!NT_STATUS_IS_OK(result)) goto done;
1977 /* Get domain policy handle */
1979 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
1980 MAXIMUM_ALLOWED_ACCESS,
1981 domain_sid, &domain_pol);
1982 if (!NT_STATUS_IS_OK(result)) goto done;
1984 /* Create the group */
1986 result = rpccli_samr_create_dom_alias(pipe_hnd, mem_ctx, &domain_pol,
1987 argv[0], &alias_pol);
1988 if (!NT_STATUS_IS_OK(result)) goto done;
1990 if (strlen(opt_comment) == 0) goto done;
1992 /* We've got a comment to set */
1994 alias_info.level = 3;
1995 init_samr_alias_info3(&alias_info.alias.info3, opt_comment);
1997 result = rpccli_samr_set_aliasinfo(pipe_hnd, mem_ctx, &alias_pol, &alias_info);
1998 if (!NT_STATUS_IS_OK(result)) goto done;
2001 if (NT_STATUS_IS_OK(result))
2002 DEBUG(5, ("add alias succeeded\n"));
2004 d_fprintf(stderr, "add alias failed: %s\n", nt_errstr(result));
2009 static int rpc_group_add(int argc, const char **argv)
2012 return run_rpc_command(NULL, PI_SAMR, 0,
2013 rpc_alias_add_internals,
2016 return run_rpc_command(NULL, PI_SAMR, 0,
2017 rpc_group_add_internals,
2021 static NTSTATUS get_sid_from_name(struct cli_state *cli,
2022 TALLOC_CTX *mem_ctx,
2025 enum lsa_SidType *type)
2027 DOM_SID *sids = NULL;
2028 enum lsa_SidType *types = NULL;
2029 struct rpc_pipe_client *pipe_hnd;
2031 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2033 pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_LSARPC, &result);
2038 result = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, False,
2039 SEC_RIGHTS_MAXIMUM_ALLOWED, &lsa_pol);
2041 if (!NT_STATUS_IS_OK(result)) {
2045 result = rpccli_lsa_lookup_names(pipe_hnd, mem_ctx, &lsa_pol, 1,
2046 &name, NULL, 1, &sids, &types);
2048 if (NT_STATUS_IS_OK(result)) {
2049 sid_copy(sid, &sids[0]);
2053 rpccli_lsa_Close(pipe_hnd, mem_ctx, &lsa_pol);
2057 cli_rpc_pipe_close(pipe_hnd);
2060 if (!NT_STATUS_IS_OK(result) && (StrnCaseCmp(name, "S-", 2) == 0)) {
2062 /* Try as S-1-5-whatever */
2066 if (string_to_sid(&tmp_sid, name)) {
2067 sid_copy(sid, &tmp_sid);
2068 *type = SID_NAME_UNKNOWN;
2069 result = NT_STATUS_OK;
2076 static NTSTATUS rpc_add_groupmem(struct rpc_pipe_client *pipe_hnd,
2077 TALLOC_CTX *mem_ctx,
2078 const DOM_SID *group_sid,
2081 POLICY_HND connect_pol, domain_pol;
2084 POLICY_HND group_pol;
2087 uint32 *rids = NULL;
2088 uint32 *rid_types = NULL;
2092 sid_copy(&sid, group_sid);
2094 if (!sid_split_rid(&sid, &group_rid)) {
2095 return NT_STATUS_UNSUCCESSFUL;
2098 /* Get sam policy handle */
2099 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
2101 if (!NT_STATUS_IS_OK(result)) {
2105 /* Get domain policy handle */
2106 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
2107 MAXIMUM_ALLOWED_ACCESS,
2109 if (!NT_STATUS_IS_OK(result)) {
2113 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, 1000,
2115 &num_rids, &rids, &rid_types);
2117 if (!NT_STATUS_IS_OK(result)) {
2118 d_fprintf(stderr, "Could not lookup up group member %s\n", member);
2122 result = rpccli_samr_open_group(pipe_hnd, mem_ctx, &domain_pol,
2123 MAXIMUM_ALLOWED_ACCESS,
2124 group_rid, &group_pol);
2126 if (!NT_STATUS_IS_OK(result)) {
2130 result = rpccli_samr_add_groupmem(pipe_hnd, mem_ctx, &group_pol, rids[0]);
2133 rpccli_samr_close(pipe_hnd, mem_ctx, &connect_pol);
2137 static NTSTATUS rpc_add_aliasmem(struct rpc_pipe_client *pipe_hnd,
2138 TALLOC_CTX *mem_ctx,
2139 const DOM_SID *alias_sid,
2142 POLICY_HND connect_pol, domain_pol;
2145 POLICY_HND alias_pol;
2148 enum lsa_SidType member_type;
2152 sid_copy(&sid, alias_sid);
2154 if (!sid_split_rid(&sid, &alias_rid)) {
2155 return NT_STATUS_UNSUCCESSFUL;
2158 result = get_sid_from_name(pipe_hnd->cli, mem_ctx, member,
2159 &member_sid, &member_type);
2161 if (!NT_STATUS_IS_OK(result)) {
2162 d_fprintf(stderr, "Could not lookup up group member %s\n", member);
2166 /* Get sam policy handle */
2167 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
2169 if (!NT_STATUS_IS_OK(result)) {
2173 /* Get domain policy handle */
2174 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
2175 MAXIMUM_ALLOWED_ACCESS,
2177 if (!NT_STATUS_IS_OK(result)) {
2181 result = rpccli_samr_open_alias(pipe_hnd, mem_ctx, &domain_pol,
2182 MAXIMUM_ALLOWED_ACCESS,
2183 alias_rid, &alias_pol);
2185 if (!NT_STATUS_IS_OK(result)) {
2189 result = rpccli_samr_add_aliasmem(pipe_hnd, mem_ctx, &alias_pol, &member_sid);
2191 if (!NT_STATUS_IS_OK(result)) {
2196 rpccli_samr_close(pipe_hnd, mem_ctx, &connect_pol);
2200 static NTSTATUS rpc_group_addmem_internals(const DOM_SID *domain_sid,
2201 const char *domain_name,
2202 struct cli_state *cli,
2203 struct rpc_pipe_client *pipe_hnd,
2204 TALLOC_CTX *mem_ctx,
2209 enum lsa_SidType group_type;
2212 d_printf("Usage: 'net rpc group addmem <group> <member>\n");
2213 return NT_STATUS_UNSUCCESSFUL;
2216 if (!NT_STATUS_IS_OK(get_sid_from_name(cli, mem_ctx, argv[0],
2217 &group_sid, &group_type))) {
2218 d_fprintf(stderr, "Could not lookup group name %s\n", argv[0]);
2219 return NT_STATUS_UNSUCCESSFUL;
2222 if (group_type == SID_NAME_DOM_GRP) {
2223 NTSTATUS result = rpc_add_groupmem(pipe_hnd, mem_ctx,
2224 &group_sid, argv[1]);
2226 if (!NT_STATUS_IS_OK(result)) {
2227 d_fprintf(stderr, "Could not add %s to %s: %s\n",
2228 argv[1], argv[0], nt_errstr(result));
2233 if (group_type == SID_NAME_ALIAS) {
2234 NTSTATUS result = rpc_add_aliasmem(pipe_hnd, mem_ctx,
2235 &group_sid, argv[1]);
2237 if (!NT_STATUS_IS_OK(result)) {
2238 d_fprintf(stderr, "Could not add %s to %s: %s\n",
2239 argv[1], argv[0], nt_errstr(result));
2244 d_fprintf(stderr, "Can only add members to global or local groups "
2245 "which %s is not\n", argv[0]);
2247 return NT_STATUS_UNSUCCESSFUL;
2250 static int rpc_group_addmem(int argc, const char **argv)
2252 return run_rpc_command(NULL, PI_SAMR, 0,
2253 rpc_group_addmem_internals,
2257 static NTSTATUS rpc_del_groupmem(struct rpc_pipe_client *pipe_hnd,
2258 TALLOC_CTX *mem_ctx,
2259 const DOM_SID *group_sid,
2262 POLICY_HND connect_pol, domain_pol;
2265 POLICY_HND group_pol;
2268 uint32 *rids = NULL;
2269 uint32 *rid_types = NULL;
2273 sid_copy(&sid, group_sid);
2275 if (!sid_split_rid(&sid, &group_rid))
2276 return NT_STATUS_UNSUCCESSFUL;
2278 /* Get sam policy handle */
2279 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
2281 if (!NT_STATUS_IS_OK(result))
2284 /* Get domain policy handle */
2285 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
2286 MAXIMUM_ALLOWED_ACCESS,
2288 if (!NT_STATUS_IS_OK(result))
2291 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, 1000,
2293 &num_rids, &rids, &rid_types);
2295 if (!NT_STATUS_IS_OK(result)) {
2296 d_fprintf(stderr, "Could not lookup up group member %s\n", member);
2300 result = rpccli_samr_open_group(pipe_hnd, mem_ctx, &domain_pol,
2301 MAXIMUM_ALLOWED_ACCESS,
2302 group_rid, &group_pol);
2304 if (!NT_STATUS_IS_OK(result))
2307 result = rpccli_samr_del_groupmem(pipe_hnd, mem_ctx, &group_pol, rids[0]);
2310 rpccli_samr_close(pipe_hnd, mem_ctx, &connect_pol);
2314 static NTSTATUS rpc_del_aliasmem(struct rpc_pipe_client *pipe_hnd,
2315 TALLOC_CTX *mem_ctx,
2316 const DOM_SID *alias_sid,
2319 POLICY_HND connect_pol, domain_pol;
2322 POLICY_HND alias_pol;
2325 enum lsa_SidType member_type;
2329 sid_copy(&sid, alias_sid);
2331 if (!sid_split_rid(&sid, &alias_rid))
2332 return NT_STATUS_UNSUCCESSFUL;
2334 result = get_sid_from_name(pipe_hnd->cli, mem_ctx, member,
2335 &member_sid, &member_type);
2337 if (!NT_STATUS_IS_OK(result)) {
2338 d_fprintf(stderr, "Could not lookup up group member %s\n", member);
2342 /* Get sam policy handle */
2343 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
2345 if (!NT_STATUS_IS_OK(result)) {
2349 /* Get domain policy handle */
2350 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
2351 MAXIMUM_ALLOWED_ACCESS,
2353 if (!NT_STATUS_IS_OK(result)) {
2357 result = rpccli_samr_open_alias(pipe_hnd, mem_ctx, &domain_pol,
2358 MAXIMUM_ALLOWED_ACCESS,
2359 alias_rid, &alias_pol);
2361 if (!NT_STATUS_IS_OK(result))
2364 result = rpccli_samr_del_aliasmem(pipe_hnd, mem_ctx, &alias_pol, &member_sid);
2366 if (!NT_STATUS_IS_OK(result))
2370 rpccli_samr_close(pipe_hnd, mem_ctx, &connect_pol);
2374 static NTSTATUS rpc_group_delmem_internals(const DOM_SID *domain_sid,
2375 const char *domain_name,
2376 struct cli_state *cli,
2377 struct rpc_pipe_client *pipe_hnd,
2378 TALLOC_CTX *mem_ctx,
2383 enum lsa_SidType group_type;
2386 d_printf("Usage: 'net rpc group delmem <group> <member>\n");
2387 return NT_STATUS_UNSUCCESSFUL;
2390 if (!NT_STATUS_IS_OK(get_sid_from_name(cli, mem_ctx, argv[0],
2391 &group_sid, &group_type))) {
2392 d_fprintf(stderr, "Could not lookup group name %s\n", argv[0]);
2393 return NT_STATUS_UNSUCCESSFUL;
2396 if (group_type == SID_NAME_DOM_GRP) {
2397 NTSTATUS result = rpc_del_groupmem(pipe_hnd, mem_ctx,
2398 &group_sid, argv[1]);
2400 if (!NT_STATUS_IS_OK(result)) {
2401 d_fprintf(stderr, "Could not del %s from %s: %s\n",
2402 argv[1], argv[0], nt_errstr(result));
2407 if (group_type == SID_NAME_ALIAS) {
2408 NTSTATUS result = rpc_del_aliasmem(pipe_hnd, mem_ctx,
2409 &group_sid, argv[1]);
2411 if (!NT_STATUS_IS_OK(result)) {
2412 d_fprintf(stderr, "Could not del %s from %s: %s\n",
2413 argv[1], argv[0], nt_errstr(result));
2418 d_fprintf(stderr, "Can only delete members from global or local groups "
2419 "which %s is not\n", argv[0]);
2421 return NT_STATUS_UNSUCCESSFUL;
2424 static int rpc_group_delmem(int argc, const char **argv)
2426 return run_rpc_command(NULL, PI_SAMR, 0,
2427 rpc_group_delmem_internals,
2432 * List groups on a remote RPC server
2434 * All parameters are provided by the run_rpc_command function, except for
2435 * argc, argv which are passes through.
2437 * @param domain_sid The domain sid acquired from the remote server
2438 * @param cli A cli_state connected to the server.
2439 * @param mem_ctx Talloc context, destoyed on completion of the function.
2440 * @param argc Standard main() style argc
2441 * @param argv Standard main() style argv. Initial components are already
2444 * @return Normal NTSTATUS return.
2447 static NTSTATUS rpc_group_list_internals(const DOM_SID *domain_sid,
2448 const char *domain_name,
2449 struct cli_state *cli,
2450 struct rpc_pipe_client *pipe_hnd,
2451 TALLOC_CTX *mem_ctx,
2455 POLICY_HND connect_pol, domain_pol;
2456 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2457 uint32 start_idx=0, max_entries=250, num_entries, i, loop_count = 0;
2458 struct acct_info *groups;
2459 bool global = False;
2461 bool builtin = False;
2469 for (i=0; i<argc; i++) {
2470 if (strequal(argv[i], "global"))
2473 if (strequal(argv[i], "local"))
2476 if (strequal(argv[i], "builtin"))
2480 /* Get sam policy handle */
2482 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
2484 if (!NT_STATUS_IS_OK(result)) {
2488 /* Get domain policy handle */
2490 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
2491 MAXIMUM_ALLOWED_ACCESS,
2492 domain_sid, &domain_pol);
2493 if (!NT_STATUS_IS_OK(result)) {
2497 /* Query domain groups */
2498 if (opt_long_list_entries)
2499 d_printf("\nGroup name Comment"\
2500 "\n-----------------------------\n");
2502 SAM_DISPINFO_CTR ctr;
2503 SAM_DISPINFO_3 info3;
2508 ctr.sam.info3 = &info3;
2512 get_query_dispinfo_params(
2513 loop_count, &max_entries, &max_size);
2515 result = rpccli_samr_query_dispinfo(pipe_hnd, mem_ctx, &domain_pol,
2516 &start_idx, 3, &num_entries,
2517 max_entries, max_size, &ctr);
2519 if (!NT_STATUS_IS_OK(result) &&
2520 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
2523 for (i = 0; i < num_entries; i++) {
2525 fstring group, desc;
2527 unistr2_to_ascii(group, &(&ctr.sam.info3->str[i])->uni_grp_name, sizeof(group));
2528 unistr2_to_ascii(desc, &(&ctr.sam.info3->str[i])->uni_grp_desc, sizeof(desc));
2530 if (opt_long_list_entries)
2531 printf("%-21.21s %-50.50s\n",
2534 printf("%s\n", group);
2536 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
2537 /* query domain aliases */
2542 /* The max_size field in cli_samr_enum_als_groups is more like
2543 * an account_control field with indiviual bits what to
2544 * retrieve. Set this to 0xffff as NT4 usrmgr.exe does to get
2545 * everything. I'm too lazy (sorry) to get this through to
2546 * rpc_parse/ etc. Volker */
2548 result = rpccli_samr_enum_als_groups(pipe_hnd, mem_ctx, &domain_pol,
2550 &groups, &num_entries);
2552 if (!NT_STATUS_IS_OK(result) &&
2553 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
2556 for (i = 0; i < num_entries; i++) {
2558 char *description = NULL;
2560 if (opt_long_list_entries) {
2562 POLICY_HND alias_pol;
2565 if ((NT_STATUS_IS_OK(rpccli_samr_open_alias(pipe_hnd, mem_ctx,
2570 (NT_STATUS_IS_OK(rpccli_samr_query_alias_info(pipe_hnd, mem_ctx,
2573 (NT_STATUS_IS_OK(rpccli_samr_close(pipe_hnd, mem_ctx,
2575 description = unistr2_to_ascii_talloc(mem_ctx,
2576 ctr.alias.info3.description.string);
2580 if (description != NULL) {
2581 printf("%-21.21s %-50.50s\n",
2582 groups[i].acct_name,
2585 printf("%s\n", groups[i].acct_name);
2588 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
2589 rpccli_samr_close(pipe_hnd, mem_ctx, &domain_pol);
2590 /* Get builtin policy handle */
2592 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
2593 MAXIMUM_ALLOWED_ACCESS,
2594 &global_sid_Builtin, &domain_pol);
2595 if (!NT_STATUS_IS_OK(result)) {
2598 /* query builtin aliases */
2601 if (!builtin) break;
2603 result = rpccli_samr_enum_als_groups(pipe_hnd, mem_ctx, &domain_pol,
2604 &start_idx, max_entries,
2605 &groups, &num_entries);
2607 if (!NT_STATUS_IS_OK(result) &&
2608 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
2611 for (i = 0; i < num_entries; i++) {
2613 char *description = NULL;
2615 if (opt_long_list_entries) {
2617 POLICY_HND alias_pol;
2620 if ((NT_STATUS_IS_OK(rpccli_samr_open_alias(pipe_hnd, mem_ctx,
2625 (NT_STATUS_IS_OK(rpccli_samr_query_alias_info(pipe_hnd, mem_ctx,
2628 (NT_STATUS_IS_OK(rpccli_samr_close(pipe_hnd, mem_ctx,
2630 description = unistr2_to_ascii_talloc(mem_ctx,
2631 ctr.alias.info3.description.string);
2635 if (description != NULL) {
2636 printf("%-21.21s %-50.50s\n",
2637 groups[i].acct_name,
2640 printf("%s\n", groups[i].acct_name);
2643 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
2649 static int rpc_group_list(int argc, const char **argv)
2651 return run_rpc_command(NULL, PI_SAMR, 0,
2652 rpc_group_list_internals,
2656 static NTSTATUS rpc_list_group_members(struct rpc_pipe_client *pipe_hnd,
2657 TALLOC_CTX *mem_ctx,
2658 const char *domain_name,
2659 const DOM_SID *domain_sid,
2660 POLICY_HND *domain_pol,
2664 POLICY_HND group_pol;
2665 uint32 num_members, *group_rids, *group_attrs;
2672 sid_to_fstring(sid_str, domain_sid);
2674 result = rpccli_samr_open_group(pipe_hnd, mem_ctx, domain_pol,
2675 MAXIMUM_ALLOWED_ACCESS,
2678 if (!NT_STATUS_IS_OK(result))
2681 result = rpccli_samr_query_groupmem(pipe_hnd, mem_ctx, &group_pol,
2682 &num_members, &group_rids,
2685 if (!NT_STATUS_IS_OK(result))
2688 while (num_members > 0) {
2689 int this_time = 512;
2691 if (num_members < this_time)
2692 this_time = num_members;
2694 result = rpccli_samr_lookup_rids(pipe_hnd, mem_ctx, domain_pol,
2695 this_time, group_rids,
2696 &num_names, &names, &name_types);
2698 if (!NT_STATUS_IS_OK(result))
2701 /* We only have users as members, but make the output
2702 the same as the output of alias members */
2704 for (i = 0; i < this_time; i++) {
2706 if (opt_long_list_entries) {
2707 printf("%s-%d %s\\%s %d\n", sid_str,
2708 group_rids[i], domain_name, names[i],
2711 printf("%s\\%s\n", domain_name, names[i]);
2715 num_members -= this_time;
2719 return NT_STATUS_OK;
2722 static NTSTATUS rpc_list_alias_members(struct rpc_pipe_client *pipe_hnd,
2723 TALLOC_CTX *mem_ctx,
2724 POLICY_HND *domain_pol,
2728 struct rpc_pipe_client *lsa_pipe;
2729 POLICY_HND alias_pol, lsa_pol;
2731 DOM_SID *alias_sids;
2734 enum lsa_SidType *types;
2737 result = rpccli_samr_open_alias(pipe_hnd, mem_ctx, domain_pol,
2738 MAXIMUM_ALLOWED_ACCESS, rid, &alias_pol);
2740 if (!NT_STATUS_IS_OK(result))
2743 result = rpccli_samr_query_aliasmem(pipe_hnd, mem_ctx, &alias_pol,
2744 &num_members, &alias_sids);
2746 if (!NT_STATUS_IS_OK(result)) {
2747 d_fprintf(stderr, "Couldn't list alias members\n");
2751 if (num_members == 0) {
2752 return NT_STATUS_OK;
2755 lsa_pipe = cli_rpc_pipe_open_noauth(pipe_hnd->cli, PI_LSARPC, &result);
2757 d_fprintf(stderr, "Couldn't open LSA pipe. Error was %s\n",
2758 nt_errstr(result) );
2762 result = rpccli_lsa_open_policy(lsa_pipe, mem_ctx, True,
2763 SEC_RIGHTS_MAXIMUM_ALLOWED, &lsa_pol);
2765 if (!NT_STATUS_IS_OK(result)) {
2766 d_fprintf(stderr, "Couldn't open LSA policy handle\n");
2767 cli_rpc_pipe_close(lsa_pipe);
2771 result = rpccli_lsa_lookup_sids(lsa_pipe, mem_ctx, &lsa_pol, num_members,
2773 &domains, &names, &types);
2775 if (!NT_STATUS_IS_OK(result) &&
2776 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
2777 d_fprintf(stderr, "Couldn't lookup SIDs\n");
2778 cli_rpc_pipe_close(lsa_pipe);
2782 for (i = 0; i < num_members; i++) {
2784 sid_to_fstring(sid_str, &alias_sids[i]);
2786 if (opt_long_list_entries) {
2787 printf("%s %s\\%s %d\n", sid_str,
2788 domains[i] ? domains[i] : "*unknown*",
2789 names[i] ? names[i] : "*unknown*", types[i]);
2792 printf("%s\\%s\n", domains[i], names[i]);
2794 printf("%s\n", sid_str);
2798 cli_rpc_pipe_close(lsa_pipe);
2799 return NT_STATUS_OK;
2802 static NTSTATUS rpc_group_members_internals(const DOM_SID *domain_sid,
2803 const char *domain_name,
2804 struct cli_state *cli,
2805 struct rpc_pipe_client *pipe_hnd,
2806 TALLOC_CTX *mem_ctx,
2811 POLICY_HND connect_pol, domain_pol;
2812 uint32 num_rids, *rids, *rid_types;
2814 /* Get sam policy handle */
2816 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
2819 if (!NT_STATUS_IS_OK(result))
2822 /* Get domain policy handle */
2824 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
2825 MAXIMUM_ALLOWED_ACCESS,
2826 domain_sid, &domain_pol);
2828 if (!NT_STATUS_IS_OK(result))
2831 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, 1000,
2832 1, argv, &num_rids, &rids, &rid_types);
2834 if (!NT_STATUS_IS_OK(result)) {
2836 /* Ok, did not find it in the global sam, try with builtin */
2838 DOM_SID sid_Builtin;
2840 rpccli_samr_close(pipe_hnd, mem_ctx, &domain_pol);
2842 string_to_sid(&sid_Builtin, "S-1-5-32");
2844 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
2845 MAXIMUM_ALLOWED_ACCESS,
2846 &sid_Builtin, &domain_pol);
2848 if (!NT_STATUS_IS_OK(result)) {
2849 d_fprintf(stderr, "Couldn't find group %s\n", argv[0]);
2853 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, 1000,
2857 if (!NT_STATUS_IS_OK(result)) {
2858 d_fprintf(stderr, "Couldn't find group %s\n", argv[0]);
2863 if (num_rids != 1) {
2864 d_fprintf(stderr, "Couldn't find group %s\n", argv[0]);
2868 if (rid_types[0] == SID_NAME_DOM_GRP) {
2869 return rpc_list_group_members(pipe_hnd, mem_ctx, domain_name,
2870 domain_sid, &domain_pol,
2874 if (rid_types[0] == SID_NAME_ALIAS) {
2875 return rpc_list_alias_members(pipe_hnd, mem_ctx, &domain_pol,
2879 return NT_STATUS_NO_SUCH_GROUP;
2882 static int rpc_group_members(int argc, const char **argv)
2885 return rpc_group_usage(argc, argv);
2888 return run_rpc_command(NULL, PI_SAMR, 0,
2889 rpc_group_members_internals,
2893 static NTSTATUS rpc_group_rename_internals(const DOM_SID *domain_sid,
2894 const char *domain_name,
2895 struct cli_state *cli,
2896 struct rpc_pipe_client *pipe_hnd,
2897 TALLOC_CTX *mem_ctx,
2902 POLICY_HND connect_pol, domain_pol, group_pol;
2903 uint32 num_rids, *rids, *rid_types;
2907 d_printf("Usage: 'net rpc group rename group newname'\n");
2908 return NT_STATUS_UNSUCCESSFUL;
2911 /* Get sam policy handle */
2913 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
2916 if (!NT_STATUS_IS_OK(result))
2919 /* Get domain policy handle */
2921 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
2922 MAXIMUM_ALLOWED_ACCESS,
2923 domain_sid, &domain_pol);
2925 if (!NT_STATUS_IS_OK(result))
2928 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, 1000,
2929 1, argv, &num_rids, &rids, &rid_types);
2931 if (num_rids != 1) {
2932 d_fprintf(stderr, "Couldn't find group %s\n", argv[0]);
2936 if (rid_types[0] != SID_NAME_DOM_GRP) {
2937 d_fprintf(stderr, "Can only rename domain groups\n");
2938 return NT_STATUS_UNSUCCESSFUL;
2941 result = rpccli_samr_open_group(pipe_hnd, mem_ctx, &domain_pol,
2942 MAXIMUM_ALLOWED_ACCESS,
2943 rids[0], &group_pol);
2945 if (!NT_STATUS_IS_OK(result))
2950 ctr.switch_value1 = 2;
2951 init_samr_group_info2(&ctr.group.info2, argv[1]);
2953 result = rpccli_samr_set_groupinfo(pipe_hnd, mem_ctx, &group_pol, &ctr);
2955 if (!NT_STATUS_IS_OK(result))
2958 return NT_STATUS_NO_SUCH_GROUP;
2961 static int rpc_group_rename(int argc, const char **argv)
2964 return rpc_group_usage(argc, argv);
2967 return run_rpc_command(NULL, PI_SAMR, 0,
2968 rpc_group_rename_internals,
2973 * 'net rpc group' entrypoint.
2974 * @param argc Standard main() style argc
2975 * @param argc Standard main() style argv. Initial components are already
2979 int net_rpc_group(int argc, const char **argv)
2981 struct functable func[] = {
2982 {"add", rpc_group_add},
2983 {"delete", rpc_group_delete},
2984 {"addmem", rpc_group_addmem},
2985 {"delmem", rpc_group_delmem},
2986 {"list", rpc_group_list},
2987 {"members", rpc_group_members},
2988 {"rename", rpc_group_rename},
2993 return run_rpc_command(NULL, PI_SAMR, 0,
2994 rpc_group_list_internals,
2998 return net_run_function(argc, argv, func, rpc_group_usage);
3001 /****************************************************************************/
3003 static int rpc_share_usage(int argc, const char **argv)
3005 return net_help_share(argc, argv);
3009 * Add a share on a remote RPC server
3011 * All parameters are provided by the run_rpc_command function, except for
3012 * argc, argv which are passes through.
3014 * @param domain_sid The domain sid acquired from the remote server
3015 * @param cli A cli_state connected to the server.
3016 * @param mem_ctx Talloc context, destoyed on completion of the function.
3017 * @param argc Standard main() style argc
3018 * @param argv Standard main() style argv. Initial components are already
3021 * @return Normal NTSTATUS return.
3023 static NTSTATUS rpc_share_add_internals(const DOM_SID *domain_sid,
3024 const char *domain_name,
3025 struct cli_state *cli,
3026 struct rpc_pipe_client *pipe_hnd,
3027 TALLOC_CTX *mem_ctx,int argc,
3033 uint32 type = STYPE_DISKTREE; /* only allow disk shares to be added */
3034 uint32 num_users=0, perms=0;
3035 char *password=NULL; /* don't allow a share password */
3038 if ((sharename = talloc_strdup(mem_ctx, argv[0])) == NULL) {
3039 return NT_STATUS_NO_MEMORY;
3042 path = strchr(sharename, '=');
3044 return NT_STATUS_UNSUCCESSFUL;
3047 result = rpccli_srvsvc_net_share_add(pipe_hnd, mem_ctx, sharename, type,
3048 opt_comment, perms, opt_maxusers,
3049 num_users, path, password,
3051 return werror_to_ntstatus(result);
3054 static int rpc_share_add(int argc, const char **argv)
3056 if ((argc < 1) || !strchr(argv[0], '=')) {
3057 DEBUG(1,("Sharename or path not specified on add\n"));
3058 return rpc_share_usage(argc, argv);
3060 return run_rpc_command(NULL, PI_SRVSVC, 0,
3061 rpc_share_add_internals,
3066 * Delete a share on a remote RPC server
3068 * All parameters are provided by the run_rpc_command function, except for
3069 * argc, argv which are passes through.
3071 * @param domain_sid The domain sid acquired from the remote server
3072 * @param cli A cli_state connected to the server.
3073 * @param mem_ctx Talloc context, destoyed on completion of the function.
3074 * @param argc Standard main() style argc
3075 * @param argv Standard main() style argv. Initial components are already
3078 * @return Normal NTSTATUS return.
3080 static NTSTATUS rpc_share_del_internals(const DOM_SID *domain_sid,
3081 const char *domain_name,
3082 struct cli_state *cli,
3083 struct rpc_pipe_client *pipe_hnd,
3084 TALLOC_CTX *mem_ctx,
3090 result = rpccli_srvsvc_net_share_del(pipe_hnd, mem_ctx, argv[0]);
3091 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
3095 * Delete a share on a remote RPC server
3097 * @param domain_sid The domain sid acquired from the remote server
3098 * @param argc Standard main() style argc
3099 * @param argv Standard main() style argv. Initial components are already
3102 * @return A shell status integer (0 for success)
3104 static int rpc_share_delete(int argc, const char **argv)
3107 DEBUG(1,("Sharename not specified on delete\n"));
3108 return rpc_share_usage(argc, argv);
3110 return run_rpc_command(NULL, PI_SRVSVC, 0,
3111 rpc_share_del_internals,
3116 * Formatted print of share info
3118 * @param info1 pointer to SRV_SHARE_INFO_1 to format
3121 static void display_share_info_1(SRV_SHARE_INFO_1 *info1)
3123 fstring netname = "", remark = "";
3125 rpcstr_pull_unistr2_fstring(netname, &info1->info_1_str.uni_netname);
3126 rpcstr_pull_unistr2_fstring(remark, &info1->info_1_str.uni_remark);
3128 if (opt_long_list_entries) {
3129 d_printf("%-12s %-8.8s %-50s\n",
3130 netname, share_type[info1->info_1.type & ~(STYPE_TEMPORARY|STYPE_HIDDEN)], remark);
3132 d_printf("%s\n", netname);
3137 static WERROR get_share_info(struct rpc_pipe_client *pipe_hnd,
3138 TALLOC_CTX *mem_ctx,
3142 SRV_SHARE_INFO_CTR *ctr)
3145 SRV_SHARE_INFO info;
3147 /* no specific share requested, enumerate all */
3151 uint32 preferred_len = 0xffffffff;
3153 init_enum_hnd(&hnd, 0);
3155 return rpccli_srvsvc_net_share_enum(pipe_hnd, mem_ctx, level, ctr,
3156 preferred_len, &hnd);
3159 /* request just one share */
3160 result = rpccli_srvsvc_net_share_get_info(pipe_hnd, mem_ctx, argv[0], level, &info);
3162 if (!W_ERROR_IS_OK(result))
3168 ctr->info_level = ctr->switch_value = level;
3169 ctr->ptr_share_info = ctr->ptr_entries = 1;
3170 ctr->num_entries = ctr->num_entries2 = 1;
3176 SRV_SHARE_INFO_1 *info1;
3178 ctr->share.info1 = TALLOC_ARRAY(mem_ctx, SRV_SHARE_INFO_1, 1);
3179 if (ctr->share.info1 == NULL) {
3180 result = WERR_NOMEM;
3183 info1 = ctr->share.info1;
3185 memset(ctr->share.info1, 0, sizeof(SRV_SHARE_INFO_1));
3187 /* Copy pointer crap */
3189 memcpy(&info1->info_1, &info.share.info1.info_1, sizeof(SH_INFO_1));
3191 /* Duplicate strings */
3193 s = unistr2_to_ascii_talloc(mem_ctx, &info.share.info1.info_1_str.uni_netname);
3195 init_unistr2(&info1->info_1_str.uni_netname, s, UNI_STR_TERMINATE);
3197 s = unistr2_to_ascii_talloc(mem_ctx, &info.share.info1.info_1_str.uni_remark);
3199 init_unistr2(&info1->info_1_str.uni_remark, s, UNI_STR_TERMINATE);
3204 SRV_SHARE_INFO_2 *info2;
3206 ctr->share.info2 = TALLOC_ARRAY(mem_ctx, SRV_SHARE_INFO_2, 1);
3207 if (ctr->share.info2 == NULL) {
3208 result = WERR_NOMEM;
3211 info2 = ctr->share.info2;
3213 memset(ctr->share.info2, 0, sizeof(SRV_SHARE_INFO_2));
3215 /* Copy pointer crap */
3217 memcpy(&info2->info_2, &info.share.info2.info_2, sizeof(SH_INFO_2));
3219 /* Duplicate strings */
3221 s = unistr2_to_ascii_talloc(mem_ctx, &info.share.info2.info_2_str.uni_netname);
3223 init_unistr2(&info2->info_2_str.uni_netname, s, UNI_STR_TERMINATE);
3225 s = unistr2_to_ascii_talloc(mem_ctx, &info.share.info2.info_2_str.uni_remark);
3227 init_unistr2(&info2->info_2_str.uni_remark, s, UNI_STR_TERMINATE);
3229 s = unistr2_to_ascii_talloc(mem_ctx, &info.share.info2.info_2_str.uni_path);
3231 init_unistr2(&info2->info_2_str.uni_path, s, UNI_STR_TERMINATE);
3233 s = unistr2_to_ascii_talloc(mem_ctx, &info.share.info2.info_2_str.uni_passwd);
3235 init_unistr2(&info2->info_2_str.uni_passwd, s, UNI_STR_TERMINATE);
3240 SRV_SHARE_INFO_502 *info502;
3242 ctr->share.info502 = TALLOC_ARRAY(mem_ctx, SRV_SHARE_INFO_502, 1);
3243 if (ctr->share.info502 == NULL) {
3244 result = WERR_NOMEM;
3247 info502 = ctr->share.info502;
3249 memset(ctr->share.info502, 0, sizeof(SRV_SHARE_INFO_502));
3251 /* Copy pointer crap */
3253 memcpy(&info502->info_502, &info.share.info502.info_502, sizeof(SH_INFO_502));
3255 /* Duplicate strings */
3257 s = unistr2_to_ascii_talloc(mem_ctx, &info.share.info502.info_502_str.uni_netname);
3259 init_unistr2(&info502->info_502_str.uni_netname, s, UNI_STR_TERMINATE);
3261 s = unistr2_to_ascii_talloc(mem_ctx, &info.share.info502.info_502_str.uni_remark);
3263 init_unistr2(&info502->info_502_str.uni_remark, s, UNI_STR_TERMINATE);
3265 s = unistr2_to_ascii_talloc(mem_ctx, &info.share.info502.info_502_str.uni_path);
3267 init_unistr2(&info502->info_502_str.uni_path, s, UNI_STR_TERMINATE);
3269 s = unistr2_to_ascii_talloc(mem_ctx, &info.share.info502.info_502_str.uni_passwd);
3271 init_unistr2(&info502->info_502_str.uni_passwd, s, UNI_STR_TERMINATE);
3273 info502->info_502_str.sd = dup_sec_desc(mem_ctx, info.share.info502.info_502_str.sd);
3284 * List shares on a remote RPC server
3286 * All parameters are provided by the run_rpc_command function, except for
3287 * argc, argv which are passes through.
3289 * @param domain_sid The domain sid acquired from the remote server
3290 * @param cli A cli_state connected to the server.
3291 * @param mem_ctx Talloc context, destoyed on completion of the function.
3292 * @param argc Standard main() style argc
3293 * @param argv Standard main() style argv. Initial components are already
3296 * @return Normal NTSTATUS return.
3299 static NTSTATUS rpc_share_list_internals(const DOM_SID *domain_sid,
3300 const char *domain_name,
3301 struct cli_state *cli,
3302 struct rpc_pipe_client *pipe_hnd,
3303 TALLOC_CTX *mem_ctx,
3307 SRV_SHARE_INFO_CTR ctr;
3309 uint32 i, level = 1;
3311 result = get_share_info(pipe_hnd, mem_ctx, level, argc, argv, &ctr);
3312 if (!W_ERROR_IS_OK(result))
3315 /* Display results */
3317 if (opt_long_list_entries) {
3319 "\nEnumerating shared resources (exports) on remote server:\n\n"\
3320 "\nShare name Type Description\n"\
3321 "---------- ---- -----------\n");
3323 for (i = 0; i < ctr.num_entries; i++)
3324 display_share_info_1(&ctr.share.info1[i]);
3326 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
3330 * 'net rpc share list' entrypoint.
3331 * @param argc Standard main() style argc
3332 * @param argv Standard main() style argv. Initial components are already
3335 static int rpc_share_list(int argc, const char **argv)
3337 return run_rpc_command(NULL, PI_SRVSVC, 0, rpc_share_list_internals, argc, argv);
3340 static bool check_share_availability(struct cli_state *cli, const char *netname)
3342 if (!cli_send_tconX(cli, netname, "A:", "", 0)) {
3343 d_printf("skipping [%s]: not a file share.\n", netname);
3353 static bool check_share_sanity(struct cli_state *cli, fstring netname, uint32 type)
3355 /* only support disk shares */
3356 if (! ( type == STYPE_DISKTREE || type == (STYPE_DISKTREE | STYPE_HIDDEN)) ) {
3357 printf("share [%s] is not a diskshare (type: %x)\n", netname, type);
3361 /* skip builtin shares */
3362 /* FIXME: should print$ be added too ? */
3363 if (strequal(netname,"IPC$") || strequal(netname,"ADMIN$") ||
3364 strequal(netname,"global"))
3367 if (opt_exclude && in_list(netname, opt_exclude, False)) {
3368 printf("excluding [%s]\n", netname);
3372 return check_share_availability(cli, netname);
3376 * Migrate shares from a remote RPC server to the local RPC srever
3378 * All parameters are provided by the run_rpc_command function, except for
3379 * argc, argv which are passes through.
3381 * @param domain_sid The domain sid acquired from the remote server
3382 * @param cli A cli_state connected to the server.
3383 * @param mem_ctx Talloc context, destoyed on completion of the function.
3384 * @param argc Standard main() style argc
3385 * @param argv Standard main() style argv. Initial components are already
3388 * @return Normal NTSTATUS return.
3391 static NTSTATUS rpc_share_migrate_shares_internals(const DOM_SID *domain_sid,
3392 const char *domain_name,
3393 struct cli_state *cli,
3394 struct rpc_pipe_client *pipe_hnd,
3395 TALLOC_CTX *mem_ctx,
3400 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
3401 SRV_SHARE_INFO_CTR ctr_src;
3402 uint32 type = STYPE_DISKTREE; /* only allow disk shares to be added */
3403 char *password = NULL; /* don't allow a share password */
3405 struct rpc_pipe_client *srvsvc_pipe = NULL;
3406 struct cli_state *cli_dst = NULL;
3407 uint32 level = 502; /* includes secdesc */
3409 result = get_share_info(pipe_hnd, mem_ctx, level, argc, argv, &ctr_src);
3410 if (!W_ERROR_IS_OK(result))
3413 /* connect destination PI_SRVSVC */
3414 nt_status = connect_dst_pipe(&cli_dst, &srvsvc_pipe, PI_SRVSVC);
3415 if (!NT_STATUS_IS_OK(nt_status))
3419 for (i = 0; i < ctr_src.num_entries; i++) {
3421 fstring netname = "", remark = "", path = "";
3422 /* reset error-code */
3423 nt_status = NT_STATUS_UNSUCCESSFUL;
3425 rpcstr_pull_unistr2_fstring(
3426 netname, &ctr_src.share.info502[i].info_502_str.uni_netname);
3427 rpcstr_pull_unistr2_fstring(
3428 remark, &ctr_src.share.info502[i].info_502_str.uni_remark);
3429 rpcstr_pull_unistr2_fstring(
3430 path, &ctr_src.share.info502[i].info_502_str.uni_path);
3432 if (!check_share_sanity(cli, netname, ctr_src.share.info502[i].info_502.type))
3435 /* finally add the share on the dst server */
3437 printf("migrating: [%s], path: %s, comment: %s, without share-ACLs\n",
3438 netname, path, remark);
3440 result = rpccli_srvsvc_net_share_add(srvsvc_pipe, mem_ctx, netname, type, remark,
3441 ctr_src.share.info502[i].info_502.perms,
3442 ctr_src.share.info502[i].info_502.max_uses,
3443 ctr_src.share.info502[i].info_502.num_uses,
3444 path, password, level,
3447 if (W_ERROR_V(result) == W_ERROR_V(WERR_ALREADY_EXISTS)) {
3448 printf(" [%s] does already exist\n", netname);
3452 if (!W_ERROR_IS_OK(result)) {
3453 printf("cannot add share: %s\n", dos_errstr(result));
3459 nt_status = NT_STATUS_OK;
3463 cli_shutdown(cli_dst);
3471 * Migrate shares from a rpc-server to another
3473 * @param argc Standard main() style argc
3474 * @param argv Standard main() style argv. Initial components are already
3477 * @return A shell status integer (0 for success)
3479 static int rpc_share_migrate_shares(int argc, const char **argv)
3483 printf("no server to migrate\n");
3487 return run_rpc_command(NULL, PI_SRVSVC, 0,
3488 rpc_share_migrate_shares_internals,
3495 * @param f file_info
3496 * @param mask current search mask
3497 * @param state arg-pointer
3500 static void copy_fn(const char *mnt, file_info *f, const char *mask, void *state)
3502 static NTSTATUS nt_status;
3503 static struct copy_clistate *local_state;
3504 static fstring filename, new_mask;
3508 local_state = (struct copy_clistate *)state;
3509 nt_status = NT_STATUS_UNSUCCESSFUL;
3511 if (strequal(f->name, ".") || strequal(f->name, ".."))
3514 DEBUG(3,("got mask: %s, name: %s\n", mask, f->name));
3517 if (f->mode & aDIR) {
3519 DEBUG(3,("got dir: %s\n", f->name));
3521 fstrcpy(dir, local_state->cwd);
3523 fstrcat(dir, f->name);
3525 switch (net_mode_share)
3527 case NET_MODE_SHARE_MIGRATE:
3528 /* create that directory */
3529 nt_status = net_copy_file(local_state->mem_ctx,
3530 local_state->cli_share_src,
3531 local_state->cli_share_dst,
3533 opt_acls? True : False,
3534 opt_attrs? True : False,
3535 opt_timestamps? True : False,
3539 d_fprintf(stderr, "Unsupported mode %d\n", net_mode_share);
3543 if (!NT_STATUS_IS_OK(nt_status))
3544 printf("could not handle dir %s: %s\n",
3545 dir, nt_errstr(nt_status));
3547 /* search below that directory */
3548 fstrcpy(new_mask, dir);
3549 fstrcat(new_mask, "\\*");
3551 old_dir = local_state->cwd;
3552 local_state->cwd = dir;
3553 if (!sync_files(local_state, new_mask))
3554 printf("could not handle files\n");
3555 local_state->cwd = old_dir;
3562 fstrcpy(filename, local_state->cwd);
3563 fstrcat(filename, "\\");
3564 fstrcat(filename, f->name);
3566 DEBUG(3,("got file: %s\n", filename));
3568 switch (net_mode_share)
3570 case NET_MODE_SHARE_MIGRATE:
3571 nt_status = net_copy_file(local_state->mem_ctx,
3572 local_state->cli_share_src,
3573 local_state->cli_share_dst,
3575 opt_acls? True : False,
3576 opt_attrs? True : False,
3577 opt_timestamps? True: False,
3581 d_fprintf(stderr, "Unsupported file mode %d\n", net_mode_share);
3585 if (!NT_STATUS_IS_OK(nt_status))
3586 printf("could not handle file %s: %s\n",
3587 filename, nt_errstr(nt_status));
3592 * sync files, can be called recursivly to list files
3593 * and then call copy_fn for each file
3595 * @param cp_clistate pointer to the copy_clistate we work with
3596 * @param mask the current search mask
3598 * @return Boolean result
3600 static bool sync_files(struct copy_clistate *cp_clistate, const char *mask)
3602 struct cli_state *targetcli;
3603 char *targetpath = NULL;
3605 DEBUG(3,("calling cli_list with mask: %s\n", mask));
3607 if ( !cli_resolve_path(talloc_tos(), "", cp_clistate->cli_share_src,
3608 mask, &targetcli, &targetpath ) ) {
3609 d_fprintf(stderr, "cli_resolve_path %s failed with error: %s\n",
3610 mask, cli_errstr(cp_clistate->cli_share_src));
3614 if (cli_list(targetcli, targetpath, cp_clistate->attribute, copy_fn, cp_clistate) == -1) {
3615 d_fprintf(stderr, "listing %s failed with error: %s\n",
3616 mask, cli_errstr(targetcli));
3625 * Set the top level directory permissions before we do any further copies.
3626 * Should set up ACL inheritance.
3629 bool copy_top_level_perms(struct copy_clistate *cp_clistate,
3630 const char *sharename)
3632 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
3634 switch (net_mode_share) {
3635 case NET_MODE_SHARE_MIGRATE:
3636 DEBUG(3,("calling net_copy_fileattr for '.' directory in share %s\n", sharename));
3637 nt_status = net_copy_fileattr(cp_clistate->mem_ctx,
3638 cp_clistate->cli_share_src,
3639 cp_clistate->cli_share_dst,
3641 opt_acls? True : False,
3642 opt_attrs? True : False,
3643 opt_timestamps? True: False,
3647 d_fprintf(stderr, "Unsupported mode %d\n", net_mode_share);
3651 if (!NT_STATUS_IS_OK(nt_status)) {
3652 printf("Could handle directory attributes for top level directory of share %s. Error %s\n",
3653 sharename, nt_errstr(nt_status));
3661 * Sync all files inside a remote share to another share (over smb)
3663 * All parameters are provided by the run_rpc_command function, except for
3664 * argc, argv which are passes through.
3666 * @param domain_sid The domain sid acquired from the remote server
3667 * @param cli A cli_state connected to the server.
3668 * @param mem_ctx Talloc context, destoyed on completion of the function.
3669 * @param argc Standard main() style argc
3670 * @param argv Standard main() style argv. Initial components are already
3673 * @return Normal NTSTATUS return.
3676 static NTSTATUS rpc_share_migrate_files_internals(const DOM_SID *domain_sid,
3677 const char *domain_name,
3678 struct cli_state *cli,
3679 struct rpc_pipe_client *pipe_hnd,
3680 TALLOC_CTX *mem_ctx,
3685 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
3686 SRV_SHARE_INFO_CTR ctr_src;
3689 struct copy_clistate cp_clistate;
3690 bool got_src_share = False;
3691 bool got_dst_share = False;
3692 const char *mask = "\\*";
3695 dst = SMB_STRDUP(opt_destination?opt_destination:"127.0.0.1");
3697 result = get_share_info(pipe_hnd, mem_ctx, level, argc, argv, &ctr_src);
3699 if (!W_ERROR_IS_OK(result))
3702 for (i = 0; i < ctr_src.num_entries; i++) {
3704 fstring netname = "";
3706 rpcstr_pull_unistr2_fstring(
3707 netname, &ctr_src.share.info502[i].info_502_str.uni_netname);
3709 if (!check_share_sanity(cli, netname, ctr_src.share.info502[i].info_502.type))
3712 /* one might not want to mirror whole discs :) */
3713 if (strequal(netname, "print$") || netname[1] == '$') {
3714 d_printf("skipping [%s]: builtin/hidden share\n", netname);
3718 switch (net_mode_share)
3720 case NET_MODE_SHARE_MIGRATE:
3724 d_fprintf(stderr, "Unsupported mode %d\n", net_mode_share);
3727 printf(" [%s] files and directories %s ACLs, %s DOS Attributes %s\n",
3729 opt_acls ? "including" : "without",
3730 opt_attrs ? "including" : "without",
3731 opt_timestamps ? "(preserving timestamps)" : "");
3733 cp_clistate.mem_ctx = mem_ctx;
3734 cp_clistate.cli_share_src = NULL;
3735 cp_clistate.cli_share_dst = NULL;
3736 cp_clistate.cwd = NULL;
3737 cp_clistate.attribute = aSYSTEM | aHIDDEN | aDIR;
3739 /* open share source */
3740 nt_status = connect_to_service(&cp_clistate.cli_share_src,
3741 &cli->dest_ss, cli->desthost,
3743 if (!NT_STATUS_IS_OK(nt_status))
3746 got_src_share = True;
3748 if (net_mode_share == NET_MODE_SHARE_MIGRATE) {
3749 /* open share destination */
3750 nt_status = connect_to_service(&cp_clistate.cli_share_dst,
3751 NULL, dst, netname, "A:");
3752 if (!NT_STATUS_IS_OK(nt_status))
3755 got_dst_share = True;
3758 if (!copy_top_level_perms(&cp_clistate, netname)) {
3759 d_fprintf(stderr, "Could not handle the top level directory permissions for the share: %s\n", netname);
3760 nt_status = NT_STATUS_UNSUCCESSFUL;
3764 if (!sync_files(&cp_clistate, mask)) {
3765 d_fprintf(stderr, "could not handle files for share: %s\n", netname);
3766 nt_status = NT_STATUS_UNSUCCESSFUL;
3771 nt_status = NT_STATUS_OK;
3776 cli_shutdown(cp_clistate.cli_share_src);
3779 cli_shutdown(cp_clistate.cli_share_dst);
3785 static int rpc_share_migrate_files(int argc, const char **argv)
3789 printf("no server to migrate\n");
3793 return run_rpc_command(NULL, PI_SRVSVC, 0,
3794 rpc_share_migrate_files_internals,
3799 * Migrate share-ACLs from a remote RPC server to the local RPC srever
3801 * All parameters are provided by the run_rpc_command function, except for
3802 * argc, argv which are passes through.
3804 * @param domain_sid The domain sid acquired from the remote server
3805 * @param cli A cli_state connected to the server.
3806 * @param mem_ctx Talloc context, destoyed on completion of the function.
3807 * @param argc Standard main() style argc
3808 * @param argv Standard main() style argv. Initial components are already
3811 * @return Normal NTSTATUS return.
3814 static NTSTATUS rpc_share_migrate_security_internals(const DOM_SID *domain_sid,
3815 const char *domain_name,
3816 struct cli_state *cli,
3817 struct rpc_pipe_client *pipe_hnd,
3818 TALLOC_CTX *mem_ctx,
3823 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
3824 SRV_SHARE_INFO_CTR ctr_src;
3825 SRV_SHARE_INFO info;
3827 struct rpc_pipe_client *srvsvc_pipe = NULL;
3828 struct cli_state *cli_dst = NULL;
3829 uint32 level = 502; /* includes secdesc */
3831 result = get_share_info(pipe_hnd, mem_ctx, level, argc, argv, &ctr_src);
3833 if (!W_ERROR_IS_OK(result))
3836 /* connect destination PI_SRVSVC */
3837 nt_status = connect_dst_pipe(&cli_dst, &srvsvc_pipe, PI_SRVSVC);
3838 if (!NT_STATUS_IS_OK(nt_status))
3842 for (i = 0; i < ctr_src.num_entries; i++) {
3844 fstring netname = "", remark = "", path = "";
3845 /* reset error-code */
3846 nt_status = NT_STATUS_UNSUCCESSFUL;
3848 rpcstr_pull_unistr2_fstring(
3849 netname, &ctr_src.share.info502[i].info_502_str.uni_netname);
3850 rpcstr_pull_unistr2_fstring(
3851 remark, &ctr_src.share.info502[i].info_502_str.uni_remark);
3852 rpcstr_pull_unistr2_fstring(
3853 path, &ctr_src.share.info502[i].info_502_str.uni_path);
3855 if (!check_share_sanity(cli, netname, ctr_src.share.info502[i].info_502.type))
3858 printf("migrating: [%s], path: %s, comment: %s, including share-ACLs\n",
3859 netname, path, remark);
3862 display_sec_desc(ctr_src.share.info502[i].info_502_str.sd);
3867 info.switch_value = level;
3868 info.ptr_share_ctr = 1;
3870 /* FIXME: shouldn't we be able to just set the security descriptor ? */
3871 info.share.info502 = ctr_src.share.info502[i];
3873 /* finally modify the share on the dst server */
3874 result = rpccli_srvsvc_net_share_set_info(srvsvc_pipe, mem_ctx, netname, level, &info);
3876 if (!W_ERROR_IS_OK(result)) {
3877 printf("cannot set share-acl: %s\n", dos_errstr(result));
3883 nt_status = NT_STATUS_OK;
3887 cli_shutdown(cli_dst);
3895 * Migrate share-acls from a rpc-server to another
3897 * @param argc Standard main() style argc
3898 * @param argv Standard main() style argv. Initial components are already
3901 * @return A shell status integer (0 for success)
3903 static int rpc_share_migrate_security(int argc, const char **argv)
3907 printf("no server to migrate\n");
3911 return run_rpc_command(NULL, PI_SRVSVC, 0,
3912 rpc_share_migrate_security_internals,
3917 * Migrate shares (including share-definitions, share-acls and files with acls/attrs)
3918 * from one server to another
3920 * @param argc Standard main() style argc
3921 * @param argv Standard main() style argv. Initial components are already
3924 * @return A shell status integer (0 for success)
3927 static int rpc_share_migrate_all(int argc, const char **argv)
3932 printf("no server to migrate\n");
3936 /* order is important. we don't want to be locked out by the share-acl
3937 * before copying files - gd */
3939 ret = run_rpc_command(NULL, PI_SRVSVC, 0, rpc_share_migrate_shares_internals, argc, argv);
3943 ret = run_rpc_command(NULL, PI_SRVSVC, 0, rpc_share_migrate_files_internals, argc, argv);
3947 return run_rpc_command(NULL, PI_SRVSVC, 0, rpc_share_migrate_security_internals, argc, argv);
3952 * 'net rpc share migrate' entrypoint.
3953 * @param argc Standard main() style argc
3954 * @param argv Standard main() style argv. Initial components are already
3957 static int rpc_share_migrate(int argc, const char **argv)
3960 struct functable func[] = {
3961 {"all", rpc_share_migrate_all},
3962 {"files", rpc_share_migrate_files},
3963 {"help", rpc_share_usage},
3964 {"security", rpc_share_migrate_security},
3965 {"shares", rpc_share_migrate_shares},
3969 net_mode_share = NET_MODE_SHARE_MIGRATE;
3971 return net_run_function(argc, argv, func, rpc_share_usage);
3980 static int num_server_aliases;
3981 static struct full_alias *server_aliases;
3984 * Add an alias to the static list.
3986 static void push_alias(TALLOC_CTX *mem_ctx, struct full_alias *alias)
3988 if (server_aliases == NULL)
3989 server_aliases = SMB_MALLOC_ARRAY(struct full_alias, 100);
3991 server_aliases[num_server_aliases] = *alias;
3992 num_server_aliases += 1;
3996 * For a specific domain on the server, fetch all the aliases
3997 * and their members. Add all of them to the server_aliases.
4000 static NTSTATUS rpc_fetch_domain_aliases(struct rpc_pipe_client *pipe_hnd,
4001 TALLOC_CTX *mem_ctx,
4002 POLICY_HND *connect_pol,
4003 const DOM_SID *domain_sid)
4005 uint32 start_idx, max_entries, num_entries, i;
4006 struct acct_info *groups;
4008 POLICY_HND domain_pol;
4010 /* Get domain policy handle */
4012 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, connect_pol,
4013 MAXIMUM_ALLOWED_ACCESS,
4014 domain_sid, &domain_pol);
4015 if (!NT_STATUS_IS_OK(result))
4022 result = rpccli_samr_enum_als_groups(pipe_hnd, mem_ctx, &domain_pol,
4023 &start_idx, max_entries,
4024 &groups, &num_entries);
4026 for (i = 0; i < num_entries; i++) {
4028 POLICY_HND alias_pol;
4029 struct full_alias alias;
4033 result = rpccli_samr_open_alias(pipe_hnd, mem_ctx, &domain_pol,
4034 MAXIMUM_ALLOWED_ACCESS,
4037 if (!NT_STATUS_IS_OK(result))
4040 result = rpccli_samr_query_aliasmem(pipe_hnd, mem_ctx,
4044 if (!NT_STATUS_IS_OK(result))
4047 result = rpccli_samr_close(pipe_hnd, mem_ctx, &alias_pol);
4048 if (!NT_STATUS_IS_OK(result))
4051 alias.members = NULL;
4053 if (alias.num_members > 0) {
4054 alias.members = SMB_MALLOC_ARRAY(DOM_SID, alias.num_members);
4056 for (j = 0; j < alias.num_members; j++)
4057 sid_copy(&alias.members[j],
4061 sid_copy(&alias.sid, domain_sid);
4062 sid_append_rid(&alias.sid, groups[i].rid);
4064 push_alias(mem_ctx, &alias);
4066 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
4068 result = NT_STATUS_OK;
4071 rpccli_samr_close(pipe_hnd, mem_ctx, &domain_pol);
4077 * Dump server_aliases as names for debugging purposes.
4080 static NTSTATUS rpc_aliaslist_dump(const DOM_SID *domain_sid,
4081 const char *domain_name,
4082 struct cli_state *cli,
4083 struct rpc_pipe_client *pipe_hnd,
4084 TALLOC_CTX *mem_ctx,
4092 result = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, True,
4093 SEC_RIGHTS_MAXIMUM_ALLOWED,
4095 if (!NT_STATUS_IS_OK(result))
4098 for (i=0; i<num_server_aliases; i++) {
4101 enum lsa_SidType *types;
4104 struct full_alias *alias = &server_aliases[i];
4106 result = rpccli_lsa_lookup_sids(pipe_hnd, mem_ctx, &lsa_pol, 1,
4108 &domains, &names, &types);
4109 if (!NT_STATUS_IS_OK(result))
4112 DEBUG(1, ("%s\\%s %d: ", domains[0], names[0], types[0]));
4114 if (alias->num_members == 0) {
4119 result = rpccli_lsa_lookup_sids(pipe_hnd, mem_ctx, &lsa_pol,
4122 &domains, &names, &types);
4124 if (!NT_STATUS_IS_OK(result) &&
4125 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
4128 for (j=0; j<alias->num_members; j++)
4129 DEBUG(1, ("%s\\%s (%d); ",
4130 domains[j] ? domains[j] : "*unknown*",
4131 names[j] ? names[j] : "*unknown*",types[j]));
4135 rpccli_lsa_Close(pipe_hnd, mem_ctx, &lsa_pol);
4137 return NT_STATUS_OK;
4141 * Fetch a list of all server aliases and their members into
4145 static NTSTATUS rpc_aliaslist_internals(const DOM_SID *domain_sid,
4146 const char *domain_name,
4147 struct cli_state *cli,
4148 struct rpc_pipe_client *pipe_hnd,
4149 TALLOC_CTX *mem_ctx,
4154 POLICY_HND connect_pol;
4156 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
4159 if (!NT_STATUS_IS_OK(result))
4162 result = rpc_fetch_domain_aliases(pipe_hnd, mem_ctx, &connect_pol,
4163 &global_sid_Builtin);
4165 if (!NT_STATUS_IS_OK(result))
4168 result = rpc_fetch_domain_aliases(pipe_hnd, mem_ctx, &connect_pol,
4171 rpccli_samr_close(pipe_hnd, mem_ctx, &connect_pol);
4176 static void init_user_token(NT_USER_TOKEN *token, DOM_SID *user_sid)
4178 token->num_sids = 4;
4180 if (!(token->user_sids = SMB_MALLOC_ARRAY(DOM_SID, 4))) {
4181 d_fprintf(stderr, "malloc failed\n");
4182 token->num_sids = 0;
4186 token->user_sids[0] = *user_sid;
4187 sid_copy(&token->user_sids[1], &global_sid_World);
4188 sid_copy(&token->user_sids[2], &global_sid_Network);
4189 sid_copy(&token->user_sids[3], &global_sid_Authenticated_Users);
4192 static void free_user_token(NT_USER_TOKEN *token)
4194 SAFE_FREE(token->user_sids);
4197 static bool is_sid_in_token(NT_USER_TOKEN *token, DOM_SID *sid)
4201 for (i=0; i<token->num_sids; i++) {
4202 if (sid_compare(sid, &token->user_sids[i]) == 0)
4208 static void add_sid_to_token(NT_USER_TOKEN *token, DOM_SID *sid)
4210 if (is_sid_in_token(token, sid))
4213 token->user_sids = SMB_REALLOC_ARRAY(token->user_sids, DOM_SID, token->num_sids+1);
4214 if (!token->user_sids) {
4218 sid_copy(&token->user_sids[token->num_sids], sid);
4220 token->num_sids += 1;
4225 NT_USER_TOKEN token;
4228 static void dump_user_token(struct user_token *token)
4232 d_printf("%s\n", token->name);
4234 for (i=0; i<token->token.num_sids; i++) {
4235 d_printf(" %s\n", sid_string_tos(&token->token.user_sids[i]));
4239 static bool is_alias_member(DOM_SID *sid, struct full_alias *alias)
4243 for (i=0; i<alias->num_members; i++) {
4244 if (sid_compare(sid, &alias->members[i]) == 0)
4251 static void collect_sid_memberships(NT_USER_TOKEN *token, DOM_SID sid)
4255 for (i=0; i<num_server_aliases; i++) {
4256 if (is_alias_member(&sid, &server_aliases[i]))
4257 add_sid_to_token(token, &server_aliases[i].sid);
4262 * We got a user token with all the SIDs we can know about without asking the
4263 * server directly. These are the user and domain group sids. All of these can
4264 * be members of aliases. So scan the list of aliases for each of the SIDs and
4265 * add them to the token.
4268 static void collect_alias_memberships(NT_USER_TOKEN *token)
4270 int num_global_sids = token->num_sids;
4273 for (i=0; i<num_global_sids; i++) {
4274 collect_sid_memberships(token, token->user_sids[i]);
4278 static bool get_user_sids(const char *domain, const char *user, NT_USER_TOKEN *token)
4280 struct winbindd_request request;
4281 struct winbindd_response response;
4289 fstr_sprintf(full_name, "%s%c%s",
4290 domain, *lp_winbind_separator(), user);
4292 /* First let's find out the user sid */
4294 ZERO_STRUCT(request);
4295 ZERO_STRUCT(response);
4297 fstrcpy(request.data.name.dom_name, domain);
4298 fstrcpy(request.data.name.name, user);
4300 result = winbindd_request_response(WINBINDD_LOOKUPNAME, &request, &response);
4302 if (result != NSS_STATUS_SUCCESS) {
4303 DEBUG(1, ("winbind could not find %s\n", full_name));
4307 if (response.data.sid.type != SID_NAME_USER) {
4308 DEBUG(1, ("%s is not a user\n", full_name));
4312 string_to_sid(&user_sid, response.data.sid.sid);
4314 init_user_token(token, &user_sid);
4316 /* And now the groups winbind knows about */
4318 ZERO_STRUCT(response);
4320 fstrcpy(request.data.username, full_name);
4322 result = winbindd_request_response(WINBINDD_GETGROUPS, &request, &response);
4324 if (result != NSS_STATUS_SUCCESS) {
4325 DEBUG(1, ("winbind could not get groups of %s\n", full_name));
4329 for (i = 0; i < response.data.num_entries; i++) {
4330 gid_t gid = ((gid_t *)response.extra_data.data)[i];
4333 struct winbindd_request sidrequest;
4334 struct winbindd_response sidresponse;
4336 ZERO_STRUCT(sidrequest);
4337 ZERO_STRUCT(sidresponse);
4339 sidrequest.data.gid = gid;
4341 result = winbindd_request_response(WINBINDD_GID_TO_SID,
4342 &sidrequest, &sidresponse);
4344 if (result != NSS_STATUS_SUCCESS) {
4345 DEBUG(1, ("winbind could not find SID of gid %d\n",
4350 DEBUG(3, (" %s\n", sidresponse.data.sid.sid));
4352 string_to_sid(&sid, sidresponse.data.sid.sid);
4353 add_sid_to_token(token, &sid);
4356 SAFE_FREE(response.extra_data.data);
4362 * Get a list of all user tokens we want to look at
4365 static bool get_user_tokens(int *num_tokens, struct user_token **user_tokens)
4367 struct winbindd_request request;
4368 struct winbindd_response response;
4369 const char *extra_data;
4372 struct user_token *result;
4373 TALLOC_CTX *frame = NULL;
4375 if (lp_winbind_use_default_domain() &&
4376 (opt_target_workgroup == NULL)) {
4377 d_fprintf(stderr, "winbind use default domain = yes set, "
4378 "please specify a workgroup\n");
4382 /* Send request to winbind daemon */
4384 ZERO_STRUCT(request);
4385 ZERO_STRUCT(response);
4387 if (winbindd_request_response(WINBINDD_LIST_USERS, &request, &response) !=
4391 /* Look through extra data */
4393 if (!response.extra_data.data)
4396 extra_data = (const char *)response.extra_data.data;
4399 frame = talloc_stackframe();
4400 while(next_token_talloc(frame, &extra_data, &name, ",")) {
4404 result = SMB_MALLOC_ARRAY(struct user_token, *num_tokens);
4406 if (result == NULL) {
4407 DEBUG(1, ("Could not malloc sid array\n"));
4412 extra_data = (const char *)response.extra_data.data;
4415 while(next_token_talloc(frame, &extra_data, &name, ",")) {
4416 fstring domain, user;
4419 fstrcpy(result[i].name, name);
4421 p = strchr(name, *lp_winbind_separator());
4423 DEBUG(3, ("%s\n", name));
4426 fstrcpy(domain, opt_target_workgroup);
4427 fstrcpy(user, name);
4430 fstrcpy(domain, name);
4435 get_user_sids(domain, user, &(result[i].token));
4439 SAFE_FREE(response.extra_data.data);
4441 *user_tokens = result;
4446 static bool get_user_tokens_from_file(FILE *f,
4448 struct user_token **tokens)
4450 struct user_token *token = NULL;
4455 if (fgets(line, sizeof(line)-1, f) == NULL) {
4459 if (line[strlen(line)-1] == '\n')
4460 line[strlen(line)-1] = '\0';
4462 if (line[0] == ' ') {
4466 string_to_sid(&sid, &line[1]);
4468 if (token == NULL) {
4469 DEBUG(0, ("File does not begin with username"));
4473 add_sid_to_token(&token->token, &sid);
4477 /* And a new user... */
4480 *tokens = SMB_REALLOC_ARRAY(*tokens, struct user_token, *num_tokens);
4481 if (*tokens == NULL) {
4482 DEBUG(0, ("Could not realloc tokens\n"));
4486 token = &((*tokens)[*num_tokens-1]);
4488 fstrcpy(token->name, line);
4489 token->token.num_sids = 0;
4490 token->token.user_sids = NULL;
4499 * Show the list of all users that have access to a share
4502 static void show_userlist(struct rpc_pipe_client *pipe_hnd,
4503 TALLOC_CTX *mem_ctx,
4504 const char *netname,
4506 struct user_token *tokens)
4509 SEC_DESC *share_sd = NULL;
4510 SEC_DESC *root_sd = NULL;
4511 struct cli_state *cli = pipe_hnd->cli;
4513 SRV_SHARE_INFO info;
4517 result = rpccli_srvsvc_net_share_get_info(pipe_hnd, mem_ctx, netname,
4520 if (!W_ERROR_IS_OK(result)) {
4521 DEBUG(1, ("Coult not query secdesc for share %s\n",
4526 share_sd = info.share.info502.info_502_str.sd;
4527 if (share_sd == NULL) {
4528 DEBUG(1, ("Got no secdesc for share %s\n",
4534 if (!cli_send_tconX(cli, netname, "A:", "", 0)) {
4538 fnum = cli_nt_create(cli, "\\", READ_CONTROL_ACCESS);
4541 root_sd = cli_query_secdesc(cli, fnum, mem_ctx);
4544 for (i=0; i<num_tokens; i++) {
4548 if (share_sd != NULL) {
4549 if (!se_access_check(share_sd, &tokens[i].token,
4550 1, &acc_granted, &status)) {
4551 DEBUG(1, ("Could not check share_sd for "
4557 if (!NT_STATUS_IS_OK(status))
4561 if (root_sd == NULL) {
4562 d_printf(" %s\n", tokens[i].name);
4566 if (!se_access_check(root_sd, &tokens[i].token,
4567 1, &acc_granted, &status)) {
4568 DEBUG(1, ("Could not check root_sd for user %s\n",
4573 if (!NT_STATUS_IS_OK(status))
4576 d_printf(" %s\n", tokens[i].name);
4580 cli_close(cli, fnum);
4592 static void collect_share(const char *name, uint32 m,
4593 const char *comment, void *state)
4595 struct share_list *share_list = (struct share_list *)state;
4597 if (m != STYPE_DISKTREE)
4600 share_list->num_shares += 1;
4601 share_list->shares = SMB_REALLOC_ARRAY(share_list->shares, char *, share_list->num_shares);
4602 if (!share_list->shares) {
4603 share_list->num_shares = 0;
4606 share_list->shares[share_list->num_shares-1] = SMB_STRDUP(name);
4609 static void rpc_share_userlist_usage(void)
4615 * List shares on a remote RPC server, including the security descriptors
4617 * All parameters are provided by the run_rpc_command function, except for
4618 * argc, argv which are passes through.
4620 * @param domain_sid The domain sid acquired from the remote server
4621 * @param cli A cli_state connected to the server.
4622 * @param mem_ctx Talloc context, destoyed on completion of the function.
4623 * @param argc Standard main() style argc
4624 * @param argv Standard main() style argv. Initial components are already
4627 * @return Normal NTSTATUS return.
4630 static NTSTATUS rpc_share_allowedusers_internals(const DOM_SID *domain_sid,
4631 const char *domain_name,
4632 struct cli_state *cli,
4633 struct rpc_pipe_client *pipe_hnd,
4634 TALLOC_CTX *mem_ctx,
4644 struct user_token *tokens = NULL;
4647 struct share_list share_list;
4650 rpc_share_userlist_usage();
4651 return NT_STATUS_UNSUCCESSFUL;
4657 f = fopen(argv[0], "r");
4661 DEBUG(0, ("Could not open userlist: %s\n", strerror(errno)));
4662 return NT_STATUS_UNSUCCESSFUL;
4665 r = get_user_tokens_from_file(f, &num_tokens, &tokens);
4671 DEBUG(0, ("Could not read users from file\n"));
4672 return NT_STATUS_UNSUCCESSFUL;
4675 for (i=0; i<num_tokens; i++)
4676 collect_alias_memberships(&tokens[i].token);
4678 init_enum_hnd(&hnd, 0);
4680 share_list.num_shares = 0;
4681 share_list.shares = NULL;
4683 ret = cli_RNetShareEnum(cli, collect_share, &share_list);
4686 DEBUG(0, ("Error returning browse list: %s\n",
4691 for (i = 0; i < share_list.num_shares; i++) {
4692 char *netname = share_list.shares[i];
4694 if (netname[strlen(netname)-1] == '$')
4697 d_printf("%s\n", netname);
4699 show_userlist(pipe_hnd, mem_ctx, netname,
4700 num_tokens, tokens);
4703 for (i=0; i<num_tokens; i++) {
4704 free_user_token(&tokens[i].token);
4707 SAFE_FREE(share_list.shares);
4709 return NT_STATUS_OK;
4712 static int rpc_share_allowedusers(int argc, const char **argv)
4716 result = run_rpc_command(NULL, PI_SAMR, 0,
4717 rpc_aliaslist_internals,
4722 result = run_rpc_command(NULL, PI_LSARPC, 0,
4728 return run_rpc_command(NULL, PI_SRVSVC, 0,
4729 rpc_share_allowedusers_internals,
4733 int net_usersidlist(int argc, const char **argv)
4736 struct user_token *tokens = NULL;
4740 net_usersidlist_usage(argc, argv);
4744 if (!get_user_tokens(&num_tokens, &tokens)) {
4745 DEBUG(0, ("Could not get the user/sid list\n"));
4749 for (i=0; i<num_tokens; i++) {
4750 dump_user_token(&tokens[i]);
4751 free_user_token(&tokens[i].token);
4758 int net_usersidlist_usage(int argc, const char **argv)
4760 d_printf("net usersidlist\n"
4761 "\tprints out a list of all users the running winbind knows\n"
4762 "\tabout, together with all their SIDs. This is used as\n"
4763 "\tinput to the 'net rpc share allowedusers' command.\n\n");
4765 net_common_flags_usage(argc, argv);
4770 * 'net rpc share' entrypoint.
4771 * @param argc Standard main() style argc
4772 * @param argv Standard main() style argv. Initial components are already
4776 int net_rpc_share(int argc, const char **argv)
4778 struct functable func[] = {
4779 {"add", rpc_share_add},
4780 {"delete", rpc_share_delete},
4781 {"allowedusers", rpc_share_allowedusers},
4782 {"migrate", rpc_share_migrate},
4783 {"list", rpc_share_list},
4788 return run_rpc_command(NULL, PI_SRVSVC, 0,
4789 rpc_share_list_internals,
4792 return net_run_function(argc, argv, func, rpc_share_usage);
4795 static NTSTATUS rpc_sh_share_list(TALLOC_CTX *mem_ctx,
4796 struct rpc_sh_ctx *ctx,
4797 struct rpc_pipe_client *pipe_hnd,
4798 int argc, const char **argv)
4800 return rpc_share_list_internals(ctx->domain_sid, ctx->domain_name,
4801 ctx->cli, pipe_hnd, mem_ctx,
4805 static NTSTATUS rpc_sh_share_add(TALLOC_CTX *mem_ctx,
4806 struct rpc_sh_ctx *ctx,
4807 struct rpc_pipe_client *pipe_hnd,
4808 int argc, const char **argv)
4812 if ((argc < 2) || (argc > 3)) {
4813 d_fprintf(stderr, "usage: %s <share> <path> [comment]\n",
4815 return NT_STATUS_INVALID_PARAMETER;
4818 result = rpccli_srvsvc_net_share_add(
4819 pipe_hnd, mem_ctx, argv[0], STYPE_DISKTREE,
4820 (argc == 3) ? argv[2] : "",
4821 0, 0, 0, argv[1], NULL, 2, NULL);
4823 return werror_to_ntstatus(result);
4826 static NTSTATUS rpc_sh_share_delete(TALLOC_CTX *mem_ctx,
4827 struct rpc_sh_ctx *ctx,
4828 struct rpc_pipe_client *pipe_hnd,
4829 int argc, const char **argv)
4834 d_fprintf(stderr, "usage: %s <share>\n", ctx->whoami);
4835 return NT_STATUS_INVALID_PARAMETER;
4838 result = rpccli_srvsvc_net_share_del(pipe_hnd, mem_ctx, argv[0]);
4839 return werror_to_ntstatus(result);
4842 static NTSTATUS rpc_sh_share_info(TALLOC_CTX *mem_ctx,
4843 struct rpc_sh_ctx *ctx,
4844 struct rpc_pipe_client *pipe_hnd,
4845 int argc, const char **argv)
4847 SRV_SHARE_INFO info;
4848 SRV_SHARE_INFO_2 *info2 = &info.share.info2;
4852 d_fprintf(stderr, "usage: %s <share>\n", ctx->whoami);
4853 return NT_STATUS_INVALID_PARAMETER;
4856 result = rpccli_srvsvc_net_share_get_info(
4857 pipe_hnd, mem_ctx, argv[0], 2, &info);
4858 if (!W_ERROR_IS_OK(result)) {
4862 d_printf("Name: %s\n",
4863 rpcstr_pull_unistr2_talloc(mem_ctx,
4864 &info2->info_2_str.uni_netname));
4865 d_printf("Comment: %s\n",
4866 rpcstr_pull_unistr2_talloc(mem_ctx,
4867 &info2->info_2_str.uni_remark));
4869 d_printf("Path: %s\n",
4870 rpcstr_pull_unistr2_talloc(mem_ctx,
4871 &info2->info_2_str.uni_path));
4872 d_printf("Password: %s\n",
4873 rpcstr_pull_unistr2_talloc(mem_ctx,
4874 &info2->info_2_str.uni_passwd));
4877 return werror_to_ntstatus(result);
4880 struct rpc_sh_cmd *net_rpc_share_cmds(TALLOC_CTX *mem_ctx,
4881 struct rpc_sh_ctx *ctx)
4883 static struct rpc_sh_cmd cmds[] = {
4885 { "list", NULL, PI_SRVSVC, rpc_sh_share_list,
4886 "List available shares" },
4888 { "add", NULL, PI_SRVSVC, rpc_sh_share_add,
4891 { "delete", NULL, PI_SRVSVC, rpc_sh_share_delete,
4894 { "info", NULL, PI_SRVSVC, rpc_sh_share_info,
4895 "Get information about a share" },
4897 { NULL, NULL, 0, NULL, NULL }
4903 /****************************************************************************/
4905 static int rpc_file_usage(int argc, const char **argv)
4907 return net_help_file(argc, argv);
4911 * Close a file on a remote RPC server
4913 * All parameters are provided by the run_rpc_command function, except for
4914 * argc, argv which are passes through.
4916 * @param domain_sid The domain sid acquired from the remote server
4917 * @param cli A cli_state connected to the server.
4918 * @param mem_ctx Talloc context, destoyed on completion of the function.
4919 * @param argc Standard main() style argc
4920 * @param argv Standard main() style argv. Initial components are already
4923 * @return Normal NTSTATUS return.
4925 static NTSTATUS rpc_file_close_internals(const DOM_SID *domain_sid,
4926 const char *domain_name,
4927 struct cli_state *cli,
4928 struct rpc_pipe_client *pipe_hnd,
4929 TALLOC_CTX *mem_ctx,
4933 return rpccli_srvsvc_NetFileClose(pipe_hnd, mem_ctx,
4934 pipe_hnd->cli->desthost,
4935 atoi(argv[0]), NULL);
4939 * Close a file on a remote RPC server
4941 * @param argc Standard main() style argc
4942 * @param argv Standard main() style argv. Initial components are already
4945 * @return A shell status integer (0 for success)
4947 static int rpc_file_close(int argc, const char **argv)
4950 DEBUG(1, ("No fileid given on close\n"));
4951 return(rpc_file_usage(argc, argv));
4954 return run_rpc_command(NULL, PI_SRVSVC, 0,
4955 rpc_file_close_internals,
4960 * Formatted print of open file info
4962 * @param info3 FILE_INFO_3 contents
4963 * @param str3 strings for FILE_INFO_3
4966 static void display_file_info_3( FILE_INFO_3 *info3 )
4968 fstring user = "", path = "";
4970 rpcstr_pull_unistr2_fstring(user, info3->user);
4971 rpcstr_pull_unistr2_fstring(path, info3->path);
4973 d_printf("%-7.1d %-20.20s 0x%-4.2x %-6.1d %s\n",
4974 info3->id, user, info3->perms, info3->num_locks, path);
4978 * List open files on a remote RPC server
4980 * All parameters are provided by the run_rpc_command function, except for
4981 * argc, argv which are passes through.
4983 * @param domain_sid The domain sid acquired from the remote server
4984 * @param cli A cli_state connected to the server.
4985 * @param mem_ctx Talloc context, destoyed on completion of the function.
4986 * @param argc Standard main() style argc
4987 * @param argv Standard main() style argv. Initial components are already
4990 * @return Normal NTSTATUS return.
4993 static NTSTATUS rpc_file_list_internals(const DOM_SID *domain_sid,
4994 const char *domain_name,
4995 struct cli_state *cli,
4996 struct rpc_pipe_client *pipe_hnd,
4997 TALLOC_CTX *mem_ctx,
5001 SRV_FILE_INFO_CTR ctr;
5004 uint32 preferred_len = 0xffffffff, i;
5005 const char *username=NULL;
5007 init_enum_hnd(&hnd, 0);
5009 /* if argc > 0, must be user command */
5011 username = smb_xstrdup(argv[0]);
5013 result = rpccli_srvsvc_net_file_enum(pipe_hnd,
5014 mem_ctx, 3, username, &ctr, preferred_len, &hnd);
5016 if (!W_ERROR_IS_OK(result))
5019 /* Display results */
5022 "\nEnumerating open files on remote server:\n\n"\
5023 "\nFileId Opened by Perms Locks Path"\
5024 "\n------ --------- ----- ----- ---- \n");
5025 for (i = 0; i < ctr.num_entries; i++)
5026 display_file_info_3(&ctr.file.info3[i]);
5028 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
5032 * List files for a user on a remote RPC server
5034 * @param argc Standard main() style argc
5035 * @param argv Standard main() style argv. Initial components are already
5038 * @return A shell status integer (0 for success)
5041 static int rpc_file_user(int argc, const char **argv)
5044 DEBUG(1, ("No username given\n"));
5045 return(rpc_file_usage(argc, argv));
5048 return run_rpc_command(NULL, PI_SRVSVC, 0,
5049 rpc_file_list_internals,
5054 * 'net rpc file' entrypoint.
5055 * @param argc Standard main() style argc
5056 * @param argv Standard main() style argv. Initial components are already
5060 int net_rpc_file(int argc, const char **argv)
5062 struct functable func[] = {
5063 {"close", rpc_file_close},
5064 {"user", rpc_file_user},
5066 {"info", rpc_file_info},
5072 return run_rpc_command(NULL, PI_SRVSVC, 0,
5073 rpc_file_list_internals,
5076 return net_run_function(argc, argv, func, rpc_file_usage);
5080 * ABORT the shutdown of a remote RPC Server over, initshutdown pipe
5082 * All parameters are provided by the run_rpc_command function, except for
5083 * argc, argv which are passed through.
5085 * @param domain_sid The domain sid aquired from the remote server
5086 * @param cli A cli_state connected to the server.
5087 * @param mem_ctx Talloc context, destoyed on compleation of the function.
5088 * @param argc Standard main() style argc
5089 * @param argv Standard main() style argv. Initial components are already
5092 * @return Normal NTSTATUS return.
5095 static NTSTATUS rpc_shutdown_abort_internals(const DOM_SID *domain_sid,
5096 const char *domain_name,
5097 struct cli_state *cli,
5098 struct rpc_pipe_client *pipe_hnd,
5099 TALLOC_CTX *mem_ctx,
5103 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
5105 result = rpccli_initshutdown_Abort(pipe_hnd, mem_ctx, NULL, NULL);
5107 if (NT_STATUS_IS_OK(result)) {
5108 d_printf("\nShutdown successfully aborted\n");
5109 DEBUG(5,("cmd_shutdown_abort: query succeeded\n"));
5111 DEBUG(5,("cmd_shutdown_abort: query failed\n"));
5117 * ABORT the shutdown of a remote RPC Server, over winreg pipe
5119 * All parameters are provided by the run_rpc_command function, except for
5120 * argc, argv which are passed through.
5122 * @param domain_sid The domain sid aquired from the remote server
5123 * @param cli A cli_state connected to the server.
5124 * @param mem_ctx Talloc context, destoyed on compleation of the function.
5125 * @param argc Standard main() style argc
5126 * @param argv Standard main() style argv. Initial components are already
5129 * @return Normal NTSTATUS return.
5132 static NTSTATUS rpc_reg_shutdown_abort_internals(const DOM_SID *domain_sid,
5133 const char *domain_name,
5134 struct cli_state *cli,
5135 struct rpc_pipe_client *pipe_hnd,
5136 TALLOC_CTX *mem_ctx,
5140 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
5142 result = rpccli_winreg_AbortSystemShutdown(pipe_hnd, mem_ctx, NULL, NULL);
5144 if (NT_STATUS_IS_OK(result)) {
5145 d_printf("\nShutdown successfully aborted\n");
5146 DEBUG(5,("cmd_reg_abort_shutdown: query succeeded\n"));
5148 DEBUG(5,("cmd_reg_abort_shutdown: query failed\n"));
5154 * ABORT the Shut down of a remote RPC server
5156 * @param argc Standard main() style argc
5157 * @param argv Standard main() style argv. Initial components are already
5160 * @return A shell status integer (0 for success)
5163 static int rpc_shutdown_abort(int argc, const char **argv)
5165 int rc = run_rpc_command(NULL, PI_INITSHUTDOWN, 0,
5166 rpc_shutdown_abort_internals,
5172 DEBUG(1, ("initshutdown pipe didn't work, trying winreg pipe\n"));
5174 return run_rpc_command(NULL, PI_WINREG, 0,
5175 rpc_reg_shutdown_abort_internals,
5180 * Shut down a remote RPC Server via initshutdown pipe
5182 * All parameters are provided by the run_rpc_command function, except for
5183 * argc, argv which are passes through.
5185 * @param domain_sid The domain sid aquired from the remote server
5186 * @param cli A cli_state connected to the server.
5187 * @param mem_ctx Talloc context, destoyed on compleation of the function.
5188 * @param argc Standard main() style argc
5189 * @param argc Standard main() style argv. Initial components are already
5192 * @return Normal NTSTATUS return.
5195 NTSTATUS rpc_init_shutdown_internals(const DOM_SID *domain_sid,
5196 const char *domain_name,
5197 struct cli_state *cli,
5198 struct rpc_pipe_client *pipe_hnd,
5199 TALLOC_CTX *mem_ctx,
5203 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
5204 const char *msg = "This machine will be shutdown shortly";
5205 uint32 timeout = 20;
5206 struct initshutdown_String msg_string;
5207 struct initshutdown_String_sub s;
5213 timeout = opt_timeout;
5217 msg_string.name = &s;
5219 /* create an entry */
5220 result = rpccli_initshutdown_Init(pipe_hnd, mem_ctx, NULL,
5221 &msg_string, timeout, opt_force, opt_reboot, NULL);
5223 if (NT_STATUS_IS_OK(result)) {
5224 d_printf("\nShutdown of remote machine succeeded\n");
5225 DEBUG(5,("Shutdown of remote machine succeeded\n"));
5227 DEBUG(1,("Shutdown of remote machine failed!\n"));
5233 * Shut down a remote RPC Server via winreg pipe
5235 * All parameters are provided by the run_rpc_command function, except for
5236 * argc, argv which are passes through.
5238 * @param domain_sid The domain sid aquired from the remote server
5239 * @param cli A cli_state connected to the server.
5240 * @param mem_ctx Talloc context, destoyed on compleation of the function.
5241 * @param argc Standard main() style argc
5242 * @param argc Standard main() style argv. Initial components are already
5245 * @return Normal NTSTATUS return.
5248 NTSTATUS rpc_reg_shutdown_internals(const DOM_SID *domain_sid,
5249 const char *domain_name,
5250 struct cli_state *cli,
5251 struct rpc_pipe_client *pipe_hnd,
5252 TALLOC_CTX *mem_ctx,
5256 const char *msg = "This machine will be shutdown shortly";
5257 uint32 timeout = 20;
5258 struct initshutdown_String msg_string;
5259 struct initshutdown_String_sub s;
5267 msg_string.name = &s;
5270 timeout = opt_timeout;
5273 /* create an entry */
5274 result = rpccli_winreg_InitiateSystemShutdown(pipe_hnd, mem_ctx, NULL,
5275 &msg_string, timeout, opt_force, opt_reboot, &werr);
5277 if (NT_STATUS_IS_OK(result)) {
5278 d_printf("\nShutdown of remote machine succeeded\n");
5280 d_fprintf(stderr, "\nShutdown of remote machine failed\n");
5281 if ( W_ERROR_EQUAL(werr, WERR_MACHINE_LOCKED) )
5282 d_fprintf(stderr, "\nMachine locked, use -f switch to force\n");
5284 d_fprintf(stderr, "\nresult was: %s\n", dos_errstr(werr));
5291 * Shut down a remote RPC server
5293 * @param argc Standard main() style argc
5294 * @param argc Standard main() style argv. Initial components are already
5297 * @return A shell status integer (0 for success)
5300 static int rpc_shutdown(int argc, const char **argv)
5302 int rc = run_rpc_command(NULL, PI_INITSHUTDOWN, 0,
5303 rpc_init_shutdown_internals,
5307 DEBUG(1, ("initshutdown pipe failed, trying winreg pipe\n"));
5308 rc = run_rpc_command(NULL, PI_WINREG, 0,
5309 rpc_reg_shutdown_internals, argc, argv);
5315 /***************************************************************************
5316 NT Domain trusts code (i.e. 'net rpc trustdom' functionality)
5318 ***************************************************************************/
5321 * Add interdomain trust account to the RPC server.
5322 * All parameters (except for argc and argv) are passed by run_rpc_command
5325 * @param domain_sid The domain sid acquired from the server
5326 * @param cli A cli_state connected to the server.
5327 * @param mem_ctx Talloc context, destoyed on completion of the function.
5328 * @param argc Standard main() style argc
5329 * @param argc Standard main() style argv. Initial components are already
5332 * @return normal NTSTATUS return code
5335 static NTSTATUS rpc_trustdom_add_internals(const DOM_SID *domain_sid,
5336 const char *domain_name,
5337 struct cli_state *cli,
5338 struct rpc_pipe_client *pipe_hnd,
5339 TALLOC_CTX *mem_ctx,
5343 POLICY_HND connect_pol, domain_pol, user_pol;
5344 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
5347 uint32 acct_flags=0;
5351 d_printf("Usage: net rpc trustdom add <domain_name> <pw>\n");
5352 return NT_STATUS_INVALID_PARAMETER;
5356 * Make valid trusting domain account (ie. uppercased and with '$' appended)
5359 if (asprintf(&acct_name, "%s$", argv[0]) < 0) {
5360 return NT_STATUS_NO_MEMORY;
5363 strupper_m(acct_name);
5365 /* Get samr policy handle */
5366 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
5368 if (!NT_STATUS_IS_OK(result)) {
5372 /* Get domain policy handle */
5373 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
5374 MAXIMUM_ALLOWED_ACCESS,
5375 domain_sid, &domain_pol);
5376 if (!NT_STATUS_IS_OK(result)) {
5380 /* Create trusting domain's account */
5381 acb_info = ACB_NORMAL;
5382 acct_flags = SAMR_GENERIC_READ | SAMR_GENERIC_WRITE |
5383 SAMR_GENERIC_EXECUTE | SAMR_STANDARD_WRITEDAC |
5384 SAMR_STANDARD_DELETE | SAMR_USER_SETPASS | SAMR_USER_GETATTR |
5387 result = rpccli_samr_create_dom_user(pipe_hnd, mem_ctx, &domain_pol,
5388 acct_name, acb_info, acct_flags,
5389 &user_pol, &user_rid);
5390 if (!NT_STATUS_IS_OK(result)) {
5395 SAM_USERINFO_CTR ctr;
5396 SAM_USER_INFO_23 p23;
5402 encode_pw_buffer(pwbuf, argv[1], STR_UNICODE);
5406 ZERO_STRUCT(notime);
5410 memset(hrs.hours, 0xFF, sizeof(hrs.hours));
5411 acb_info = ACB_DOMTRUST;
5413 init_sam_user_info23A(&p23, ¬ime, ¬ime, ¬ime,
5414 ¬ime, ¬ime, ¬ime,
5415 nostr, nostr, nostr, nostr, nostr,
5416 nostr, nostr, nostr, nostr, nostr,
5417 0, 0, acb_info, ACCT_FLAGS, 168, &hrs,
5418 0, 0, (char *)pwbuf);
5419 ctr.switch_value = 23;
5420 ctr.info.id23 = &p23;
5421 p23.passmustchange = 0;
5423 result = rpccli_samr_set_userinfo(pipe_hnd, mem_ctx, &user_pol, 23,
5424 &cli->user_session_key, &ctr);
5426 if (!NT_STATUS_IS_OK(result)) {
5427 DEBUG(0,("Could not set trust account password: %s\n",
5428 nt_errstr(result)));
5434 SAFE_FREE(acct_name);
5439 * Create interdomain trust account for a remote domain.
5441 * @param argc standard argc
5442 * @param argv standard argv without initial components
5444 * @return Integer status (0 means success)
5447 static int rpc_trustdom_add(int argc, const char **argv)
5450 return run_rpc_command(NULL, PI_SAMR, 0, rpc_trustdom_add_internals,
5453 d_printf("Usage: net rpc trustdom add <domain>\n");
5460 * Remove interdomain trust account from the RPC server.
5461 * All parameters (except for argc and argv) are passed by run_rpc_command
5464 * @param domain_sid The domain sid acquired from the server
5465 * @param cli A cli_state connected to the server.
5466 * @param mem_ctx Talloc context, destoyed on completion of the function.
5467 * @param argc Standard main() style argc
5468 * @param argc Standard main() style argv. Initial components are already
5471 * @return normal NTSTATUS return code
5474 static NTSTATUS rpc_trustdom_del_internals(const DOM_SID *domain_sid,
5475 const char *domain_name,
5476 struct cli_state *cli,
5477 struct rpc_pipe_client *pipe_hnd,
5478 TALLOC_CTX *mem_ctx,
5482 POLICY_HND connect_pol, domain_pol, user_pol;
5483 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
5486 DOM_SID trust_acct_sid;
5487 uint32 *user_rids, num_rids, *name_types;
5488 uint32 flags = 0x000003e8; /* Unknown */
5491 d_printf("Usage: net rpc trustdom del <domain_name>\n");
5492 return NT_STATUS_INVALID_PARAMETER;
5496 * Make valid trusting domain account (ie. uppercased and with '$' appended)
5498 acct_name = talloc_asprintf(mem_ctx, "%s$", argv[0]);
5500 if (acct_name == NULL)
5501 return NT_STATUS_NO_MEMORY;
5503 strupper_m(acct_name);
5505 if ((names = TALLOC_ARRAY(mem_ctx, const char *, 1)) == NULL) {
5506 return NT_STATUS_NO_MEMORY;
5508 names[0] = acct_name;
5511 /* Get samr policy handle */
5512 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
5514 if (!NT_STATUS_IS_OK(result)) {
5518 /* Get domain policy handle */
5519 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
5520 MAXIMUM_ALLOWED_ACCESS,
5521 domain_sid, &domain_pol);
5522 if (!NT_STATUS_IS_OK(result)) {
5526 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, flags, 1,
5528 &user_rids, &name_types);
5530 if (!NT_STATUS_IS_OK(result)) {
5534 result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
5535 MAXIMUM_ALLOWED_ACCESS,
5536 user_rids[0], &user_pol);
5538 if (!NT_STATUS_IS_OK(result)) {
5542 /* append the rid to the domain sid */
5543 sid_copy(&trust_acct_sid, domain_sid);
5544 if (!sid_append_rid(&trust_acct_sid, user_rids[0])) {
5548 /* remove the sid */
5550 result = rpccli_samr_remove_sid_foreign_domain(pipe_hnd, mem_ctx, &user_pol,
5553 if (!NT_STATUS_IS_OK(result)) {
5559 result = rpccli_samr_delete_dom_user(pipe_hnd, mem_ctx, &user_pol);
5561 if (!NT_STATUS_IS_OK(result)) {
5565 if (!NT_STATUS_IS_OK(result)) {
5566 DEBUG(0,("Could not set trust account password: %s\n",
5567 nt_errstr(result)));
5576 * Delete interdomain trust account for a remote domain.
5578 * @param argc standard argc
5579 * @param argv standard argv without initial components
5581 * @return Integer status (0 means success)
5584 static int rpc_trustdom_del(int argc, const char **argv)
5587 return run_rpc_command(NULL, PI_SAMR, 0, rpc_trustdom_del_internals,
5590 d_printf("Usage: net rpc trustdom del <domain>\n");
5597 * Establish trust relationship to a trusting domain.
5598 * Interdomain account must already be created on remote PDC.
5600 * @param argc standard argc
5601 * @param argv standard argv without initial components
5603 * @return Integer status (0 means success)
5606 static int rpc_trustdom_establish(int argc, const char **argv)
5608 struct cli_state *cli = NULL;
5609 struct sockaddr_storage server_ss;
5610 struct rpc_pipe_client *pipe_hnd = NULL;
5611 POLICY_HND connect_hnd;
5612 TALLOC_CTX *mem_ctx;
5614 DOM_SID *domain_sid;
5617 const char* domain_name_pol;
5623 * Connect to \\server\ipc$ as 'our domain' account with password
5627 d_printf("Usage: net rpc trustdom establish <domain_name>\n");
5631 domain_name = smb_xstrdup(argv[0]);
5632 strupper_m(domain_name);
5634 /* account name used at first is our domain's name with '$' */
5635 asprintf(&acct_name, "%s$", lp_workgroup());
5636 strupper_m(acct_name);
5639 * opt_workgroup will be used by connection functions further,
5640 * hence it should be set to remote domain name instead of ours
5642 if (opt_workgroup) {
5643 opt_workgroup = smb_xstrdup(domain_name);
5646 opt_user_name = acct_name;
5648 /* find the domain controller */
5649 if (!net_find_pdc(&server_ss, pdc_name, domain_name)) {
5650 DEBUG(0, ("Couldn't find domain controller for domain %s\n", domain_name));
5654 /* connect to ipc$ as username/password */
5655 nt_status = connect_to_ipc(&cli, &server_ss, pdc_name);
5656 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT)) {
5658 /* Is it trusting domain account for sure ? */
5659 DEBUG(0, ("Couldn't verify trusting domain account. Error was %s\n",
5660 nt_errstr(nt_status)));
5664 /* store who we connected to */
5666 saf_store( domain_name, pdc_name );
5669 * Connect to \\server\ipc$ again (this time anonymously)
5672 nt_status = connect_to_ipc_anonymous(&cli, &server_ss, (char*)pdc_name);
5674 if (NT_STATUS_IS_ERR(nt_status)) {
5675 DEBUG(0, ("Couldn't connect to domain %s controller. Error was %s.\n",
5676 domain_name, nt_errstr(nt_status)));
5681 * Use NetServerEnum2 to make sure we're talking to a proper server
5684 if (!cli_get_pdc_name(cli, domain_name, &dc_name)) {
5685 DEBUG(0, ("NetServerEnum2 error: Couldn't find primary domain controller\
5686 for domain %s\n", domain_name));
5692 if (!(mem_ctx = talloc_init("establishing trust relationship to "
5693 "domain %s", domain_name))) {
5694 DEBUG(0, ("talloc_init() failed\n"));
5700 * Call LsaOpenPolicy and LsaQueryInfo
5703 pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_LSARPC, &nt_status);
5705 DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n", nt_errstr(nt_status) ));
5707 talloc_destroy(mem_ctx);
5711 nt_status = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, True, SEC_RIGHTS_QUERY_VALUE,
5713 if (NT_STATUS_IS_ERR(nt_status)) {
5714 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
5715 nt_errstr(nt_status)));
5717 talloc_destroy(mem_ctx);
5721 /* Querying info level 5 */
5723 nt_status = rpccli_lsa_query_info_policy(pipe_hnd, mem_ctx, &connect_hnd,
5725 &domain_name_pol, &domain_sid);
5726 if (NT_STATUS_IS_ERR(nt_status)) {
5727 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
5728 nt_errstr(nt_status)));
5730 talloc_destroy(mem_ctx);
5734 /* There should be actually query info level 3 (following nt serv behaviour),
5735 but I still don't know if it's _really_ necessary */
5738 * Store the password in secrets db
5741 if (!pdb_set_trusteddom_pw(domain_name, opt_password, domain_sid)) {
5742 DEBUG(0, ("Storing password for trusted domain failed.\n"));
5744 talloc_destroy(mem_ctx);
5749 * Close the pipes and clean up
5752 nt_status = rpccli_lsa_Close(pipe_hnd, mem_ctx, &connect_hnd);
5753 if (NT_STATUS_IS_ERR(nt_status)) {
5754 DEBUG(0, ("Couldn't close LSA pipe. Error was %s\n",
5755 nt_errstr(nt_status)));
5757 talloc_destroy(mem_ctx);
5763 talloc_destroy(mem_ctx);
5765 d_printf("Trust to domain %s established\n", domain_name);
5770 * Revoke trust relationship to the remote domain
5772 * @param argc standard argc
5773 * @param argv standard argv without initial components
5775 * @return Integer status (0 means success)
5778 static int rpc_trustdom_revoke(int argc, const char **argv)
5783 if (argc < 1) return -1;
5785 /* generate upper cased domain name */
5786 domain_name = smb_xstrdup(argv[0]);
5787 strupper_m(domain_name);
5789 /* delete password of the trust */
5790 if (!pdb_del_trusteddom_pw(domain_name)) {
5791 DEBUG(0, ("Failed to revoke relationship to the trusted domain %s\n",
5798 SAFE_FREE(domain_name);
5803 * Usage for 'net rpc trustdom' command
5805 * @param argc standard argc
5806 * @param argv standard argv without inital components
5808 * @return Integer status returned to shell
5811 static int rpc_trustdom_usage(int argc, const char **argv)
5813 d_printf(" net rpc trustdom add \t\t add trusting domain's account\n");
5814 d_printf(" net rpc trustdom del \t\t delete trusting domain's account\n");
5815 d_printf(" net rpc trustdom establish \t establish relationship to trusted domain\n");
5816 d_printf(" net rpc trustdom revoke \t abandon relationship to trusted domain\n");
5817 d_printf(" net rpc trustdom list \t show current interdomain trust relationships\n");
5818 d_printf(" net rpc trustdom vampire \t vampire interdomain trust relationships from remote server\n");
5823 static NTSTATUS rpc_query_domain_sid(const DOM_SID *domain_sid,
5824 const char *domain_name,
5825 struct cli_state *cli,
5826 struct rpc_pipe_client *pipe_hnd,
5827 TALLOC_CTX *mem_ctx,
5832 sid_to_fstring(str_sid, domain_sid);
5833 d_printf("%s\n", str_sid);
5834 return NT_STATUS_OK;
5837 static void print_trusted_domain(DOM_SID *dom_sid, const char *trusted_dom_name)
5839 fstring ascii_sid, padding;
5840 int pad_len, col_len = 20;
5842 /* convert sid into ascii string */
5843 sid_to_fstring(ascii_sid, dom_sid);
5845 /* calculate padding space for d_printf to look nicer */
5846 pad_len = col_len - strlen(trusted_dom_name);
5847 padding[pad_len] = 0;
5848 do padding[--pad_len] = ' '; while (pad_len);
5850 d_printf("%s%s%s\n", trusted_dom_name, padding, ascii_sid);
5853 static NTSTATUS vampire_trusted_domain(struct rpc_pipe_client *pipe_hnd,
5854 TALLOC_CTX *mem_ctx,
5857 const char *trusted_dom_name)
5860 union lsa_TrustedDomainInfo info;
5861 char *cleartextpwd = NULL;
5864 nt_status = rpccli_lsa_QueryTrustedDomainInfoBySid(pipe_hnd, mem_ctx,
5867 LSA_TRUSTED_DOMAIN_INFO_PASSWORD,
5869 if (NT_STATUS_IS_ERR(nt_status)) {
5870 DEBUG(0,("Could not query trusted domain info. Error was %s\n",
5871 nt_errstr(nt_status)));
5875 data = data_blob(NULL, info.password.password->length);
5878 info.password.password->data,
5879 info.password.password->length);
5880 data.length = info.password.password->length;
5882 cleartextpwd = decrypt_trustdom_secret(pipe_hnd->cli->pwd.password,
5885 if (cleartextpwd == NULL) {
5886 DEBUG(0,("retrieved NULL password\n"));
5887 nt_status = NT_STATUS_UNSUCCESSFUL;
5891 if (!pdb_set_trusteddom_pw(trusted_dom_name, cleartextpwd, &dom_sid)) {
5892 DEBUG(0, ("Storing password for trusted domain failed.\n"));
5893 nt_status = NT_STATUS_UNSUCCESSFUL;
5897 #ifdef DEBUG_PASSWORD
5898 DEBUG(100,("sucessfully vampired trusted domain [%s], sid: [%s], "
5899 "password: [%s]\n", trusted_dom_name,
5900 sid_string_dbg(&dom_sid), cleartextpwd));
5904 SAFE_FREE(cleartextpwd);
5905 data_blob_free(&data);
5910 static int rpc_trustdom_vampire(int argc, const char **argv)
5912 /* common variables */
5913 TALLOC_CTX* mem_ctx;
5914 struct cli_state *cli = NULL;
5915 struct rpc_pipe_client *pipe_hnd = NULL;
5917 const char *domain_name = NULL;
5918 DOM_SID *queried_dom_sid;
5919 POLICY_HND connect_hnd;
5921 /* trusted domains listing variables */
5922 unsigned int num_domains, enum_ctx = 0;
5924 DOM_SID *domain_sids;
5925 char **trusted_dom_names;
5930 * Listing trusted domains (stored in secrets.tdb, if local)
5933 mem_ctx = talloc_init("trust relationships vampire");
5936 * set domain and pdc name to local samba server (default)
5937 * or to remote one given in command line
5940 if (StrCaseCmp(opt_workgroup, lp_workgroup())) {
5941 domain_name = opt_workgroup;
5942 opt_target_workgroup = opt_workgroup;
5944 fstrcpy(pdc_name, global_myname());
5945 domain_name = talloc_strdup(mem_ctx, lp_workgroup());
5946 opt_target_workgroup = domain_name;
5949 /* open \PIPE\lsarpc and open policy handle */
5950 nt_status = net_make_ipc_connection(NET_FLAGS_PDC, &cli);
5951 if (!NT_STATUS_IS_OK(nt_status)) {
5952 DEBUG(0, ("Couldn't connect to domain controller: %s\n",
5953 nt_errstr(nt_status)));
5954 talloc_destroy(mem_ctx);
5958 pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_LSARPC, &nt_status);
5960 DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n",
5961 nt_errstr(nt_status) ));
5963 talloc_destroy(mem_ctx);
5967 nt_status = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, False, SEC_RIGHTS_QUERY_VALUE,
5969 if (NT_STATUS_IS_ERR(nt_status)) {
5970 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
5971 nt_errstr(nt_status)));
5973 talloc_destroy(mem_ctx);
5977 /* query info level 5 to obtain sid of a domain being queried */
5978 nt_status = rpccli_lsa_query_info_policy(
5979 pipe_hnd, mem_ctx, &connect_hnd, 5 /* info level */,
5980 &dummy, &queried_dom_sid);
5982 if (NT_STATUS_IS_ERR(nt_status)) {
5983 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
5984 nt_errstr(nt_status)));
5986 talloc_destroy(mem_ctx);
5991 * Keep calling LsaEnumTrustdom over opened pipe until
5992 * the end of enumeration is reached
5995 d_printf("Vampire trusted domains:\n\n");
5998 nt_status = rpccli_lsa_enum_trust_dom(pipe_hnd, mem_ctx, &connect_hnd, &enum_ctx,
6000 &trusted_dom_names, &domain_sids);
6002 if (NT_STATUS_IS_ERR(nt_status)) {
6003 DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
6004 nt_errstr(nt_status)));
6006 talloc_destroy(mem_ctx);
6010 for (i = 0; i < num_domains; i++) {
6012 print_trusted_domain(&(domain_sids[i]), trusted_dom_names[i]);
6014 nt_status = vampire_trusted_domain(pipe_hnd, mem_ctx, &connect_hnd,
6015 domain_sids[i], trusted_dom_names[i]);
6016 if (!NT_STATUS_IS_OK(nt_status)) {
6018 talloc_destroy(mem_ctx);
6024 * in case of no trusted domains say something rather
6025 * than just display blank line
6027 if (!num_domains) d_printf("none\n");
6029 } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
6031 /* close this connection before doing next one */
6032 nt_status = rpccli_lsa_Close(pipe_hnd, mem_ctx, &connect_hnd);
6033 if (NT_STATUS_IS_ERR(nt_status)) {
6034 DEBUG(0, ("Couldn't properly close lsa policy handle. Error was %s\n",
6035 nt_errstr(nt_status)));
6037 talloc_destroy(mem_ctx);
6041 /* close lsarpc pipe and connection to IPC$ */
6044 talloc_destroy(mem_ctx);
6048 static int rpc_trustdom_list(int argc, const char **argv)
6050 /* common variables */
6051 TALLOC_CTX* mem_ctx;
6052 struct cli_state *cli = NULL, *remote_cli = NULL;
6053 struct rpc_pipe_client *pipe_hnd = NULL;
6055 const char *domain_name = NULL;
6056 DOM_SID *queried_dom_sid;
6058 int ascii_dom_name_len;
6059 POLICY_HND connect_hnd;
6061 /* trusted domains listing variables */
6062 unsigned int num_domains, enum_ctx = 0;
6063 int i, pad_len, col_len = 20;
6064 DOM_SID *domain_sids;
6065 char **trusted_dom_names;
6069 /* trusting domains listing variables */
6070 POLICY_HND domain_hnd;
6071 char **trusting_dom_names;
6072 uint32 *trusting_dom_rids;
6075 * Listing trusted domains (stored in secrets.tdb, if local)
6078 mem_ctx = talloc_init("trust relationships listing");
6081 * set domain and pdc name to local samba server (default)
6082 * or to remote one given in command line
6085 if (StrCaseCmp(opt_workgroup, lp_workgroup())) {
6086 domain_name = opt_workgroup;
6087 opt_target_workgroup = opt_workgroup;
6089 fstrcpy(pdc_name, global_myname());
6090 domain_name = talloc_strdup(mem_ctx, lp_workgroup());
6091 opt_target_workgroup = domain_name;
6094 /* open \PIPE\lsarpc and open policy handle */
6095 nt_status = net_make_ipc_connection(NET_FLAGS_PDC, &cli);
6096 if (!NT_STATUS_IS_OK(nt_status)) {
6097 DEBUG(0, ("Couldn't connect to domain controller: %s\n",
6098 nt_errstr(nt_status)));
6099 talloc_destroy(mem_ctx);
6103 pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_LSARPC, &nt_status);
6105 DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n",
6106 nt_errstr(nt_status) ));
6108 talloc_destroy(mem_ctx);
6112 nt_status = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, False, SEC_RIGHTS_QUERY_VALUE,
6114 if (NT_STATUS_IS_ERR(nt_status)) {
6115 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
6116 nt_errstr(nt_status)));
6118 talloc_destroy(mem_ctx);
6122 /* query info level 5 to obtain sid of a domain being queried */
6123 nt_status = rpccli_lsa_query_info_policy(
6124 pipe_hnd, mem_ctx, &connect_hnd, 5 /* info level */,
6125 &dummy, &queried_dom_sid);
6127 if (NT_STATUS_IS_ERR(nt_status)) {
6128 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
6129 nt_errstr(nt_status)));
6131 talloc_destroy(mem_ctx);
6136 * Keep calling LsaEnumTrustdom over opened pipe until
6137 * the end of enumeration is reached
6140 d_printf("Trusted domains list:\n\n");
6143 nt_status = rpccli_lsa_enum_trust_dom(pipe_hnd, mem_ctx, &connect_hnd, &enum_ctx,
6145 &trusted_dom_names, &domain_sids);
6147 if (NT_STATUS_IS_ERR(nt_status)) {
6148 DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
6149 nt_errstr(nt_status)));
6151 talloc_destroy(mem_ctx);
6155 for (i = 0; i < num_domains; i++) {
6156 print_trusted_domain(&(domain_sids[i]), trusted_dom_names[i]);
6160 * in case of no trusted domains say something rather
6161 * than just display blank line
6163 if (!num_domains) d_printf("none\n");
6165 } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
6167 /* close this connection before doing next one */
6168 nt_status = rpccli_lsa_Close(pipe_hnd, mem_ctx, &connect_hnd);
6169 if (NT_STATUS_IS_ERR(nt_status)) {
6170 DEBUG(0, ("Couldn't properly close lsa policy handle. Error was %s\n",
6171 nt_errstr(nt_status)));
6173 talloc_destroy(mem_ctx);
6177 cli_rpc_pipe_close(pipe_hnd);
6180 * Listing trusting domains (stored in passdb backend, if local)
6183 d_printf("\nTrusting domains list:\n\n");
6186 * Open \PIPE\samr and get needed policy handles
6188 pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SAMR, &nt_status);
6190 DEBUG(0, ("Could not initialise samr pipe. Error was %s\n", nt_errstr(nt_status)));
6192 talloc_destroy(mem_ctx);
6197 nt_status = rpccli_samr_connect(pipe_hnd, mem_ctx, SA_RIGHT_SAM_OPEN_DOMAIN,
6199 if (!NT_STATUS_IS_OK(nt_status)) {
6200 DEBUG(0, ("Couldn't open SAMR policy handle. Error was %s\n",
6201 nt_errstr(nt_status)));
6203 talloc_destroy(mem_ctx);
6207 /* SamrOpenDomain - we have to open domain policy handle in order to be
6208 able to enumerate accounts*/
6209 nt_status = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_hnd,
6210 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
6211 queried_dom_sid, &domain_hnd);
6212 if (!NT_STATUS_IS_OK(nt_status)) {
6213 DEBUG(0, ("Couldn't open domain object. Error was %s\n",
6214 nt_errstr(nt_status)));
6216 talloc_destroy(mem_ctx);
6221 * perform actual enumeration
6224 enum_ctx = 0; /* reset enumeration context from last enumeration */
6227 nt_status = rpccli_samr_enum_dom_users(pipe_hnd, mem_ctx, &domain_hnd,
6228 &enum_ctx, ACB_DOMTRUST, 0xffff,
6229 &trusting_dom_names, &trusting_dom_rids,
6231 if (NT_STATUS_IS_ERR(nt_status)) {
6232 DEBUG(0, ("Couldn't enumerate accounts. Error was: %s\n",
6233 nt_errstr(nt_status)));
6235 talloc_destroy(mem_ctx);
6239 for (i = 0; i < num_domains; i++) {
6242 * get each single domain's sid (do we _really_ need this ?):
6243 * 1) connect to domain's pdc
6244 * 2) query the pdc for domain's sid
6247 /* get rid of '$' tail */
6248 ascii_dom_name_len = strlen(trusting_dom_names[i]);
6249 if (ascii_dom_name_len && ascii_dom_name_len < FSTRING_LEN)
6250 trusting_dom_names[i][ascii_dom_name_len - 1] = '\0';
6252 /* calculate padding space for d_printf to look nicer */
6253 pad_len = col_len - strlen(trusting_dom_names[i]);
6254 padding[pad_len] = 0;
6255 do padding[--pad_len] = ' '; while (pad_len);
6257 /* set opt_* variables to remote domain */
6258 strupper_m(trusting_dom_names[i]);
6259 opt_workgroup = talloc_strdup(mem_ctx, trusting_dom_names[i]);
6260 opt_target_workgroup = opt_workgroup;
6262 d_printf("%s%s", trusting_dom_names[i], padding);
6264 /* connect to remote domain controller */
6265 nt_status = net_make_ipc_connection(
6266 NET_FLAGS_PDC | NET_FLAGS_ANONYMOUS,
6268 if (NT_STATUS_IS_OK(nt_status)) {
6269 /* query for domain's sid */
6270 if (run_rpc_command(remote_cli, PI_LSARPC, 0, rpc_query_domain_sid, argc, argv))
6271 d_fprintf(stderr, "couldn't get domain's sid\n");
6273 cli_shutdown(remote_cli);
6276 d_fprintf(stderr, "domain controller is not "
6278 nt_errstr(nt_status));
6282 if (!num_domains) d_printf("none\n");
6284 } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
6286 /* close opened samr and domain policy handles */
6287 nt_status = rpccli_samr_close(pipe_hnd, mem_ctx, &domain_hnd);
6288 if (!NT_STATUS_IS_OK(nt_status)) {
6289 DEBUG(0, ("Couldn't properly close domain policy handle for domain %s\n", domain_name));
6292 nt_status = rpccli_samr_close(pipe_hnd, mem_ctx, &connect_hnd);
6293 if (!NT_STATUS_IS_OK(nt_status)) {
6294 DEBUG(0, ("Couldn't properly close samr policy handle for domain %s\n", domain_name));
6297 /* close samr pipe and connection to IPC$ */
6300 talloc_destroy(mem_ctx);
6305 * Entrypoint for 'net rpc trustdom' code
6307 * @param argc standard argc
6308 * @param argv standard argv without initial components
6310 * @return Integer status (0 means success)
6313 static int rpc_trustdom(int argc, const char **argv)
6315 struct functable func[] = {
6316 {"add", rpc_trustdom_add},
6317 {"del", rpc_trustdom_del},
6318 {"establish", rpc_trustdom_establish},
6319 {"revoke", rpc_trustdom_revoke},
6320 {"help", rpc_trustdom_usage},
6321 {"list", rpc_trustdom_list},
6322 {"vampire", rpc_trustdom_vampire},
6327 rpc_trustdom_usage(argc, argv);
6331 return (net_run_function(argc, argv, func, rpc_user_usage));
6335 * Check if a server will take rpc commands
6336 * @param flags Type of server to connect to (PDC, DMB, localhost)
6337 * if the host is not explicitly specified
6338 * @return bool (true means rpc supported)
6340 bool net_rpc_check(unsigned flags)
6342 struct cli_state *cli;
6344 struct sockaddr_storage server_ss;
6345 char *server_name = NULL;
6348 /* flags (i.e. server type) may depend on command */
6349 if (!net_find_server(NULL, flags, &server_ss, &server_name))
6352 if ((cli = cli_initialise()) == NULL) {
6356 status = cli_connect(cli, server_name, &server_ss);
6357 if (!NT_STATUS_IS_OK(status))
6359 if (!attempt_netbios_session_request(&cli, global_myname(),
6360 server_name, &server_ss))
6362 if (!cli_negprot(cli))
6364 if (cli->protocol < PROTOCOL_NT1)
6373 /* dump sam database via samsync rpc calls */
6374 static int rpc_samdump(int argc, const char **argv) {
6375 return run_rpc_command(NULL, PI_NETLOGON, NET_FLAGS_ANONYMOUS, rpc_samdump_internals,
6379 /* syncronise sam database via samsync rpc calls */
6380 static int rpc_vampire(int argc, const char **argv) {
6381 return run_rpc_command(NULL, PI_NETLOGON, NET_FLAGS_ANONYMOUS, rpc_vampire_internals,
6386 * Migrate everything from a print-server
6388 * @param argc Standard main() style argc
6389 * @param argv Standard main() style argv. Initial components are already
6392 * @return A shell status integer (0 for success)
6394 * The order is important !
6395 * To successfully add drivers the print-queues have to exist !
6396 * Applying ACLs should be the last step, because you're easily locked out
6399 static int rpc_printer_migrate_all(int argc, const char **argv)
6404 printf("no server to migrate\n");
6408 ret = run_rpc_command(NULL, PI_SPOOLSS, 0, rpc_printer_migrate_printers_internals, argc, argv);
6412 ret = run_rpc_command(NULL, PI_SPOOLSS, 0, rpc_printer_migrate_drivers_internals, argc, argv);
6416 ret = run_rpc_command(NULL, PI_SPOOLSS, 0, rpc_printer_migrate_forms_internals, argc, argv);
6420 ret = run_rpc_command(NULL, PI_SPOOLSS, 0, rpc_printer_migrate_settings_internals, argc, argv);
6424 return run_rpc_command(NULL, PI_SPOOLSS, 0, rpc_printer_migrate_security_internals, argc, argv);
6429 * Migrate print-drivers from a print-server
6431 * @param argc Standard main() style argc
6432 * @param argv Standard main() style argv. Initial components are already
6435 * @return A shell status integer (0 for success)
6437 static int rpc_printer_migrate_drivers(int argc, const char **argv)
6440 printf("no server to migrate\n");
6444 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6445 rpc_printer_migrate_drivers_internals,
6450 * Migrate print-forms from a print-server
6452 * @param argc Standard main() style argc
6453 * @param argv Standard main() style argv. Initial components are already
6456 * @return A shell status integer (0 for success)
6458 static int rpc_printer_migrate_forms(int argc, const char **argv)
6461 printf("no server to migrate\n");
6465 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6466 rpc_printer_migrate_forms_internals,
6471 * Migrate printers from a print-server
6473 * @param argc Standard main() style argc
6474 * @param argv Standard main() style argv. Initial components are already
6477 * @return A shell status integer (0 for success)
6479 static int rpc_printer_migrate_printers(int argc, const char **argv)
6482 printf("no server to migrate\n");
6486 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6487 rpc_printer_migrate_printers_internals,
6492 * Migrate printer-ACLs from a print-server
6494 * @param argc Standard main() style argc
6495 * @param argv Standard main() style argv. Initial components are already
6498 * @return A shell status integer (0 for success)
6500 static int rpc_printer_migrate_security(int argc, const char **argv)
6503 printf("no server to migrate\n");
6507 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6508 rpc_printer_migrate_security_internals,
6513 * Migrate printer-settings from a print-server
6515 * @param argc Standard main() style argc
6516 * @param argv Standard main() style argv. Initial components are already
6519 * @return A shell status integer (0 for success)
6521 static int rpc_printer_migrate_settings(int argc, const char **argv)
6524 printf("no server to migrate\n");
6528 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6529 rpc_printer_migrate_settings_internals,
6534 * 'net rpc printer' entrypoint.
6535 * @param argc Standard main() style argc
6536 * @param argv Standard main() style argv. Initial components are already
6540 int rpc_printer_migrate(int argc, const char **argv)
6543 /* ouch: when addriver and setdriver are called from within
6544 rpc_printer_migrate_drivers_internals, the printer-queue already
6547 struct functable func[] = {
6548 {"all", rpc_printer_migrate_all},
6549 {"drivers", rpc_printer_migrate_drivers},
6550 {"forms", rpc_printer_migrate_forms},
6551 {"help", rpc_printer_usage},
6552 {"printers", rpc_printer_migrate_printers},
6553 {"security", rpc_printer_migrate_security},
6554 {"settings", rpc_printer_migrate_settings},
6558 return net_run_function(argc, argv, func, rpc_printer_usage);
6563 * List printers on a remote RPC server
6565 * @param argc Standard main() style argc
6566 * @param argv Standard main() style argv. Initial components are already
6569 * @return A shell status integer (0 for success)
6571 static int rpc_printer_list(int argc, const char **argv)
6574 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6575 rpc_printer_list_internals,
6580 * List printer-drivers on a remote RPC server
6582 * @param argc Standard main() style argc
6583 * @param argv Standard main() style argv. Initial components are already
6586 * @return A shell status integer (0 for success)
6588 static int rpc_printer_driver_list(int argc, const char **argv)
6591 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6592 rpc_printer_driver_list_internals,
6597 * Publish printer in ADS via MSRPC
6599 * @param argc Standard main() style argc
6600 * @param argv Standard main() style argv. Initial components are already
6603 * @return A shell status integer (0 for success)
6605 static int rpc_printer_publish_publish(int argc, const char **argv)
6608 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6609 rpc_printer_publish_publish_internals,
6614 * Update printer in ADS via MSRPC
6616 * @param argc Standard main() style argc
6617 * @param argv Standard main() style argv. Initial components are already
6620 * @return A shell status integer (0 for success)
6622 static int rpc_printer_publish_update(int argc, const char **argv)
6625 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6626 rpc_printer_publish_update_internals,
6631 * UnPublish printer in ADS via MSRPC
6633 * @param argc Standard main() style argc
6634 * @param argv Standard main() style argv. Initial components are already
6637 * @return A shell status integer (0 for success)
6639 static int rpc_printer_publish_unpublish(int argc, const char **argv)
6642 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6643 rpc_printer_publish_unpublish_internals,
6648 * List published printers via MSRPC
6650 * @param argc Standard main() style argc
6651 * @param argv Standard main() style argv. Initial components are already
6654 * @return A shell status integer (0 for success)
6656 static int rpc_printer_publish_list(int argc, const char **argv)
6659 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6660 rpc_printer_publish_list_internals,
6666 * Publish printer in ADS
6668 * @param argc Standard main() style argc
6669 * @param argv Standard main() style argv. Initial components are already
6672 * @return A shell status integer (0 for success)
6674 static int rpc_printer_publish(int argc, const char **argv)
6677 struct functable func[] = {
6678 {"publish", rpc_printer_publish_publish},
6679 {"update", rpc_printer_publish_update},
6680 {"unpublish", rpc_printer_publish_unpublish},
6681 {"list", rpc_printer_publish_list},
6682 {"help", rpc_printer_usage},
6687 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6688 rpc_printer_publish_list_internals,
6691 return net_run_function(argc, argv, func, rpc_printer_usage);
6697 * Display rpc printer help page.
6698 * @param argc Standard main() style argc
6699 * @param argv Standard main() style argv. Initial components are already
6702 int rpc_printer_usage(int argc, const char **argv)
6704 return net_help_printer(argc, argv);
6708 * 'net rpc printer' entrypoint.
6709 * @param argc Standard main() style argc
6710 * @param argv Standard main() style argv. Initial components are already
6713 int net_rpc_printer(int argc, const char **argv)
6715 struct functable func[] = {
6716 {"list", rpc_printer_list},
6717 {"migrate", rpc_printer_migrate},
6718 {"driver", rpc_printer_driver_list},
6719 {"publish", rpc_printer_publish},
6724 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6725 rpc_printer_list_internals,
6728 return net_run_function(argc, argv, func, rpc_printer_usage);
6731 /****************************************************************************/
6735 * Basic usage function for 'net rpc'
6736 * @param argc Standard main() style argc
6737 * @param argv Standard main() style argv. Initial components are already
6741 int net_rpc_usage(int argc, const char **argv)
6743 d_printf(" net rpc info \t\t\tshow basic info about a domain \n");
6744 d_printf(" net rpc join \t\t\tto join a domain \n");
6745 d_printf(" net rpc oldjoin \t\tto join a domain created in server manager\n");
6746 d_printf(" net rpc testjoin \t\ttests that a join is valid\n");
6747 d_printf(" net rpc user \t\t\tto add, delete and list users\n");
6748 d_printf(" net rpc password <username> [<password>] -Uadmin_username%%admin_pass\n");
6749 d_printf(" net rpc group \t\tto list groups\n");
6750 d_printf(" net rpc share \t\tto add, delete, list and migrate shares\n");
6751 d_printf(" net rpc printer \t\tto list and migrate printers\n");
6752 d_printf(" net rpc file \t\t\tto list open files\n");
6753 d_printf(" net rpc changetrustpw \tto change the trust account password\n");
6754 d_printf(" net rpc getsid \t\tfetch the domain sid into the local secrets.tdb\n");
6755 d_printf(" net rpc vampire \t\tsyncronise an NT PDC's users and groups into the local passdb\n");
6756 d_printf(" net rpc samdump \t\tdisplay an NT PDC's users, groups and other data\n");
6757 d_printf(" net rpc trustdom \t\tto create trusting domain's account or establish trust\n");
6758 d_printf(" net rpc abortshutdown \tto abort the shutdown of a remote server\n");
6759 d_printf(" net rpc shutdown \t\tto shutdown a remote server\n");
6760 d_printf(" net rpc rights\t\tto manage privileges assigned to SIDs\n");
6761 d_printf(" net rpc registry\t\tto manage registry hives\n");
6762 d_printf(" net rpc service\t\tto start, stop and query services\n");
6763 d_printf(" net rpc audit\t\t\tto modify global auditing settings\n");
6764 d_printf(" net rpc shell\t\t\tto open an interactive shell for remote server/account management\n");
6766 d_printf("'net rpc shutdown' also accepts the following miscellaneous options:\n"); /* misc options */
6767 d_printf("\t-r or --reboot\trequest remote server reboot on shutdown\n");
6768 d_printf("\t-f or --force\trequest the remote server force its shutdown\n");
6769 d_printf("\t-t or --timeout=<timeout>\tnumber of seconds before shutdown\n");
6770 d_printf("\t-C or --comment=<message>\ttext message to display on impending shutdown\n");
6776 * Help function for 'net rpc'. Calls command specific help if requested
6777 * or displays usage of net rpc
6778 * @param argc Standard main() style argc
6779 * @param argv Standard main() style argv. Initial components are already
6783 int net_rpc_help(int argc, const char **argv)
6785 struct functable func[] = {
6786 {"join", rpc_join_usage},
6787 {"user", rpc_user_usage},
6788 {"group", rpc_group_usage},
6789 {"share", rpc_share_usage},
6790 /*{"changetrustpw", rpc_changetrustpw_usage}, */
6791 {"trustdom", rpc_trustdom_usage},
6792 /*{"abortshutdown", rpc_shutdown_abort_usage},*/
6793 /*{"shutdown", rpc_shutdown_usage}, */
6794 {"vampire", rpc_vampire_usage},
6799 net_rpc_usage(argc, argv);
6803 return (net_run_function(argc, argv, func, rpc_user_usage));
6807 * 'net rpc' entrypoint.
6808 * @param argc Standard main() style argc
6809 * @param argv Standard main() style argv. Initial components are already
6813 int net_rpc(int argc, const char **argv)
6815 struct functable func[] = {
6816 {"audit", net_rpc_audit},
6817 {"info", net_rpc_info},
6818 {"join", net_rpc_join},
6819 {"oldjoin", net_rpc_oldjoin},
6820 {"testjoin", net_rpc_testjoin},
6821 {"user", net_rpc_user},
6822 {"password", rpc_user_password},
6823 {"group", net_rpc_group},
6824 {"share", net_rpc_share},
6825 {"file", net_rpc_file},
6826 {"printer", net_rpc_printer},
6827 {"changetrustpw", net_rpc_changetrustpw},
6828 {"trustdom", rpc_trustdom},
6829 {"abortshutdown", rpc_shutdown_abort},
6830 {"shutdown", rpc_shutdown},
6831 {"samdump", rpc_samdump},
6832 {"vampire", rpc_vampire},
6833 {"getsid", net_rpc_getsid},
6834 {"rights", net_rpc_rights},
6835 {"service", net_rpc_service},
6836 {"registry", net_rpc_registry},
6837 {"shell", net_rpc_shell},
6838 {"help", net_rpc_help},
6841 return net_run_function(argc, argv, func, net_rpc_usage);