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 = SEC_GENERIC_READ | SEC_GENERIC_WRITE | SEC_GENERIC_EXECUTE |
622 SEC_STD_WRITE_DAC | SEC_STD_DELETE |
623 SAMR_USER_ACCESS_SET_PASSWORD |
624 SAMR_USER_ACCESS_GET_ATTRIBUTES |
625 SAMR_USER_ACCESS_SET_ATTRIBUTES;
627 result = rpccli_samr_create_dom_user(pipe_hnd, mem_ctx, &domain_pol,
628 acct_name, acb_info, acct_flags,
629 &user_pol, &user_rid);
630 if (!NT_STATUS_IS_OK(result)) {
636 uint32 *user_rids, num_rids, *name_types;
637 uint32 flags = 0x000003e8; /* Unknown */
638 SAM_USERINFO_CTR ctr;
639 SAM_USER_INFO_24 p24;
642 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol,
643 flags, 1, &acct_name,
644 &num_rids, &user_rids,
647 if (!NT_STATUS_IS_OK(result)) {
651 result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
652 MAXIMUM_ALLOWED_ACCESS,
653 user_rids[0], &user_pol);
655 if (!NT_STATUS_IS_OK(result)) {
659 /* Set password on account */
664 encode_pw_buffer(pwbuf, argv[1], STR_UNICODE);
666 init_sam_user_info24(&p24, (char *)pwbuf,24);
668 ctr.switch_value = 24;
669 ctr.info.id24 = &p24;
671 result = rpccli_samr_set_userinfo(pipe_hnd, mem_ctx, &user_pol, 24,
672 &cli->user_session_key, &ctr);
674 if (!NT_STATUS_IS_OK(result)) {
675 d_fprintf(stderr, "Failed to set password for user %s - %s\n",
676 acct_name, nt_errstr(result));
678 result = rpccli_samr_delete_dom_user(pipe_hnd, mem_ctx, &user_pol);
680 if (!NT_STATUS_IS_OK(result)) {
681 d_fprintf(stderr, "Failed to delete user %s - %s\n",
682 acct_name, nt_errstr(result));
689 if (!NT_STATUS_IS_OK(result)) {
690 d_fprintf(stderr, "Failed to add user '%s' with %s.\n",
691 acct_name, nt_errstr(result));
693 d_printf("Added user '%s'.\n", acct_name);
699 * Add a new user to a remote RPC server
701 * @param argc Standard main() style argc
702 * @param argv Standard main() style argv. Initial components are already
705 * @return A shell status integer (0 for success)
708 static int rpc_user_add(int argc, const char **argv)
710 return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_add_internals,
715 * Delete a user from a remote RPC server
717 * All parameters are provided by the run_rpc_command function, except for
718 * argc, argv which are passes through.
720 * @param domain_sid The domain sid acquired from the remote server
721 * @param cli A cli_state connected to the server.
722 * @param mem_ctx Talloc context, destoyed on completion of the function.
723 * @param argc Standard main() style argc
724 * @param argv Standard main() style argv. Initial components are already
727 * @return Normal NTSTATUS return.
730 static NTSTATUS rpc_user_del_internals(const DOM_SID *domain_sid,
731 const char *domain_name,
732 struct cli_state *cli,
733 struct rpc_pipe_client *pipe_hnd,
738 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
739 POLICY_HND connect_pol, domain_pol, user_pol;
740 const char *acct_name;
743 d_printf("User must be specified\n");
744 rpc_user_usage(argc, argv);
750 /* Get sam policy and domain handles */
752 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
755 if (!NT_STATUS_IS_OK(result)) {
759 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
760 MAXIMUM_ALLOWED_ACCESS,
761 domain_sid, &domain_pol);
763 if (!NT_STATUS_IS_OK(result)) {
767 /* Get handle on user */
770 uint32 *user_rids, num_rids, *name_types;
771 uint32 flags = 0x000003e8; /* Unknown */
773 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol,
774 flags, 1, &acct_name,
775 &num_rids, &user_rids,
778 if (!NT_STATUS_IS_OK(result)) {
782 result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
783 MAXIMUM_ALLOWED_ACCESS,
784 user_rids[0], &user_pol);
786 if (!NT_STATUS_IS_OK(result)) {
793 result = rpccli_samr_delete_dom_user(pipe_hnd, mem_ctx, &user_pol);
795 if (!NT_STATUS_IS_OK(result)) {
800 if (!NT_STATUS_IS_OK(result)) {
801 d_fprintf(stderr, "Failed to delete user '%s' with %s.\n",
802 acct_name, nt_errstr(result));
804 d_printf("Deleted user '%s'.\n", acct_name);
811 * Rename a user on a remote RPC server
813 * All parameters are provided by the run_rpc_command function, except for
814 * argc, argv which are passes through.
816 * @param domain_sid The domain sid acquired from the remote server
817 * @param cli A cli_state connected to the server.
818 * @param mem_ctx Talloc context, destoyed on completion of the function.
819 * @param argc Standard main() style argc
820 * @param argv Standard main() style argv. Initial components are already
823 * @return Normal NTSTATUS return.
826 static NTSTATUS rpc_user_rename_internals(const DOM_SID *domain_sid,
827 const char *domain_name,
828 struct cli_state *cli,
829 struct rpc_pipe_client *pipe_hnd,
834 POLICY_HND connect_pol, domain_pol, user_pol;
835 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
836 uint32 info_level = 7;
837 const char *old_name, *new_name;
839 uint32 flags = 0x000003e8; /* Unknown */
840 uint32 num_rids, *name_types;
841 uint32 num_names = 1;
843 SAM_USERINFO_CTR *user_ctr;
844 SAM_USERINFO_CTR ctr;
845 SAM_USER_INFO_7 info7;
848 d_printf("Old and new username must be specified\n");
849 rpc_user_usage(argc, argv);
857 ZERO_STRUCT(user_ctr);
859 /* Get sam policy handle */
861 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
863 if (!NT_STATUS_IS_OK(result)) {
867 /* Get domain policy handle */
869 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
870 MAXIMUM_ALLOWED_ACCESS,
871 domain_sid, &domain_pol);
872 if (!NT_STATUS_IS_OK(result)) {
876 if ((names = TALLOC_ARRAY(mem_ctx, const char *, num_names)) == NULL) {
877 result = NT_STATUS_NO_MEMORY;
881 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol,
882 flags, num_names, names,
883 &num_rids, &user_rid, &name_types);
884 if (!NT_STATUS_IS_OK(result)) {
888 /* Open domain user */
889 result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
890 MAXIMUM_ALLOWED_ACCESS, user_rid[0], &user_pol);
892 if (!NT_STATUS_IS_OK(result)) {
896 /* Query user info */
897 result = rpccli_samr_query_userinfo(pipe_hnd, mem_ctx, &user_pol,
898 info_level, &user_ctr);
900 if (!NT_STATUS_IS_OK(result)) {
904 ctr.switch_value = info_level;
905 ctr.info.id7 = &info7;
907 init_sam_user_info7(&info7, new_name);
910 result = rpccli_samr_set_userinfo(pipe_hnd, mem_ctx, &user_pol,
911 info_level, &cli->user_session_key, &ctr);
913 if (!NT_STATUS_IS_OK(result)) {
918 if (!NT_STATUS_IS_OK(result)) {
919 d_fprintf(stderr, "Failed to rename user from %s to %s - %s\n", old_name, new_name,
922 d_printf("Renamed user from %s to %s\n", old_name, new_name);
928 * Rename a user on a remote RPC server
930 * @param argc Standard main() style argc
931 * @param argv Standard main() style argv. Initial components are already
934 * @return A shell status integer (0 for success)
937 static int rpc_user_rename(int argc, const char **argv)
939 return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_rename_internals,
944 * Delete a user from a remote RPC server
946 * @param argc Standard main() style argc
947 * @param argv Standard main() style argv. Initial components are already
950 * @return A shell status integer (0 for success)
953 static int rpc_user_delete(int argc, const char **argv)
955 return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_del_internals,
960 * Set a password for a user on a remote RPC server
962 * All parameters are provided by the run_rpc_command function, except for
963 * argc, argv which are passes through.
965 * @param domain_sid The domain sid acquired from the remote server
966 * @param cli A cli_state connected to the server.
967 * @param mem_ctx Talloc context, destoyed on completion of the function.
968 * @param argc Standard main() style argc
969 * @param argv Standard main() style argv. Initial components are already
972 * @return Normal NTSTATUS return.
975 static NTSTATUS rpc_user_password_internals(const DOM_SID *domain_sid,
976 const char *domain_name,
977 struct cli_state *cli,
978 struct rpc_pipe_client *pipe_hnd,
983 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
984 POLICY_HND connect_pol, domain_pol, user_pol;
985 SAM_USERINFO_CTR ctr;
986 SAM_USER_INFO_24 p24;
989 const char *new_password;
993 d_printf("User must be specified\n");
994 rpc_user_usage(argc, argv);
1001 new_password = argv[1];
1003 asprintf(&prompt, "Enter new password for %s:", user);
1004 new_password = getpass(prompt);
1008 /* Get sam policy and domain handles */
1010 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1013 if (!NT_STATUS_IS_OK(result)) {
1017 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
1018 MAXIMUM_ALLOWED_ACCESS,
1019 domain_sid, &domain_pol);
1021 if (!NT_STATUS_IS_OK(result)) {
1025 /* Get handle on user */
1028 uint32 *user_rids, num_rids, *name_types;
1029 uint32 flags = 0x000003e8; /* Unknown */
1031 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol,
1033 &num_rids, &user_rids,
1036 if (!NT_STATUS_IS_OK(result)) {
1040 result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
1041 MAXIMUM_ALLOWED_ACCESS,
1042 user_rids[0], &user_pol);
1044 if (!NT_STATUS_IS_OK(result)) {
1049 /* Set password on account */
1054 encode_pw_buffer(pwbuf, new_password, STR_UNICODE);
1056 init_sam_user_info24(&p24, (char *)pwbuf,24);
1058 ctr.switch_value = 24;
1059 ctr.info.id24 = &p24;
1061 result = rpccli_samr_set_userinfo(pipe_hnd, mem_ctx, &user_pol, 24,
1062 &cli->user_session_key, &ctr);
1064 if (!NT_STATUS_IS_OK(result)) {
1068 /* Display results */
1076 * Set a user's password on a remote RPC server
1078 * @param argc Standard main() style argc
1079 * @param argv Standard main() style argv. Initial components are already
1082 * @return A shell status integer (0 for success)
1085 static int rpc_user_password(int argc, const char **argv)
1087 return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_password_internals,
1092 * List user's groups on a remote RPC server
1094 * All parameters are provided by the run_rpc_command function, except for
1095 * argc, argv which are passes through.
1097 * @param domain_sid The domain sid acquired from the remote server
1098 * @param cli A cli_state connected to the server.
1099 * @param mem_ctx Talloc context, destoyed on completion of the function.
1100 * @param argc Standard main() style argc
1101 * @param argv Standard main() style argv. Initial components are already
1104 * @return Normal NTSTATUS return.
1107 static NTSTATUS rpc_user_info_internals(const DOM_SID *domain_sid,
1108 const char *domain_name,
1109 struct cli_state *cli,
1110 struct rpc_pipe_client *pipe_hnd,
1111 TALLOC_CTX *mem_ctx,
1115 POLICY_HND connect_pol, domain_pol, user_pol;
1116 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1117 uint32 *rids, num_rids, *name_types, num_names;
1118 uint32 flags = 0x000003e8; /* Unknown */
1124 d_printf("User must be specified\n");
1125 rpc_user_usage(argc, argv);
1126 return NT_STATUS_OK;
1128 /* Get sam policy handle */
1130 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1132 if (!NT_STATUS_IS_OK(result)) goto done;
1134 /* Get domain policy handle */
1136 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
1137 MAXIMUM_ALLOWED_ACCESS,
1138 domain_sid, &domain_pol);
1139 if (!NT_STATUS_IS_OK(result)) goto done;
1141 /* Get handle on user */
1143 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol,
1145 &num_rids, &rids, &name_types);
1147 if (!NT_STATUS_IS_OK(result)) goto done;
1149 result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
1150 MAXIMUM_ALLOWED_ACCESS,
1151 rids[0], &user_pol);
1152 if (!NT_STATUS_IS_OK(result)) goto done;
1154 result = rpccli_samr_query_usergroups(pipe_hnd, mem_ctx, &user_pol,
1155 &num_rids, &user_gids);
1157 if (!NT_STATUS_IS_OK(result)) goto done;
1162 if ((rids = TALLOC_ARRAY(mem_ctx, uint32, num_rids)) == NULL) {
1163 result = NT_STATUS_NO_MEMORY;
1167 for (i = 0; i < num_rids; i++)
1168 rids[i] = user_gids[i].g_rid;
1170 result = rpccli_samr_lookup_rids(pipe_hnd, mem_ctx, &domain_pol,
1172 &num_names, &names, &name_types);
1174 if (!NT_STATUS_IS_OK(result)) {
1178 /* Display results */
1180 for (i = 0; i < num_names; i++)
1181 printf("%s\n", names[i]);
1188 * List a user's groups from a remote RPC server
1190 * @param argc Standard main() style argc
1191 * @param argv Standard main() style argv. Initial components are already
1194 * @return A shell status integer (0 for success)
1197 static int rpc_user_info(int argc, const char **argv)
1199 return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_info_internals,
1204 * List users on a remote RPC server
1206 * All parameters are provided by the run_rpc_command function, except for
1207 * argc, argv which are passes through.
1209 * @param domain_sid The domain sid acquired from the remote server
1210 * @param cli A cli_state connected to the server.
1211 * @param mem_ctx Talloc context, destoyed on completion of the function.
1212 * @param argc Standard main() style argc
1213 * @param argv Standard main() style argv. Initial components are already
1216 * @return Normal NTSTATUS return.
1219 static NTSTATUS rpc_user_list_internals(const DOM_SID *domain_sid,
1220 const char *domain_name,
1221 struct cli_state *cli,
1222 struct rpc_pipe_client *pipe_hnd,
1223 TALLOC_CTX *mem_ctx,
1227 POLICY_HND connect_pol, domain_pol;
1228 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1229 uint32 start_idx=0, num_entries, i, loop_count = 0;
1230 SAM_DISPINFO_CTR ctr;
1231 SAM_DISPINFO_1 info1;
1233 /* Get sam policy handle */
1235 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1237 if (!NT_STATUS_IS_OK(result)) {
1241 /* Get domain policy handle */
1243 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
1244 MAXIMUM_ALLOWED_ACCESS,
1245 domain_sid, &domain_pol);
1246 if (!NT_STATUS_IS_OK(result)) {
1250 /* Query domain users */
1253 ctr.sam.info1 = &info1;
1254 if (opt_long_list_entries)
1255 d_printf("\nUser name Comment"\
1256 "\n-----------------------------\n");
1259 uint32 max_entries, max_size;
1261 get_query_dispinfo_params(
1262 loop_count, &max_entries, &max_size);
1264 result = rpccli_samr_query_dispinfo(pipe_hnd, mem_ctx, &domain_pol,
1265 &start_idx, 1, &num_entries,
1266 max_entries, max_size, &ctr);
1269 for (i = 0; i < num_entries; i++) {
1270 unistr2_to_ascii(user, &(&ctr.sam.info1->str[i])->uni_acct_name, sizeof(user));
1271 if (opt_long_list_entries)
1272 unistr2_to_ascii(desc, &(&ctr.sam.info1->str[i])->uni_acct_desc, sizeof(desc));
1274 if (opt_long_list_entries)
1275 printf("%-21.21s %s\n", user, desc);
1277 printf("%s\n", user);
1279 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
1286 * 'net rpc user' entrypoint.
1287 * @param argc Standard main() style argc
1288 * @param argc Standard main() style argv. Initial components are already
1292 int net_rpc_user(int argc, const char **argv)
1294 struct functable func[] = {
1295 {"add", rpc_user_add},
1296 {"info", rpc_user_info},
1297 {"delete", rpc_user_delete},
1298 {"password", rpc_user_password},
1299 {"rename", rpc_user_rename},
1304 return run_rpc_command(NULL,PI_SAMR, 0,
1305 rpc_user_list_internals,
1309 return net_run_function(argc, argv, func, rpc_user_usage);
1312 static NTSTATUS rpc_sh_user_list(TALLOC_CTX *mem_ctx,
1313 struct rpc_sh_ctx *ctx,
1314 struct rpc_pipe_client *pipe_hnd,
1315 int argc, const char **argv)
1317 return rpc_user_list_internals(ctx->domain_sid, ctx->domain_name,
1318 ctx->cli, pipe_hnd, mem_ctx,
1322 static NTSTATUS rpc_sh_user_info(TALLOC_CTX *mem_ctx,
1323 struct rpc_sh_ctx *ctx,
1324 struct rpc_pipe_client *pipe_hnd,
1325 int argc, const char **argv)
1327 return rpc_user_info_internals(ctx->domain_sid, ctx->domain_name,
1328 ctx->cli, pipe_hnd, mem_ctx,
1332 static NTSTATUS rpc_sh_handle_user(TALLOC_CTX *mem_ctx,
1333 struct rpc_sh_ctx *ctx,
1334 struct rpc_pipe_client *pipe_hnd,
1335 int argc, const char **argv,
1337 TALLOC_CTX *mem_ctx,
1338 struct rpc_sh_ctx *ctx,
1339 struct rpc_pipe_client *pipe_hnd,
1340 const POLICY_HND *user_hnd,
1341 int argc, const char **argv))
1344 POLICY_HND connect_pol, domain_pol, user_pol;
1345 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1348 enum lsa_SidType type;
1351 d_fprintf(stderr, "usage: %s <username>\n", ctx->whoami);
1352 return NT_STATUS_INVALID_PARAMETER;
1355 ZERO_STRUCT(connect_pol);
1356 ZERO_STRUCT(domain_pol);
1357 ZERO_STRUCT(user_pol);
1359 result = net_rpc_lookup_name(mem_ctx, pipe_hnd->cli, argv[0],
1360 NULL, NULL, &sid, &type);
1361 if (!NT_STATUS_IS_OK(result)) {
1362 d_fprintf(stderr, "Could not lookup %s: %s\n", argv[0],
1367 if (type != SID_NAME_USER) {
1368 d_fprintf(stderr, "%s is a %s, not a user\n", argv[0],
1369 sid_type_lookup(type));
1370 result = NT_STATUS_NO_SUCH_USER;
1374 if (!sid_peek_check_rid(ctx->domain_sid, &sid, &rid)) {
1375 d_fprintf(stderr, "%s is not in our domain\n", argv[0]);
1376 result = NT_STATUS_NO_SUCH_USER;
1380 result = rpccli_samr_connect(pipe_hnd, mem_ctx,
1381 MAXIMUM_ALLOWED_ACCESS, &connect_pol);
1382 if (!NT_STATUS_IS_OK(result)) {
1386 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
1387 MAXIMUM_ALLOWED_ACCESS,
1388 ctx->domain_sid, &domain_pol);
1389 if (!NT_STATUS_IS_OK(result)) {
1393 result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
1394 MAXIMUM_ALLOWED_ACCESS,
1396 if (!NT_STATUS_IS_OK(result)) {
1400 result = fn(mem_ctx, ctx, pipe_hnd, &user_pol, argc-1, argv+1);
1403 if (is_valid_policy_hnd(&user_pol)) {
1404 rpccli_samr_close(pipe_hnd, mem_ctx, &user_pol);
1406 if (is_valid_policy_hnd(&domain_pol)) {
1407 rpccli_samr_close(pipe_hnd, mem_ctx, &domain_pol);
1409 if (is_valid_policy_hnd(&connect_pol)) {
1410 rpccli_samr_close(pipe_hnd, mem_ctx, &connect_pol);
1415 static NTSTATUS rpc_sh_user_show_internals(TALLOC_CTX *mem_ctx,
1416 struct rpc_sh_ctx *ctx,
1417 struct rpc_pipe_client *pipe_hnd,
1418 const POLICY_HND *user_hnd,
1419 int argc, const char **argv)
1422 SAM_USERINFO_CTR *ctr;
1423 SAM_USER_INFO_21 *info;
1426 d_fprintf(stderr, "usage: %s show <username>\n", ctx->whoami);
1427 return NT_STATUS_INVALID_PARAMETER;
1430 result = rpccli_samr_query_userinfo(pipe_hnd, mem_ctx, user_hnd,
1432 if (!NT_STATUS_IS_OK(result)) {
1436 info = ctr->info.id21;
1438 d_printf("user rid: %d, group rid: %d\n", info->user_rid,
1444 static NTSTATUS rpc_sh_user_show(TALLOC_CTX *mem_ctx,
1445 struct rpc_sh_ctx *ctx,
1446 struct rpc_pipe_client *pipe_hnd,
1447 int argc, const char **argv)
1449 return rpc_sh_handle_user(mem_ctx, ctx, pipe_hnd, argc, argv,
1450 rpc_sh_user_show_internals);
1453 #define FETCHSTR(name, rec) \
1454 do { if (strequal(ctx->thiscmd, name)) { \
1455 oldval = rpcstr_pull_unistr2_talloc(mem_ctx, &usr->uni_##rec); } \
1458 #define SETSTR(name, rec, flag) \
1459 do { if (strequal(ctx->thiscmd, name)) { \
1460 init_unistr2(&usr->uni_##rec, argv[0], UNI_STR_TERMINATE); \
1461 init_uni_hdr(&usr->hdr_##rec, &usr->uni_##rec); \
1462 usr->fields_present |= ACCT_##flag; } \
1465 static NTSTATUS rpc_sh_user_str_edit_internals(TALLOC_CTX *mem_ctx,
1466 struct rpc_sh_ctx *ctx,
1467 struct rpc_pipe_client *pipe_hnd,
1468 const POLICY_HND *user_hnd,
1469 int argc, const char **argv)
1472 SAM_USERINFO_CTR *ctr;
1473 SAM_USER_INFO_21 *usr;
1474 const char *username;
1475 const char *oldval = "";
1478 d_fprintf(stderr, "usage: %s <username> [new value|NULL]\n",
1480 return NT_STATUS_INVALID_PARAMETER;
1483 result = rpccli_samr_query_userinfo(pipe_hnd, mem_ctx, user_hnd,
1485 if (!NT_STATUS_IS_OK(result)) {
1489 usr = ctr->info.id21;
1491 username = rpcstr_pull_unistr2_talloc(mem_ctx, &usr->uni_user_name);
1493 FETCHSTR("fullname", full_name);
1494 FETCHSTR("homedir", home_dir);
1495 FETCHSTR("homedrive", dir_drive);
1496 FETCHSTR("logonscript", logon_script);
1497 FETCHSTR("profilepath", profile_path);
1498 FETCHSTR("description", acct_desc);
1501 d_printf("%s's %s: [%s]\n", username, ctx->thiscmd, oldval);
1507 if (strcmp(argv[0], "NULL") == 0) {
1511 SETSTR("fullname", full_name, FULL_NAME);
1512 SETSTR("homedir", home_dir, HOME_DIR);
1513 SETSTR("homedrive", dir_drive, HOME_DRIVE);
1514 SETSTR("logonscript", logon_script, LOGON_SCRIPT);
1515 SETSTR("profilepath", profile_path, PROFILE);
1516 SETSTR("description", acct_desc, DESCRIPTION);
1518 result = rpccli_samr_set_userinfo2(
1519 pipe_hnd, mem_ctx, user_hnd, 21,
1520 &pipe_hnd->cli->user_session_key, ctr);
1522 d_printf("Set %s's %s from [%s] to [%s]\n", username,
1523 ctx->thiscmd, oldval, argv[0]);
1530 #define HANDLEFLG(name, rec) \
1531 do { if (strequal(ctx->thiscmd, name)) { \
1532 oldval = (oldflags & ACB_##rec) ? "yes" : "no"; \
1534 newflags = oldflags | ACB_##rec; \
1536 newflags = oldflags & ~ACB_##rec; \
1539 static NTSTATUS rpc_sh_user_str_edit(TALLOC_CTX *mem_ctx,
1540 struct rpc_sh_ctx *ctx,
1541 struct rpc_pipe_client *pipe_hnd,
1542 int argc, const char **argv)
1544 return rpc_sh_handle_user(mem_ctx, ctx, pipe_hnd, argc, argv,
1545 rpc_sh_user_str_edit_internals);
1548 static NTSTATUS rpc_sh_user_flag_edit_internals(TALLOC_CTX *mem_ctx,
1549 struct rpc_sh_ctx *ctx,
1550 struct rpc_pipe_client *pipe_hnd,
1551 const POLICY_HND *user_hnd,
1552 int argc, const char **argv)
1555 SAM_USERINFO_CTR *ctr;
1556 SAM_USER_INFO_21 *usr;
1557 const char *username;
1558 const char *oldval = "unknown";
1559 uint32 oldflags, newflags;
1563 ((argc == 1) && !strequal(argv[0], "yes") &&
1564 !strequal(argv[0], "no"))) {
1565 d_fprintf(stderr, "usage: %s <username> [yes|no]\n",
1567 return NT_STATUS_INVALID_PARAMETER;
1570 newval = strequal(argv[0], "yes");
1572 result = rpccli_samr_query_userinfo(pipe_hnd, mem_ctx, user_hnd,
1574 if (!NT_STATUS_IS_OK(result)) {
1578 usr = ctr->info.id21;
1580 username = rpcstr_pull_unistr2_talloc(mem_ctx, &usr->uni_user_name);
1581 oldflags = usr->acb_info;
1582 newflags = usr->acb_info;
1584 HANDLEFLG("disabled", DISABLED);
1585 HANDLEFLG("pwnotreq", PWNOTREQ);
1586 HANDLEFLG("autolock", AUTOLOCK);
1587 HANDLEFLG("pwnoexp", PWNOEXP);
1590 d_printf("%s's %s flag: %s\n", username, ctx->thiscmd, oldval);
1596 usr->acb_info = newflags;
1597 usr->fields_present = ACCT_FLAGS;
1599 result = rpccli_samr_set_userinfo2(
1600 pipe_hnd, mem_ctx, user_hnd, 21,
1601 &pipe_hnd->cli->user_session_key, ctr);
1603 if (NT_STATUS_IS_OK(result)) {
1604 d_printf("Set %s's %s flag from [%s] to [%s]\n", username,
1605 ctx->thiscmd, oldval, argv[0]);
1613 static NTSTATUS rpc_sh_user_flag_edit(TALLOC_CTX *mem_ctx,
1614 struct rpc_sh_ctx *ctx,
1615 struct rpc_pipe_client *pipe_hnd,
1616 int argc, const char **argv)
1618 return rpc_sh_handle_user(mem_ctx, ctx, pipe_hnd, argc, argv,
1619 rpc_sh_user_flag_edit_internals);
1622 struct rpc_sh_cmd *net_rpc_user_edit_cmds(TALLOC_CTX *mem_ctx,
1623 struct rpc_sh_ctx *ctx)
1625 static struct rpc_sh_cmd cmds[] = {
1627 { "fullname", NULL, PI_SAMR, rpc_sh_user_str_edit,
1628 "Show/Set a user's full name" },
1630 { "homedir", NULL, PI_SAMR, rpc_sh_user_str_edit,
1631 "Show/Set a user's home directory" },
1633 { "homedrive", NULL, PI_SAMR, rpc_sh_user_str_edit,
1634 "Show/Set a user's home drive" },
1636 { "logonscript", NULL, PI_SAMR, rpc_sh_user_str_edit,
1637 "Show/Set a user's logon script" },
1639 { "profilepath", NULL, PI_SAMR, rpc_sh_user_str_edit,
1640 "Show/Set a user's profile path" },
1642 { "description", NULL, PI_SAMR, rpc_sh_user_str_edit,
1643 "Show/Set a user's description" },
1645 { "disabled", NULL, PI_SAMR, rpc_sh_user_flag_edit,
1646 "Show/Set whether a user is disabled" },
1648 { "autolock", NULL, PI_SAMR, rpc_sh_user_flag_edit,
1649 "Show/Set whether a user locked out" },
1651 { "pwnotreq", NULL, PI_SAMR, rpc_sh_user_flag_edit,
1652 "Show/Set whether a user does not need a password" },
1654 { "pwnoexp", NULL, PI_SAMR, rpc_sh_user_flag_edit,
1655 "Show/Set whether a user's password does not expire" },
1657 { NULL, NULL, 0, NULL, NULL }
1663 struct rpc_sh_cmd *net_rpc_user_cmds(TALLOC_CTX *mem_ctx,
1664 struct rpc_sh_ctx *ctx)
1666 static struct rpc_sh_cmd cmds[] = {
1668 { "list", NULL, PI_SAMR, rpc_sh_user_list,
1669 "List available users" },
1671 { "info", NULL, PI_SAMR, rpc_sh_user_info,
1672 "List the domain groups a user is member of" },
1674 { "show", NULL, PI_SAMR, rpc_sh_user_show,
1675 "Show info about a user" },
1677 { "edit", net_rpc_user_edit_cmds, 0, NULL,
1678 "Show/Modify a user's fields" },
1680 { NULL, NULL, 0, NULL, NULL }
1686 /****************************************************************************/
1689 * Basic usage function for 'net rpc group'
1690 * @param argc Standard main() style argc.
1691 * @param argv Standard main() style argv. Initial components are already
1695 static int rpc_group_usage(int argc, const char **argv)
1697 return net_help_group(argc, argv);
1701 * Delete group on a remote RPC server
1703 * All parameters are provided by the run_rpc_command function, except for
1704 * argc, argv which are passes through.
1706 * @param domain_sid The domain sid acquired from the remote server
1707 * @param cli A cli_state connected to the server.
1708 * @param mem_ctx Talloc context, destoyed on completion of the function.
1709 * @param argc Standard main() style argc
1710 * @param argv Standard main() style argv. Initial components are already
1713 * @return Normal NTSTATUS return.
1716 static NTSTATUS rpc_group_delete_internals(const DOM_SID *domain_sid,
1717 const char *domain_name,
1718 struct cli_state *cli,
1719 struct rpc_pipe_client *pipe_hnd,
1720 TALLOC_CTX *mem_ctx,
1724 POLICY_HND connect_pol, domain_pol, group_pol, user_pol;
1725 bool group_is_primary = False;
1726 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1728 uint32 *group_rids, num_rids, *name_types, num_members,
1729 *group_attrs, group_rid;
1730 uint32 flags = 0x000003e8; /* Unknown */
1733 /* DOM_GID *user_gids; */
1734 SAM_USERINFO_CTR *user_ctr;
1738 d_printf("specify group\n");
1739 rpc_group_usage(argc,argv);
1740 return NT_STATUS_OK; /* ok? */
1743 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1746 if (!NT_STATUS_IS_OK(result)) {
1747 d_fprintf(stderr, "Request samr_connect failed\n");
1751 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
1752 MAXIMUM_ALLOWED_ACCESS,
1753 domain_sid, &domain_pol);
1755 if (!NT_STATUS_IS_OK(result)) {
1756 d_fprintf(stderr, "Request open_domain failed\n");
1760 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol,
1762 &num_rids, &group_rids,
1765 if (!NT_STATUS_IS_OK(result)) {
1766 d_fprintf(stderr, "Lookup of '%s' failed\n",argv[0]);
1770 switch (name_types[0])
1772 case SID_NAME_DOM_GRP:
1773 result = rpccli_samr_open_group(pipe_hnd, mem_ctx, &domain_pol,
1774 MAXIMUM_ALLOWED_ACCESS,
1775 group_rids[0], &group_pol);
1776 if (!NT_STATUS_IS_OK(result)) {
1777 d_fprintf(stderr, "Request open_group failed");
1781 group_rid = group_rids[0];
1783 result = rpccli_samr_query_groupmem(pipe_hnd, mem_ctx, &group_pol,
1784 &num_members, &group_rids,
1787 if (!NT_STATUS_IS_OK(result)) {
1788 d_fprintf(stderr, "Unable to query group members of %s",argv[0]);
1793 d_printf("Domain Group %s (rid: %d) has %d members\n",
1794 argv[0],group_rid,num_members);
1797 /* Check if group is anyone's primary group */
1798 for (i = 0; i < num_members; i++)
1800 result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
1801 MAXIMUM_ALLOWED_ACCESS,
1802 group_rids[i], &user_pol);
1804 if (!NT_STATUS_IS_OK(result)) {
1805 d_fprintf(stderr, "Unable to open group member %d\n",group_rids[i]);
1809 ZERO_STRUCT(user_ctr);
1811 result = rpccli_samr_query_userinfo(pipe_hnd, mem_ctx, &user_pol,
1814 if (!NT_STATUS_IS_OK(result)) {
1815 d_fprintf(stderr, "Unable to lookup userinfo for group member %d\n",group_rids[i]);
1819 if (user_ctr->info.id21->group_rid == group_rid) {
1820 unistr2_to_ascii(temp, &(user_ctr->info.id21)->uni_user_name,
1823 d_printf("Group is primary group of %s\n",temp);
1824 group_is_primary = True;
1827 rpccli_samr_close(pipe_hnd, mem_ctx, &user_pol);
1830 if (group_is_primary) {
1831 d_fprintf(stderr, "Unable to delete group because some "
1832 "of it's members have it as primary group\n");
1833 result = NT_STATUS_MEMBERS_PRIMARY_GROUP;
1837 /* remove all group members */
1838 for (i = 0; i < num_members; i++)
1841 d_printf("Remove group member %d...",group_rids[i]);
1842 result = rpccli_samr_del_groupmem(pipe_hnd, mem_ctx, &group_pol, group_rids[i]);
1844 if (NT_STATUS_IS_OK(result)) {
1849 d_printf("failed\n");
1854 result = rpccli_samr_delete_dom_group(pipe_hnd, mem_ctx, &group_pol);
1857 /* removing a local group is easier... */
1858 case SID_NAME_ALIAS:
1859 result = rpccli_samr_open_alias(pipe_hnd, mem_ctx, &domain_pol,
1860 MAXIMUM_ALLOWED_ACCESS,
1861 group_rids[0], &group_pol);
1863 if (!NT_STATUS_IS_OK(result)) {
1864 d_fprintf(stderr, "Request open_alias failed\n");
1868 result = rpccli_samr_delete_dom_alias(pipe_hnd, mem_ctx, &group_pol);
1871 d_fprintf(stderr, "%s is of type %s. This command is only for deleting local or global groups\n",
1872 argv[0],sid_type_lookup(name_types[0]));
1873 result = NT_STATUS_UNSUCCESSFUL;
1878 if (NT_STATUS_IS_OK(result)) {
1880 d_printf("Deleted %s '%s'\n",sid_type_lookup(name_types[0]),argv[0]);
1882 d_fprintf(stderr, "Deleting of %s failed: %s\n",argv[0],
1883 get_friendly_nt_error_msg(result));
1891 static int rpc_group_delete(int argc, const char **argv)
1893 return run_rpc_command(NULL, PI_SAMR, 0, rpc_group_delete_internals,
1897 static NTSTATUS rpc_group_add_internals(const DOM_SID *domain_sid,
1898 const char *domain_name,
1899 struct cli_state *cli,
1900 struct rpc_pipe_client *pipe_hnd,
1901 TALLOC_CTX *mem_ctx,
1905 POLICY_HND connect_pol, domain_pol, group_pol;
1906 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1907 GROUP_INFO_CTR group_info;
1910 d_printf("Group name must be specified\n");
1911 rpc_group_usage(argc, argv);
1912 return NT_STATUS_OK;
1915 /* Get sam policy handle */
1917 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1919 if (!NT_STATUS_IS_OK(result)) goto done;
1921 /* Get domain policy handle */
1923 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
1924 MAXIMUM_ALLOWED_ACCESS,
1925 domain_sid, &domain_pol);
1926 if (!NT_STATUS_IS_OK(result)) goto done;
1928 /* Create the group */
1930 result = rpccli_samr_create_dom_group(pipe_hnd, mem_ctx, &domain_pol,
1931 argv[0], MAXIMUM_ALLOWED_ACCESS,
1933 if (!NT_STATUS_IS_OK(result)) goto done;
1935 if (strlen(opt_comment) == 0) goto done;
1937 /* We've got a comment to set */
1939 group_info.switch_value1 = 4;
1940 init_samr_group_info4(&group_info.group.info4, opt_comment);
1942 result = rpccli_samr_set_groupinfo(pipe_hnd, mem_ctx, &group_pol, &group_info);
1943 if (!NT_STATUS_IS_OK(result)) goto done;
1946 if (NT_STATUS_IS_OK(result))
1947 DEBUG(5, ("add group succeeded\n"));
1949 d_fprintf(stderr, "add group failed: %s\n", nt_errstr(result));
1954 static NTSTATUS rpc_alias_add_internals(const DOM_SID *domain_sid,
1955 const char *domain_name,
1956 struct cli_state *cli,
1957 struct rpc_pipe_client *pipe_hnd,
1958 TALLOC_CTX *mem_ctx,
1962 POLICY_HND connect_pol, domain_pol, alias_pol;
1963 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1964 ALIAS_INFO_CTR alias_info;
1967 d_printf("Alias name must be specified\n");
1968 rpc_group_usage(argc, argv);
1969 return NT_STATUS_OK;
1972 /* Get sam policy handle */
1974 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1976 if (!NT_STATUS_IS_OK(result)) goto done;
1978 /* Get domain policy handle */
1980 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
1981 MAXIMUM_ALLOWED_ACCESS,
1982 domain_sid, &domain_pol);
1983 if (!NT_STATUS_IS_OK(result)) goto done;
1985 /* Create the group */
1987 result = rpccli_samr_create_dom_alias(pipe_hnd, mem_ctx, &domain_pol,
1988 argv[0], &alias_pol);
1989 if (!NT_STATUS_IS_OK(result)) goto done;
1991 if (strlen(opt_comment) == 0) goto done;
1993 /* We've got a comment to set */
1995 alias_info.level = 3;
1996 init_samr_alias_info3(&alias_info.alias.info3, opt_comment);
1998 result = rpccli_samr_set_aliasinfo(pipe_hnd, mem_ctx, &alias_pol, &alias_info);
1999 if (!NT_STATUS_IS_OK(result)) goto done;
2002 if (NT_STATUS_IS_OK(result))
2003 DEBUG(5, ("add alias succeeded\n"));
2005 d_fprintf(stderr, "add alias failed: %s\n", nt_errstr(result));
2010 static int rpc_group_add(int argc, const char **argv)
2013 return run_rpc_command(NULL, PI_SAMR, 0,
2014 rpc_alias_add_internals,
2017 return run_rpc_command(NULL, PI_SAMR, 0,
2018 rpc_group_add_internals,
2022 static NTSTATUS get_sid_from_name(struct cli_state *cli,
2023 TALLOC_CTX *mem_ctx,
2026 enum lsa_SidType *type)
2028 DOM_SID *sids = NULL;
2029 enum lsa_SidType *types = NULL;
2030 struct rpc_pipe_client *pipe_hnd;
2032 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2034 pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_LSARPC, &result);
2039 result = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, False,
2040 SEC_RIGHTS_MAXIMUM_ALLOWED, &lsa_pol);
2042 if (!NT_STATUS_IS_OK(result)) {
2046 result = rpccli_lsa_lookup_names(pipe_hnd, mem_ctx, &lsa_pol, 1,
2047 &name, NULL, 1, &sids, &types);
2049 if (NT_STATUS_IS_OK(result)) {
2050 sid_copy(sid, &sids[0]);
2054 rpccli_lsa_Close(pipe_hnd, mem_ctx, &lsa_pol);
2058 cli_rpc_pipe_close(pipe_hnd);
2061 if (!NT_STATUS_IS_OK(result) && (StrnCaseCmp(name, "S-", 2) == 0)) {
2063 /* Try as S-1-5-whatever */
2067 if (string_to_sid(&tmp_sid, name)) {
2068 sid_copy(sid, &tmp_sid);
2069 *type = SID_NAME_UNKNOWN;
2070 result = NT_STATUS_OK;
2077 static NTSTATUS rpc_add_groupmem(struct rpc_pipe_client *pipe_hnd,
2078 TALLOC_CTX *mem_ctx,
2079 const DOM_SID *group_sid,
2082 POLICY_HND connect_pol, domain_pol;
2085 POLICY_HND group_pol;
2088 uint32 *rids = NULL;
2089 uint32 *rid_types = NULL;
2093 sid_copy(&sid, group_sid);
2095 if (!sid_split_rid(&sid, &group_rid)) {
2096 return NT_STATUS_UNSUCCESSFUL;
2099 /* Get sam policy handle */
2100 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
2102 if (!NT_STATUS_IS_OK(result)) {
2106 /* Get domain policy handle */
2107 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
2108 MAXIMUM_ALLOWED_ACCESS,
2110 if (!NT_STATUS_IS_OK(result)) {
2114 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, 1000,
2116 &num_rids, &rids, &rid_types);
2118 if (!NT_STATUS_IS_OK(result)) {
2119 d_fprintf(stderr, "Could not lookup up group member %s\n", member);
2123 result = rpccli_samr_open_group(pipe_hnd, mem_ctx, &domain_pol,
2124 MAXIMUM_ALLOWED_ACCESS,
2125 group_rid, &group_pol);
2127 if (!NT_STATUS_IS_OK(result)) {
2131 result = rpccli_samr_add_groupmem(pipe_hnd, mem_ctx, &group_pol, rids[0]);
2134 rpccli_samr_close(pipe_hnd, mem_ctx, &connect_pol);
2138 static NTSTATUS rpc_add_aliasmem(struct rpc_pipe_client *pipe_hnd,
2139 TALLOC_CTX *mem_ctx,
2140 const DOM_SID *alias_sid,
2143 POLICY_HND connect_pol, domain_pol;
2146 POLICY_HND alias_pol;
2149 enum lsa_SidType member_type;
2153 sid_copy(&sid, alias_sid);
2155 if (!sid_split_rid(&sid, &alias_rid)) {
2156 return NT_STATUS_UNSUCCESSFUL;
2159 result = get_sid_from_name(pipe_hnd->cli, mem_ctx, member,
2160 &member_sid, &member_type);
2162 if (!NT_STATUS_IS_OK(result)) {
2163 d_fprintf(stderr, "Could not lookup up group member %s\n", member);
2167 /* Get sam policy handle */
2168 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
2170 if (!NT_STATUS_IS_OK(result)) {
2174 /* Get domain policy handle */
2175 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
2176 MAXIMUM_ALLOWED_ACCESS,
2178 if (!NT_STATUS_IS_OK(result)) {
2182 result = rpccli_samr_open_alias(pipe_hnd, mem_ctx, &domain_pol,
2183 MAXIMUM_ALLOWED_ACCESS,
2184 alias_rid, &alias_pol);
2186 if (!NT_STATUS_IS_OK(result)) {
2190 result = rpccli_samr_add_aliasmem(pipe_hnd, mem_ctx, &alias_pol, &member_sid);
2192 if (!NT_STATUS_IS_OK(result)) {
2197 rpccli_samr_close(pipe_hnd, mem_ctx, &connect_pol);
2201 static NTSTATUS rpc_group_addmem_internals(const DOM_SID *domain_sid,
2202 const char *domain_name,
2203 struct cli_state *cli,
2204 struct rpc_pipe_client *pipe_hnd,
2205 TALLOC_CTX *mem_ctx,
2210 enum lsa_SidType group_type;
2213 d_printf("Usage: 'net rpc group addmem <group> <member>\n");
2214 return NT_STATUS_UNSUCCESSFUL;
2217 if (!NT_STATUS_IS_OK(get_sid_from_name(cli, mem_ctx, argv[0],
2218 &group_sid, &group_type))) {
2219 d_fprintf(stderr, "Could not lookup group name %s\n", argv[0]);
2220 return NT_STATUS_UNSUCCESSFUL;
2223 if (group_type == SID_NAME_DOM_GRP) {
2224 NTSTATUS result = rpc_add_groupmem(pipe_hnd, mem_ctx,
2225 &group_sid, argv[1]);
2227 if (!NT_STATUS_IS_OK(result)) {
2228 d_fprintf(stderr, "Could not add %s to %s: %s\n",
2229 argv[1], argv[0], nt_errstr(result));
2234 if (group_type == SID_NAME_ALIAS) {
2235 NTSTATUS result = rpc_add_aliasmem(pipe_hnd, mem_ctx,
2236 &group_sid, argv[1]);
2238 if (!NT_STATUS_IS_OK(result)) {
2239 d_fprintf(stderr, "Could not add %s to %s: %s\n",
2240 argv[1], argv[0], nt_errstr(result));
2245 d_fprintf(stderr, "Can only add members to global or local groups "
2246 "which %s is not\n", argv[0]);
2248 return NT_STATUS_UNSUCCESSFUL;
2251 static int rpc_group_addmem(int argc, const char **argv)
2253 return run_rpc_command(NULL, PI_SAMR, 0,
2254 rpc_group_addmem_internals,
2258 static NTSTATUS rpc_del_groupmem(struct rpc_pipe_client *pipe_hnd,
2259 TALLOC_CTX *mem_ctx,
2260 const DOM_SID *group_sid,
2263 POLICY_HND connect_pol, domain_pol;
2266 POLICY_HND group_pol;
2269 uint32 *rids = NULL;
2270 uint32 *rid_types = NULL;
2274 sid_copy(&sid, group_sid);
2276 if (!sid_split_rid(&sid, &group_rid))
2277 return NT_STATUS_UNSUCCESSFUL;
2279 /* Get sam policy handle */
2280 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
2282 if (!NT_STATUS_IS_OK(result))
2285 /* Get domain policy handle */
2286 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
2287 MAXIMUM_ALLOWED_ACCESS,
2289 if (!NT_STATUS_IS_OK(result))
2292 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, 1000,
2294 &num_rids, &rids, &rid_types);
2296 if (!NT_STATUS_IS_OK(result)) {
2297 d_fprintf(stderr, "Could not lookup up group member %s\n", member);
2301 result = rpccli_samr_open_group(pipe_hnd, mem_ctx, &domain_pol,
2302 MAXIMUM_ALLOWED_ACCESS,
2303 group_rid, &group_pol);
2305 if (!NT_STATUS_IS_OK(result))
2308 result = rpccli_samr_del_groupmem(pipe_hnd, mem_ctx, &group_pol, rids[0]);
2311 rpccli_samr_close(pipe_hnd, mem_ctx, &connect_pol);
2315 static NTSTATUS rpc_del_aliasmem(struct rpc_pipe_client *pipe_hnd,
2316 TALLOC_CTX *mem_ctx,
2317 const DOM_SID *alias_sid,
2320 POLICY_HND connect_pol, domain_pol;
2323 POLICY_HND alias_pol;
2326 enum lsa_SidType member_type;
2330 sid_copy(&sid, alias_sid);
2332 if (!sid_split_rid(&sid, &alias_rid))
2333 return NT_STATUS_UNSUCCESSFUL;
2335 result = get_sid_from_name(pipe_hnd->cli, mem_ctx, member,
2336 &member_sid, &member_type);
2338 if (!NT_STATUS_IS_OK(result)) {
2339 d_fprintf(stderr, "Could not lookup up group member %s\n", member);
2343 /* Get sam policy handle */
2344 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
2346 if (!NT_STATUS_IS_OK(result)) {
2350 /* Get domain policy handle */
2351 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
2352 MAXIMUM_ALLOWED_ACCESS,
2354 if (!NT_STATUS_IS_OK(result)) {
2358 result = rpccli_samr_open_alias(pipe_hnd, mem_ctx, &domain_pol,
2359 MAXIMUM_ALLOWED_ACCESS,
2360 alias_rid, &alias_pol);
2362 if (!NT_STATUS_IS_OK(result))
2365 result = rpccli_samr_del_aliasmem(pipe_hnd, mem_ctx, &alias_pol, &member_sid);
2367 if (!NT_STATUS_IS_OK(result))
2371 rpccli_samr_close(pipe_hnd, mem_ctx, &connect_pol);
2375 static NTSTATUS rpc_group_delmem_internals(const DOM_SID *domain_sid,
2376 const char *domain_name,
2377 struct cli_state *cli,
2378 struct rpc_pipe_client *pipe_hnd,
2379 TALLOC_CTX *mem_ctx,
2384 enum lsa_SidType group_type;
2387 d_printf("Usage: 'net rpc group delmem <group> <member>\n");
2388 return NT_STATUS_UNSUCCESSFUL;
2391 if (!NT_STATUS_IS_OK(get_sid_from_name(cli, mem_ctx, argv[0],
2392 &group_sid, &group_type))) {
2393 d_fprintf(stderr, "Could not lookup group name %s\n", argv[0]);
2394 return NT_STATUS_UNSUCCESSFUL;
2397 if (group_type == SID_NAME_DOM_GRP) {
2398 NTSTATUS result = rpc_del_groupmem(pipe_hnd, mem_ctx,
2399 &group_sid, argv[1]);
2401 if (!NT_STATUS_IS_OK(result)) {
2402 d_fprintf(stderr, "Could not del %s from %s: %s\n",
2403 argv[1], argv[0], nt_errstr(result));
2408 if (group_type == SID_NAME_ALIAS) {
2409 NTSTATUS result = rpc_del_aliasmem(pipe_hnd, mem_ctx,
2410 &group_sid, argv[1]);
2412 if (!NT_STATUS_IS_OK(result)) {
2413 d_fprintf(stderr, "Could not del %s from %s: %s\n",
2414 argv[1], argv[0], nt_errstr(result));
2419 d_fprintf(stderr, "Can only delete members from global or local groups "
2420 "which %s is not\n", argv[0]);
2422 return NT_STATUS_UNSUCCESSFUL;
2425 static int rpc_group_delmem(int argc, const char **argv)
2427 return run_rpc_command(NULL, PI_SAMR, 0,
2428 rpc_group_delmem_internals,
2433 * List groups on a remote RPC server
2435 * All parameters are provided by the run_rpc_command function, except for
2436 * argc, argv which are passes through.
2438 * @param domain_sid The domain sid acquired from the remote server
2439 * @param cli A cli_state connected to the server.
2440 * @param mem_ctx Talloc context, destoyed on completion of the function.
2441 * @param argc Standard main() style argc
2442 * @param argv Standard main() style argv. Initial components are already
2445 * @return Normal NTSTATUS return.
2448 static NTSTATUS rpc_group_list_internals(const DOM_SID *domain_sid,
2449 const char *domain_name,
2450 struct cli_state *cli,
2451 struct rpc_pipe_client *pipe_hnd,
2452 TALLOC_CTX *mem_ctx,
2456 POLICY_HND connect_pol, domain_pol;
2457 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2458 uint32 start_idx=0, max_entries=250, num_entries, i, loop_count = 0;
2459 struct acct_info *groups;
2460 bool global = False;
2462 bool builtin = False;
2470 for (i=0; i<argc; i++) {
2471 if (strequal(argv[i], "global"))
2474 if (strequal(argv[i], "local"))
2477 if (strequal(argv[i], "builtin"))
2481 /* Get sam policy handle */
2483 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
2485 if (!NT_STATUS_IS_OK(result)) {
2489 /* Get domain policy handle */
2491 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
2492 MAXIMUM_ALLOWED_ACCESS,
2493 domain_sid, &domain_pol);
2494 if (!NT_STATUS_IS_OK(result)) {
2498 /* Query domain groups */
2499 if (opt_long_list_entries)
2500 d_printf("\nGroup name Comment"\
2501 "\n-----------------------------\n");
2503 SAM_DISPINFO_CTR ctr;
2504 SAM_DISPINFO_3 info3;
2509 ctr.sam.info3 = &info3;
2513 get_query_dispinfo_params(
2514 loop_count, &max_entries, &max_size);
2516 result = rpccli_samr_query_dispinfo(pipe_hnd, mem_ctx, &domain_pol,
2517 &start_idx, 3, &num_entries,
2518 max_entries, max_size, &ctr);
2520 if (!NT_STATUS_IS_OK(result) &&
2521 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
2524 for (i = 0; i < num_entries; i++) {
2526 fstring group, desc;
2528 unistr2_to_ascii(group, &(&ctr.sam.info3->str[i])->uni_grp_name, sizeof(group));
2529 unistr2_to_ascii(desc, &(&ctr.sam.info3->str[i])->uni_grp_desc, sizeof(desc));
2531 if (opt_long_list_entries)
2532 printf("%-21.21s %-50.50s\n",
2535 printf("%s\n", group);
2537 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
2538 /* query domain aliases */
2543 /* The max_size field in cli_samr_enum_als_groups is more like
2544 * an account_control field with indiviual bits what to
2545 * retrieve. Set this to 0xffff as NT4 usrmgr.exe does to get
2546 * everything. I'm too lazy (sorry) to get this through to
2547 * rpc_parse/ etc. Volker */
2549 result = rpccli_samr_enum_als_groups(pipe_hnd, mem_ctx, &domain_pol,
2551 &groups, &num_entries);
2553 if (!NT_STATUS_IS_OK(result) &&
2554 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
2557 for (i = 0; i < num_entries; i++) {
2559 char *description = NULL;
2561 if (opt_long_list_entries) {
2563 POLICY_HND alias_pol;
2566 if ((NT_STATUS_IS_OK(rpccli_samr_open_alias(pipe_hnd, mem_ctx,
2571 (NT_STATUS_IS_OK(rpccli_samr_query_alias_info(pipe_hnd, mem_ctx,
2574 (NT_STATUS_IS_OK(rpccli_samr_close(pipe_hnd, mem_ctx,
2576 description = unistr2_to_ascii_talloc(mem_ctx,
2577 ctr.alias.info3.description.string);
2581 if (description != NULL) {
2582 printf("%-21.21s %-50.50s\n",
2583 groups[i].acct_name,
2586 printf("%s\n", groups[i].acct_name);
2589 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
2590 rpccli_samr_close(pipe_hnd, mem_ctx, &domain_pol);
2591 /* Get builtin policy handle */
2593 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
2594 MAXIMUM_ALLOWED_ACCESS,
2595 &global_sid_Builtin, &domain_pol);
2596 if (!NT_STATUS_IS_OK(result)) {
2599 /* query builtin aliases */
2602 if (!builtin) break;
2604 result = rpccli_samr_enum_als_groups(pipe_hnd, mem_ctx, &domain_pol,
2605 &start_idx, max_entries,
2606 &groups, &num_entries);
2608 if (!NT_STATUS_IS_OK(result) &&
2609 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
2612 for (i = 0; i < num_entries; i++) {
2614 char *description = NULL;
2616 if (opt_long_list_entries) {
2618 POLICY_HND alias_pol;
2621 if ((NT_STATUS_IS_OK(rpccli_samr_open_alias(pipe_hnd, mem_ctx,
2626 (NT_STATUS_IS_OK(rpccli_samr_query_alias_info(pipe_hnd, mem_ctx,
2629 (NT_STATUS_IS_OK(rpccli_samr_close(pipe_hnd, mem_ctx,
2631 description = unistr2_to_ascii_talloc(mem_ctx,
2632 ctr.alias.info3.description.string);
2636 if (description != NULL) {
2637 printf("%-21.21s %-50.50s\n",
2638 groups[i].acct_name,
2641 printf("%s\n", groups[i].acct_name);
2644 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
2650 static int rpc_group_list(int argc, const char **argv)
2652 return run_rpc_command(NULL, PI_SAMR, 0,
2653 rpc_group_list_internals,
2657 static NTSTATUS rpc_list_group_members(struct rpc_pipe_client *pipe_hnd,
2658 TALLOC_CTX *mem_ctx,
2659 const char *domain_name,
2660 const DOM_SID *domain_sid,
2661 POLICY_HND *domain_pol,
2665 POLICY_HND group_pol;
2666 uint32 num_members, *group_rids, *group_attrs;
2673 sid_to_fstring(sid_str, domain_sid);
2675 result = rpccli_samr_open_group(pipe_hnd, mem_ctx, domain_pol,
2676 MAXIMUM_ALLOWED_ACCESS,
2679 if (!NT_STATUS_IS_OK(result))
2682 result = rpccli_samr_query_groupmem(pipe_hnd, mem_ctx, &group_pol,
2683 &num_members, &group_rids,
2686 if (!NT_STATUS_IS_OK(result))
2689 while (num_members > 0) {
2690 int this_time = 512;
2692 if (num_members < this_time)
2693 this_time = num_members;
2695 result = rpccli_samr_lookup_rids(pipe_hnd, mem_ctx, domain_pol,
2696 this_time, group_rids,
2697 &num_names, &names, &name_types);
2699 if (!NT_STATUS_IS_OK(result))
2702 /* We only have users as members, but make the output
2703 the same as the output of alias members */
2705 for (i = 0; i < this_time; i++) {
2707 if (opt_long_list_entries) {
2708 printf("%s-%d %s\\%s %d\n", sid_str,
2709 group_rids[i], domain_name, names[i],
2712 printf("%s\\%s\n", domain_name, names[i]);
2716 num_members -= this_time;
2720 return NT_STATUS_OK;
2723 static NTSTATUS rpc_list_alias_members(struct rpc_pipe_client *pipe_hnd,
2724 TALLOC_CTX *mem_ctx,
2725 POLICY_HND *domain_pol,
2729 struct rpc_pipe_client *lsa_pipe;
2730 POLICY_HND alias_pol, lsa_pol;
2732 DOM_SID *alias_sids;
2735 enum lsa_SidType *types;
2738 result = rpccli_samr_open_alias(pipe_hnd, mem_ctx, domain_pol,
2739 MAXIMUM_ALLOWED_ACCESS, rid, &alias_pol);
2741 if (!NT_STATUS_IS_OK(result))
2744 result = rpccli_samr_query_aliasmem(pipe_hnd, mem_ctx, &alias_pol,
2745 &num_members, &alias_sids);
2747 if (!NT_STATUS_IS_OK(result)) {
2748 d_fprintf(stderr, "Couldn't list alias members\n");
2752 if (num_members == 0) {
2753 return NT_STATUS_OK;
2756 lsa_pipe = cli_rpc_pipe_open_noauth(pipe_hnd->cli, PI_LSARPC, &result);
2758 d_fprintf(stderr, "Couldn't open LSA pipe. Error was %s\n",
2759 nt_errstr(result) );
2763 result = rpccli_lsa_open_policy(lsa_pipe, mem_ctx, True,
2764 SEC_RIGHTS_MAXIMUM_ALLOWED, &lsa_pol);
2766 if (!NT_STATUS_IS_OK(result)) {
2767 d_fprintf(stderr, "Couldn't open LSA policy handle\n");
2768 cli_rpc_pipe_close(lsa_pipe);
2772 result = rpccli_lsa_lookup_sids(lsa_pipe, mem_ctx, &lsa_pol, num_members,
2774 &domains, &names, &types);
2776 if (!NT_STATUS_IS_OK(result) &&
2777 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
2778 d_fprintf(stderr, "Couldn't lookup SIDs\n");
2779 cli_rpc_pipe_close(lsa_pipe);
2783 for (i = 0; i < num_members; i++) {
2785 sid_to_fstring(sid_str, &alias_sids[i]);
2787 if (opt_long_list_entries) {
2788 printf("%s %s\\%s %d\n", sid_str,
2789 domains[i] ? domains[i] : "*unknown*",
2790 names[i] ? names[i] : "*unknown*", types[i]);
2793 printf("%s\\%s\n", domains[i], names[i]);
2795 printf("%s\n", sid_str);
2799 cli_rpc_pipe_close(lsa_pipe);
2800 return NT_STATUS_OK;
2803 static NTSTATUS rpc_group_members_internals(const DOM_SID *domain_sid,
2804 const char *domain_name,
2805 struct cli_state *cli,
2806 struct rpc_pipe_client *pipe_hnd,
2807 TALLOC_CTX *mem_ctx,
2812 POLICY_HND connect_pol, domain_pol;
2813 uint32 num_rids, *rids, *rid_types;
2815 /* Get sam policy handle */
2817 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
2820 if (!NT_STATUS_IS_OK(result))
2823 /* Get domain policy handle */
2825 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
2826 MAXIMUM_ALLOWED_ACCESS,
2827 domain_sid, &domain_pol);
2829 if (!NT_STATUS_IS_OK(result))
2832 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, 1000,
2833 1, argv, &num_rids, &rids, &rid_types);
2835 if (!NT_STATUS_IS_OK(result)) {
2837 /* Ok, did not find it in the global sam, try with builtin */
2839 DOM_SID sid_Builtin;
2841 rpccli_samr_close(pipe_hnd, mem_ctx, &domain_pol);
2843 string_to_sid(&sid_Builtin, "S-1-5-32");
2845 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
2846 MAXIMUM_ALLOWED_ACCESS,
2847 &sid_Builtin, &domain_pol);
2849 if (!NT_STATUS_IS_OK(result)) {
2850 d_fprintf(stderr, "Couldn't find group %s\n", argv[0]);
2854 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, 1000,
2858 if (!NT_STATUS_IS_OK(result)) {
2859 d_fprintf(stderr, "Couldn't find group %s\n", argv[0]);
2864 if (num_rids != 1) {
2865 d_fprintf(stderr, "Couldn't find group %s\n", argv[0]);
2869 if (rid_types[0] == SID_NAME_DOM_GRP) {
2870 return rpc_list_group_members(pipe_hnd, mem_ctx, domain_name,
2871 domain_sid, &domain_pol,
2875 if (rid_types[0] == SID_NAME_ALIAS) {
2876 return rpc_list_alias_members(pipe_hnd, mem_ctx, &domain_pol,
2880 return NT_STATUS_NO_SUCH_GROUP;
2883 static int rpc_group_members(int argc, const char **argv)
2886 return rpc_group_usage(argc, argv);
2889 return run_rpc_command(NULL, PI_SAMR, 0,
2890 rpc_group_members_internals,
2894 static NTSTATUS rpc_group_rename_internals(const DOM_SID *domain_sid,
2895 const char *domain_name,
2896 struct cli_state *cli,
2897 struct rpc_pipe_client *pipe_hnd,
2898 TALLOC_CTX *mem_ctx,
2903 POLICY_HND connect_pol, domain_pol, group_pol;
2904 uint32 num_rids, *rids, *rid_types;
2908 d_printf("Usage: 'net rpc group rename group newname'\n");
2909 return NT_STATUS_UNSUCCESSFUL;
2912 /* Get sam policy handle */
2914 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
2917 if (!NT_STATUS_IS_OK(result))
2920 /* Get domain policy handle */
2922 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
2923 MAXIMUM_ALLOWED_ACCESS,
2924 domain_sid, &domain_pol);
2926 if (!NT_STATUS_IS_OK(result))
2929 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, 1000,
2930 1, argv, &num_rids, &rids, &rid_types);
2932 if (num_rids != 1) {
2933 d_fprintf(stderr, "Couldn't find group %s\n", argv[0]);
2937 if (rid_types[0] != SID_NAME_DOM_GRP) {
2938 d_fprintf(stderr, "Can only rename domain groups\n");
2939 return NT_STATUS_UNSUCCESSFUL;
2942 result = rpccli_samr_open_group(pipe_hnd, mem_ctx, &domain_pol,
2943 MAXIMUM_ALLOWED_ACCESS,
2944 rids[0], &group_pol);
2946 if (!NT_STATUS_IS_OK(result))
2951 ctr.switch_value1 = 2;
2952 init_samr_group_info2(&ctr.group.info2, argv[1]);
2954 result = rpccli_samr_set_groupinfo(pipe_hnd, mem_ctx, &group_pol, &ctr);
2956 if (!NT_STATUS_IS_OK(result))
2959 return NT_STATUS_NO_SUCH_GROUP;
2962 static int rpc_group_rename(int argc, const char **argv)
2965 return rpc_group_usage(argc, argv);
2968 return run_rpc_command(NULL, PI_SAMR, 0,
2969 rpc_group_rename_internals,
2974 * 'net rpc group' entrypoint.
2975 * @param argc Standard main() style argc
2976 * @param argc Standard main() style argv. Initial components are already
2980 int net_rpc_group(int argc, const char **argv)
2982 struct functable func[] = {
2983 {"add", rpc_group_add},
2984 {"delete", rpc_group_delete},
2985 {"addmem", rpc_group_addmem},
2986 {"delmem", rpc_group_delmem},
2987 {"list", rpc_group_list},
2988 {"members", rpc_group_members},
2989 {"rename", rpc_group_rename},
2994 return run_rpc_command(NULL, PI_SAMR, 0,
2995 rpc_group_list_internals,
2999 return net_run_function(argc, argv, func, rpc_group_usage);
3002 /****************************************************************************/
3004 static int rpc_share_usage(int argc, const char **argv)
3006 return net_help_share(argc, argv);
3010 * Add a share on a remote RPC server
3012 * All parameters are provided by the run_rpc_command function, except for
3013 * argc, argv which are passes through.
3015 * @param domain_sid The domain sid acquired from the remote server
3016 * @param cli A cli_state connected to the server.
3017 * @param mem_ctx Talloc context, destoyed on completion of the function.
3018 * @param argc Standard main() style argc
3019 * @param argv Standard main() style argv. Initial components are already
3022 * @return Normal NTSTATUS return.
3024 static NTSTATUS rpc_share_add_internals(const DOM_SID *domain_sid,
3025 const char *domain_name,
3026 struct cli_state *cli,
3027 struct rpc_pipe_client *pipe_hnd,
3028 TALLOC_CTX *mem_ctx,int argc,
3034 uint32 type = STYPE_DISKTREE; /* only allow disk shares to be added */
3035 uint32 num_users=0, perms=0;
3036 char *password=NULL; /* don't allow a share password */
3039 if ((sharename = talloc_strdup(mem_ctx, argv[0])) == NULL) {
3040 return NT_STATUS_NO_MEMORY;
3043 path = strchr(sharename, '=');
3045 return NT_STATUS_UNSUCCESSFUL;
3048 result = rpccli_srvsvc_net_share_add(pipe_hnd, mem_ctx, sharename, type,
3049 opt_comment, perms, opt_maxusers,
3050 num_users, path, password,
3052 return werror_to_ntstatus(result);
3055 static int rpc_share_add(int argc, const char **argv)
3057 if ((argc < 1) || !strchr(argv[0], '=')) {
3058 DEBUG(1,("Sharename or path not specified on add\n"));
3059 return rpc_share_usage(argc, argv);
3061 return run_rpc_command(NULL, PI_SRVSVC, 0,
3062 rpc_share_add_internals,
3067 * Delete a share on a remote RPC server
3069 * All parameters are provided by the run_rpc_command function, except for
3070 * argc, argv which are passes through.
3072 * @param domain_sid The domain sid acquired from the remote server
3073 * @param cli A cli_state connected to the server.
3074 * @param mem_ctx Talloc context, destoyed on completion of the function.
3075 * @param argc Standard main() style argc
3076 * @param argv Standard main() style argv. Initial components are already
3079 * @return Normal NTSTATUS return.
3081 static NTSTATUS rpc_share_del_internals(const DOM_SID *domain_sid,
3082 const char *domain_name,
3083 struct cli_state *cli,
3084 struct rpc_pipe_client *pipe_hnd,
3085 TALLOC_CTX *mem_ctx,
3091 result = rpccli_srvsvc_net_share_del(pipe_hnd, mem_ctx, argv[0]);
3092 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
3096 * Delete a share on a remote RPC server
3098 * @param domain_sid The domain sid acquired from the remote server
3099 * @param argc Standard main() style argc
3100 * @param argv Standard main() style argv. Initial components are already
3103 * @return A shell status integer (0 for success)
3105 static int rpc_share_delete(int argc, const char **argv)
3108 DEBUG(1,("Sharename not specified on delete\n"));
3109 return rpc_share_usage(argc, argv);
3111 return run_rpc_command(NULL, PI_SRVSVC, 0,
3112 rpc_share_del_internals,
3117 * Formatted print of share info
3119 * @param info1 pointer to SRV_SHARE_INFO_1 to format
3122 static void display_share_info_1(SRV_SHARE_INFO_1 *info1)
3124 fstring netname = "", remark = "";
3126 rpcstr_pull_unistr2_fstring(netname, &info1->info_1_str.uni_netname);
3127 rpcstr_pull_unistr2_fstring(remark, &info1->info_1_str.uni_remark);
3129 if (opt_long_list_entries) {
3130 d_printf("%-12s %-8.8s %-50s\n",
3131 netname, share_type[info1->info_1.type & ~(STYPE_TEMPORARY|STYPE_HIDDEN)], remark);
3133 d_printf("%s\n", netname);
3138 static WERROR get_share_info(struct rpc_pipe_client *pipe_hnd,
3139 TALLOC_CTX *mem_ctx,
3143 SRV_SHARE_INFO_CTR *ctr)
3146 SRV_SHARE_INFO info;
3148 /* no specific share requested, enumerate all */
3152 uint32 preferred_len = 0xffffffff;
3154 init_enum_hnd(&hnd, 0);
3156 return rpccli_srvsvc_net_share_enum(pipe_hnd, mem_ctx, level, ctr,
3157 preferred_len, &hnd);
3160 /* request just one share */
3161 result = rpccli_srvsvc_net_share_get_info(pipe_hnd, mem_ctx, argv[0], level, &info);
3163 if (!W_ERROR_IS_OK(result))
3169 ctr->info_level = ctr->switch_value = level;
3170 ctr->ptr_share_info = ctr->ptr_entries = 1;
3171 ctr->num_entries = ctr->num_entries2 = 1;
3177 SRV_SHARE_INFO_1 *info1;
3179 ctr->share.info1 = TALLOC_ARRAY(mem_ctx, SRV_SHARE_INFO_1, 1);
3180 if (ctr->share.info1 == NULL) {
3181 result = WERR_NOMEM;
3184 info1 = ctr->share.info1;
3186 memset(ctr->share.info1, 0, sizeof(SRV_SHARE_INFO_1));
3188 /* Copy pointer crap */
3190 memcpy(&info1->info_1, &info.share.info1.info_1, sizeof(SH_INFO_1));
3192 /* Duplicate strings */
3194 s = unistr2_to_ascii_talloc(mem_ctx, &info.share.info1.info_1_str.uni_netname);
3196 init_unistr2(&info1->info_1_str.uni_netname, s, UNI_STR_TERMINATE);
3198 s = unistr2_to_ascii_talloc(mem_ctx, &info.share.info1.info_1_str.uni_remark);
3200 init_unistr2(&info1->info_1_str.uni_remark, s, UNI_STR_TERMINATE);
3205 SRV_SHARE_INFO_2 *info2;
3207 ctr->share.info2 = TALLOC_ARRAY(mem_ctx, SRV_SHARE_INFO_2, 1);
3208 if (ctr->share.info2 == NULL) {
3209 result = WERR_NOMEM;
3212 info2 = ctr->share.info2;
3214 memset(ctr->share.info2, 0, sizeof(SRV_SHARE_INFO_2));
3216 /* Copy pointer crap */
3218 memcpy(&info2->info_2, &info.share.info2.info_2, sizeof(SH_INFO_2));
3220 /* Duplicate strings */
3222 s = unistr2_to_ascii_talloc(mem_ctx, &info.share.info2.info_2_str.uni_netname);
3224 init_unistr2(&info2->info_2_str.uni_netname, s, UNI_STR_TERMINATE);
3226 s = unistr2_to_ascii_talloc(mem_ctx, &info.share.info2.info_2_str.uni_remark);
3228 init_unistr2(&info2->info_2_str.uni_remark, s, UNI_STR_TERMINATE);
3230 s = unistr2_to_ascii_talloc(mem_ctx, &info.share.info2.info_2_str.uni_path);
3232 init_unistr2(&info2->info_2_str.uni_path, s, UNI_STR_TERMINATE);
3234 s = unistr2_to_ascii_talloc(mem_ctx, &info.share.info2.info_2_str.uni_passwd);
3236 init_unistr2(&info2->info_2_str.uni_passwd, s, UNI_STR_TERMINATE);
3241 SRV_SHARE_INFO_502 *info502;
3243 ctr->share.info502 = TALLOC_ARRAY(mem_ctx, SRV_SHARE_INFO_502, 1);
3244 if (ctr->share.info502 == NULL) {
3245 result = WERR_NOMEM;
3248 info502 = ctr->share.info502;
3250 memset(ctr->share.info502, 0, sizeof(SRV_SHARE_INFO_502));
3252 /* Copy pointer crap */
3254 memcpy(&info502->info_502, &info.share.info502.info_502, sizeof(SH_INFO_502));
3256 /* Duplicate strings */
3258 s = unistr2_to_ascii_talloc(mem_ctx, &info.share.info502.info_502_str.uni_netname);
3260 init_unistr2(&info502->info_502_str.uni_netname, s, UNI_STR_TERMINATE);
3262 s = unistr2_to_ascii_talloc(mem_ctx, &info.share.info502.info_502_str.uni_remark);
3264 init_unistr2(&info502->info_502_str.uni_remark, s, UNI_STR_TERMINATE);
3266 s = unistr2_to_ascii_talloc(mem_ctx, &info.share.info502.info_502_str.uni_path);
3268 init_unistr2(&info502->info_502_str.uni_path, s, UNI_STR_TERMINATE);
3270 s = unistr2_to_ascii_talloc(mem_ctx, &info.share.info502.info_502_str.uni_passwd);
3272 init_unistr2(&info502->info_502_str.uni_passwd, s, UNI_STR_TERMINATE);
3274 info502->info_502_str.sd = dup_sec_desc(mem_ctx, info.share.info502.info_502_str.sd);
3285 * List shares on a remote RPC server
3287 * All parameters are provided by the run_rpc_command function, except for
3288 * argc, argv which are passes through.
3290 * @param domain_sid The domain sid acquired from the remote server
3291 * @param cli A cli_state connected to the server.
3292 * @param mem_ctx Talloc context, destoyed on completion of the function.
3293 * @param argc Standard main() style argc
3294 * @param argv Standard main() style argv. Initial components are already
3297 * @return Normal NTSTATUS return.
3300 static NTSTATUS rpc_share_list_internals(const DOM_SID *domain_sid,
3301 const char *domain_name,
3302 struct cli_state *cli,
3303 struct rpc_pipe_client *pipe_hnd,
3304 TALLOC_CTX *mem_ctx,
3308 SRV_SHARE_INFO_CTR ctr;
3310 uint32 i, level = 1;
3312 result = get_share_info(pipe_hnd, mem_ctx, level, argc, argv, &ctr);
3313 if (!W_ERROR_IS_OK(result))
3316 /* Display results */
3318 if (opt_long_list_entries) {
3320 "\nEnumerating shared resources (exports) on remote server:\n\n"\
3321 "\nShare name Type Description\n"\
3322 "---------- ---- -----------\n");
3324 for (i = 0; i < ctr.num_entries; i++)
3325 display_share_info_1(&ctr.share.info1[i]);
3327 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
3331 * 'net rpc share list' entrypoint.
3332 * @param argc Standard main() style argc
3333 * @param argv Standard main() style argv. Initial components are already
3336 static int rpc_share_list(int argc, const char **argv)
3338 return run_rpc_command(NULL, PI_SRVSVC, 0, rpc_share_list_internals, argc, argv);
3341 static bool check_share_availability(struct cli_state *cli, const char *netname)
3343 if (!cli_send_tconX(cli, netname, "A:", "", 0)) {
3344 d_printf("skipping [%s]: not a file share.\n", netname);
3354 static bool check_share_sanity(struct cli_state *cli, fstring netname, uint32 type)
3356 /* only support disk shares */
3357 if (! ( type == STYPE_DISKTREE || type == (STYPE_DISKTREE | STYPE_HIDDEN)) ) {
3358 printf("share [%s] is not a diskshare (type: %x)\n", netname, type);
3362 /* skip builtin shares */
3363 /* FIXME: should print$ be added too ? */
3364 if (strequal(netname,"IPC$") || strequal(netname,"ADMIN$") ||
3365 strequal(netname,"global"))
3368 if (opt_exclude && in_list(netname, opt_exclude, False)) {
3369 printf("excluding [%s]\n", netname);
3373 return check_share_availability(cli, netname);
3377 * Migrate shares from a remote RPC server to the local RPC srever
3379 * All parameters are provided by the run_rpc_command function, except for
3380 * argc, argv which are passes through.
3382 * @param domain_sid The domain sid acquired from the remote server
3383 * @param cli A cli_state connected to the server.
3384 * @param mem_ctx Talloc context, destoyed on completion of the function.
3385 * @param argc Standard main() style argc
3386 * @param argv Standard main() style argv. Initial components are already
3389 * @return Normal NTSTATUS return.
3392 static NTSTATUS rpc_share_migrate_shares_internals(const DOM_SID *domain_sid,
3393 const char *domain_name,
3394 struct cli_state *cli,
3395 struct rpc_pipe_client *pipe_hnd,
3396 TALLOC_CTX *mem_ctx,
3401 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
3402 SRV_SHARE_INFO_CTR ctr_src;
3403 uint32 type = STYPE_DISKTREE; /* only allow disk shares to be added */
3404 char *password = NULL; /* don't allow a share password */
3406 struct rpc_pipe_client *srvsvc_pipe = NULL;
3407 struct cli_state *cli_dst = NULL;
3408 uint32 level = 502; /* includes secdesc */
3410 result = get_share_info(pipe_hnd, mem_ctx, level, argc, argv, &ctr_src);
3411 if (!W_ERROR_IS_OK(result))
3414 /* connect destination PI_SRVSVC */
3415 nt_status = connect_dst_pipe(&cli_dst, &srvsvc_pipe, PI_SRVSVC);
3416 if (!NT_STATUS_IS_OK(nt_status))
3420 for (i = 0; i < ctr_src.num_entries; i++) {
3422 fstring netname = "", remark = "", path = "";
3423 /* reset error-code */
3424 nt_status = NT_STATUS_UNSUCCESSFUL;
3426 rpcstr_pull_unistr2_fstring(
3427 netname, &ctr_src.share.info502[i].info_502_str.uni_netname);
3428 rpcstr_pull_unistr2_fstring(
3429 remark, &ctr_src.share.info502[i].info_502_str.uni_remark);
3430 rpcstr_pull_unistr2_fstring(
3431 path, &ctr_src.share.info502[i].info_502_str.uni_path);
3433 if (!check_share_sanity(cli, netname, ctr_src.share.info502[i].info_502.type))
3436 /* finally add the share on the dst server */
3438 printf("migrating: [%s], path: %s, comment: %s, without share-ACLs\n",
3439 netname, path, remark);
3441 result = rpccli_srvsvc_net_share_add(srvsvc_pipe, mem_ctx, netname, type, remark,
3442 ctr_src.share.info502[i].info_502.perms,
3443 ctr_src.share.info502[i].info_502.max_uses,
3444 ctr_src.share.info502[i].info_502.num_uses,
3445 path, password, level,
3448 if (W_ERROR_V(result) == W_ERROR_V(WERR_ALREADY_EXISTS)) {
3449 printf(" [%s] does already exist\n", netname);
3453 if (!W_ERROR_IS_OK(result)) {
3454 printf("cannot add share: %s\n", dos_errstr(result));
3460 nt_status = NT_STATUS_OK;
3464 cli_shutdown(cli_dst);
3472 * Migrate shares from a rpc-server to another
3474 * @param argc Standard main() style argc
3475 * @param argv Standard main() style argv. Initial components are already
3478 * @return A shell status integer (0 for success)
3480 static int rpc_share_migrate_shares(int argc, const char **argv)
3484 printf("no server to migrate\n");
3488 return run_rpc_command(NULL, PI_SRVSVC, 0,
3489 rpc_share_migrate_shares_internals,
3496 * @param f file_info
3497 * @param mask current search mask
3498 * @param state arg-pointer
3501 static void copy_fn(const char *mnt, file_info *f, const char *mask, void *state)
3503 static NTSTATUS nt_status;
3504 static struct copy_clistate *local_state;
3505 static fstring filename, new_mask;
3509 local_state = (struct copy_clistate *)state;
3510 nt_status = NT_STATUS_UNSUCCESSFUL;
3512 if (strequal(f->name, ".") || strequal(f->name, ".."))
3515 DEBUG(3,("got mask: %s, name: %s\n", mask, f->name));
3518 if (f->mode & aDIR) {
3520 DEBUG(3,("got dir: %s\n", f->name));
3522 fstrcpy(dir, local_state->cwd);
3524 fstrcat(dir, f->name);
3526 switch (net_mode_share)
3528 case NET_MODE_SHARE_MIGRATE:
3529 /* create that directory */
3530 nt_status = net_copy_file(local_state->mem_ctx,
3531 local_state->cli_share_src,
3532 local_state->cli_share_dst,
3534 opt_acls? True : False,
3535 opt_attrs? True : False,
3536 opt_timestamps? True : False,
3540 d_fprintf(stderr, "Unsupported mode %d\n", net_mode_share);
3544 if (!NT_STATUS_IS_OK(nt_status))
3545 printf("could not handle dir %s: %s\n",
3546 dir, nt_errstr(nt_status));
3548 /* search below that directory */
3549 fstrcpy(new_mask, dir);
3550 fstrcat(new_mask, "\\*");
3552 old_dir = local_state->cwd;
3553 local_state->cwd = dir;
3554 if (!sync_files(local_state, new_mask))
3555 printf("could not handle files\n");
3556 local_state->cwd = old_dir;
3563 fstrcpy(filename, local_state->cwd);
3564 fstrcat(filename, "\\");
3565 fstrcat(filename, f->name);
3567 DEBUG(3,("got file: %s\n", filename));
3569 switch (net_mode_share)
3571 case NET_MODE_SHARE_MIGRATE:
3572 nt_status = net_copy_file(local_state->mem_ctx,
3573 local_state->cli_share_src,
3574 local_state->cli_share_dst,
3576 opt_acls? True : False,
3577 opt_attrs? True : False,
3578 opt_timestamps? True: False,
3582 d_fprintf(stderr, "Unsupported file mode %d\n", net_mode_share);
3586 if (!NT_STATUS_IS_OK(nt_status))
3587 printf("could not handle file %s: %s\n",
3588 filename, nt_errstr(nt_status));
3593 * sync files, can be called recursivly to list files
3594 * and then call copy_fn for each file
3596 * @param cp_clistate pointer to the copy_clistate we work with
3597 * @param mask the current search mask
3599 * @return Boolean result
3601 static bool sync_files(struct copy_clistate *cp_clistate, const char *mask)
3603 struct cli_state *targetcli;
3604 char *targetpath = NULL;
3606 DEBUG(3,("calling cli_list with mask: %s\n", mask));
3608 if ( !cli_resolve_path(talloc_tos(), "", cp_clistate->cli_share_src,
3609 mask, &targetcli, &targetpath ) ) {
3610 d_fprintf(stderr, "cli_resolve_path %s failed with error: %s\n",
3611 mask, cli_errstr(cp_clistate->cli_share_src));
3615 if (cli_list(targetcli, targetpath, cp_clistate->attribute, copy_fn, cp_clistate) == -1) {
3616 d_fprintf(stderr, "listing %s failed with error: %s\n",
3617 mask, cli_errstr(targetcli));
3626 * Set the top level directory permissions before we do any further copies.
3627 * Should set up ACL inheritance.
3630 bool copy_top_level_perms(struct copy_clistate *cp_clistate,
3631 const char *sharename)
3633 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
3635 switch (net_mode_share) {
3636 case NET_MODE_SHARE_MIGRATE:
3637 DEBUG(3,("calling net_copy_fileattr for '.' directory in share %s\n", sharename));
3638 nt_status = net_copy_fileattr(cp_clistate->mem_ctx,
3639 cp_clistate->cli_share_src,
3640 cp_clistate->cli_share_dst,
3642 opt_acls? True : False,
3643 opt_attrs? True : False,
3644 opt_timestamps? True: False,
3648 d_fprintf(stderr, "Unsupported mode %d\n", net_mode_share);
3652 if (!NT_STATUS_IS_OK(nt_status)) {
3653 printf("Could handle directory attributes for top level directory of share %s. Error %s\n",
3654 sharename, nt_errstr(nt_status));
3662 * Sync all files inside a remote share to another share (over smb)
3664 * All parameters are provided by the run_rpc_command function, except for
3665 * argc, argv which are passes through.
3667 * @param domain_sid The domain sid acquired from the remote server
3668 * @param cli A cli_state connected to the server.
3669 * @param mem_ctx Talloc context, destoyed on completion of the function.
3670 * @param argc Standard main() style argc
3671 * @param argv Standard main() style argv. Initial components are already
3674 * @return Normal NTSTATUS return.
3677 static NTSTATUS rpc_share_migrate_files_internals(const DOM_SID *domain_sid,
3678 const char *domain_name,
3679 struct cli_state *cli,
3680 struct rpc_pipe_client *pipe_hnd,
3681 TALLOC_CTX *mem_ctx,
3686 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
3687 SRV_SHARE_INFO_CTR ctr_src;
3690 struct copy_clistate cp_clistate;
3691 bool got_src_share = False;
3692 bool got_dst_share = False;
3693 const char *mask = "\\*";
3696 dst = SMB_STRDUP(opt_destination?opt_destination:"127.0.0.1");
3698 result = get_share_info(pipe_hnd, mem_ctx, level, argc, argv, &ctr_src);
3700 if (!W_ERROR_IS_OK(result))
3703 for (i = 0; i < ctr_src.num_entries; i++) {
3705 fstring netname = "";
3707 rpcstr_pull_unistr2_fstring(
3708 netname, &ctr_src.share.info502[i].info_502_str.uni_netname);
3710 if (!check_share_sanity(cli, netname, ctr_src.share.info502[i].info_502.type))
3713 /* one might not want to mirror whole discs :) */
3714 if (strequal(netname, "print$") || netname[1] == '$') {
3715 d_printf("skipping [%s]: builtin/hidden share\n", netname);
3719 switch (net_mode_share)
3721 case NET_MODE_SHARE_MIGRATE:
3725 d_fprintf(stderr, "Unsupported mode %d\n", net_mode_share);
3728 printf(" [%s] files and directories %s ACLs, %s DOS Attributes %s\n",
3730 opt_acls ? "including" : "without",
3731 opt_attrs ? "including" : "without",
3732 opt_timestamps ? "(preserving timestamps)" : "");
3734 cp_clistate.mem_ctx = mem_ctx;
3735 cp_clistate.cli_share_src = NULL;
3736 cp_clistate.cli_share_dst = NULL;
3737 cp_clistate.cwd = NULL;
3738 cp_clistate.attribute = aSYSTEM | aHIDDEN | aDIR;
3740 /* open share source */
3741 nt_status = connect_to_service(&cp_clistate.cli_share_src,
3742 &cli->dest_ss, cli->desthost,
3744 if (!NT_STATUS_IS_OK(nt_status))
3747 got_src_share = True;
3749 if (net_mode_share == NET_MODE_SHARE_MIGRATE) {
3750 /* open share destination */
3751 nt_status = connect_to_service(&cp_clistate.cli_share_dst,
3752 NULL, dst, netname, "A:");
3753 if (!NT_STATUS_IS_OK(nt_status))
3756 got_dst_share = True;
3759 if (!copy_top_level_perms(&cp_clistate, netname)) {
3760 d_fprintf(stderr, "Could not handle the top level directory permissions for the share: %s\n", netname);
3761 nt_status = NT_STATUS_UNSUCCESSFUL;
3765 if (!sync_files(&cp_clistate, mask)) {
3766 d_fprintf(stderr, "could not handle files for share: %s\n", netname);
3767 nt_status = NT_STATUS_UNSUCCESSFUL;
3772 nt_status = NT_STATUS_OK;
3777 cli_shutdown(cp_clistate.cli_share_src);
3780 cli_shutdown(cp_clistate.cli_share_dst);
3786 static int rpc_share_migrate_files(int argc, const char **argv)
3790 printf("no server to migrate\n");
3794 return run_rpc_command(NULL, PI_SRVSVC, 0,
3795 rpc_share_migrate_files_internals,
3800 * Migrate share-ACLs from a remote RPC server to the local RPC srever
3802 * All parameters are provided by the run_rpc_command function, except for
3803 * argc, argv which are passes through.
3805 * @param domain_sid The domain sid acquired from the remote server
3806 * @param cli A cli_state connected to the server.
3807 * @param mem_ctx Talloc context, destoyed on completion of the function.
3808 * @param argc Standard main() style argc
3809 * @param argv Standard main() style argv. Initial components are already
3812 * @return Normal NTSTATUS return.
3815 static NTSTATUS rpc_share_migrate_security_internals(const DOM_SID *domain_sid,
3816 const char *domain_name,
3817 struct cli_state *cli,
3818 struct rpc_pipe_client *pipe_hnd,
3819 TALLOC_CTX *mem_ctx,
3824 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
3825 SRV_SHARE_INFO_CTR ctr_src;
3826 SRV_SHARE_INFO info;
3828 struct rpc_pipe_client *srvsvc_pipe = NULL;
3829 struct cli_state *cli_dst = NULL;
3830 uint32 level = 502; /* includes secdesc */
3832 result = get_share_info(pipe_hnd, mem_ctx, level, argc, argv, &ctr_src);
3834 if (!W_ERROR_IS_OK(result))
3837 /* connect destination PI_SRVSVC */
3838 nt_status = connect_dst_pipe(&cli_dst, &srvsvc_pipe, PI_SRVSVC);
3839 if (!NT_STATUS_IS_OK(nt_status))
3843 for (i = 0; i < ctr_src.num_entries; i++) {
3845 fstring netname = "", remark = "", path = "";
3846 /* reset error-code */
3847 nt_status = NT_STATUS_UNSUCCESSFUL;
3849 rpcstr_pull_unistr2_fstring(
3850 netname, &ctr_src.share.info502[i].info_502_str.uni_netname);
3851 rpcstr_pull_unistr2_fstring(
3852 remark, &ctr_src.share.info502[i].info_502_str.uni_remark);
3853 rpcstr_pull_unistr2_fstring(
3854 path, &ctr_src.share.info502[i].info_502_str.uni_path);
3856 if (!check_share_sanity(cli, netname, ctr_src.share.info502[i].info_502.type))
3859 printf("migrating: [%s], path: %s, comment: %s, including share-ACLs\n",
3860 netname, path, remark);
3863 display_sec_desc(ctr_src.share.info502[i].info_502_str.sd);
3868 info.switch_value = level;
3869 info.ptr_share_ctr = 1;
3871 /* FIXME: shouldn't we be able to just set the security descriptor ? */
3872 info.share.info502 = ctr_src.share.info502[i];
3874 /* finally modify the share on the dst server */
3875 result = rpccli_srvsvc_net_share_set_info(srvsvc_pipe, mem_ctx, netname, level, &info);
3877 if (!W_ERROR_IS_OK(result)) {
3878 printf("cannot set share-acl: %s\n", dos_errstr(result));
3884 nt_status = NT_STATUS_OK;
3888 cli_shutdown(cli_dst);
3896 * Migrate share-acls from a rpc-server to another
3898 * @param argc Standard main() style argc
3899 * @param argv Standard main() style argv. Initial components are already
3902 * @return A shell status integer (0 for success)
3904 static int rpc_share_migrate_security(int argc, const char **argv)
3908 printf("no server to migrate\n");
3912 return run_rpc_command(NULL, PI_SRVSVC, 0,
3913 rpc_share_migrate_security_internals,
3918 * Migrate shares (including share-definitions, share-acls and files with acls/attrs)
3919 * from one server to another
3921 * @param argc Standard main() style argc
3922 * @param argv Standard main() style argv. Initial components are already
3925 * @return A shell status integer (0 for success)
3928 static int rpc_share_migrate_all(int argc, const char **argv)
3933 printf("no server to migrate\n");
3937 /* order is important. we don't want to be locked out by the share-acl
3938 * before copying files - gd */
3940 ret = run_rpc_command(NULL, PI_SRVSVC, 0, rpc_share_migrate_shares_internals, argc, argv);
3944 ret = run_rpc_command(NULL, PI_SRVSVC, 0, rpc_share_migrate_files_internals, argc, argv);
3948 return run_rpc_command(NULL, PI_SRVSVC, 0, rpc_share_migrate_security_internals, argc, argv);
3953 * 'net rpc share migrate' entrypoint.
3954 * @param argc Standard main() style argc
3955 * @param argv Standard main() style argv. Initial components are already
3958 static int rpc_share_migrate(int argc, const char **argv)
3961 struct functable func[] = {
3962 {"all", rpc_share_migrate_all},
3963 {"files", rpc_share_migrate_files},
3964 {"help", rpc_share_usage},
3965 {"security", rpc_share_migrate_security},
3966 {"shares", rpc_share_migrate_shares},
3970 net_mode_share = NET_MODE_SHARE_MIGRATE;
3972 return net_run_function(argc, argv, func, rpc_share_usage);
3981 static int num_server_aliases;
3982 static struct full_alias *server_aliases;
3985 * Add an alias to the static list.
3987 static void push_alias(TALLOC_CTX *mem_ctx, struct full_alias *alias)
3989 if (server_aliases == NULL)
3990 server_aliases = SMB_MALLOC_ARRAY(struct full_alias, 100);
3992 server_aliases[num_server_aliases] = *alias;
3993 num_server_aliases += 1;
3997 * For a specific domain on the server, fetch all the aliases
3998 * and their members. Add all of them to the server_aliases.
4001 static NTSTATUS rpc_fetch_domain_aliases(struct rpc_pipe_client *pipe_hnd,
4002 TALLOC_CTX *mem_ctx,
4003 POLICY_HND *connect_pol,
4004 const DOM_SID *domain_sid)
4006 uint32 start_idx, max_entries, num_entries, i;
4007 struct acct_info *groups;
4009 POLICY_HND domain_pol;
4011 /* Get domain policy handle */
4013 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, connect_pol,
4014 MAXIMUM_ALLOWED_ACCESS,
4015 domain_sid, &domain_pol);
4016 if (!NT_STATUS_IS_OK(result))
4023 result = rpccli_samr_enum_als_groups(pipe_hnd, mem_ctx, &domain_pol,
4024 &start_idx, max_entries,
4025 &groups, &num_entries);
4027 for (i = 0; i < num_entries; i++) {
4029 POLICY_HND alias_pol;
4030 struct full_alias alias;
4034 result = rpccli_samr_open_alias(pipe_hnd, mem_ctx, &domain_pol,
4035 MAXIMUM_ALLOWED_ACCESS,
4038 if (!NT_STATUS_IS_OK(result))
4041 result = rpccli_samr_query_aliasmem(pipe_hnd, mem_ctx,
4045 if (!NT_STATUS_IS_OK(result))
4048 result = rpccli_samr_close(pipe_hnd, mem_ctx, &alias_pol);
4049 if (!NT_STATUS_IS_OK(result))
4052 alias.members = NULL;
4054 if (alias.num_members > 0) {
4055 alias.members = SMB_MALLOC_ARRAY(DOM_SID, alias.num_members);
4057 for (j = 0; j < alias.num_members; j++)
4058 sid_copy(&alias.members[j],
4062 sid_copy(&alias.sid, domain_sid);
4063 sid_append_rid(&alias.sid, groups[i].rid);
4065 push_alias(mem_ctx, &alias);
4067 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
4069 result = NT_STATUS_OK;
4072 rpccli_samr_close(pipe_hnd, mem_ctx, &domain_pol);
4078 * Dump server_aliases as names for debugging purposes.
4081 static NTSTATUS rpc_aliaslist_dump(const DOM_SID *domain_sid,
4082 const char *domain_name,
4083 struct cli_state *cli,
4084 struct rpc_pipe_client *pipe_hnd,
4085 TALLOC_CTX *mem_ctx,
4093 result = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, True,
4094 SEC_RIGHTS_MAXIMUM_ALLOWED,
4096 if (!NT_STATUS_IS_OK(result))
4099 for (i=0; i<num_server_aliases; i++) {
4102 enum lsa_SidType *types;
4105 struct full_alias *alias = &server_aliases[i];
4107 result = rpccli_lsa_lookup_sids(pipe_hnd, mem_ctx, &lsa_pol, 1,
4109 &domains, &names, &types);
4110 if (!NT_STATUS_IS_OK(result))
4113 DEBUG(1, ("%s\\%s %d: ", domains[0], names[0], types[0]));
4115 if (alias->num_members == 0) {
4120 result = rpccli_lsa_lookup_sids(pipe_hnd, mem_ctx, &lsa_pol,
4123 &domains, &names, &types);
4125 if (!NT_STATUS_IS_OK(result) &&
4126 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
4129 for (j=0; j<alias->num_members; j++)
4130 DEBUG(1, ("%s\\%s (%d); ",
4131 domains[j] ? domains[j] : "*unknown*",
4132 names[j] ? names[j] : "*unknown*",types[j]));
4136 rpccli_lsa_Close(pipe_hnd, mem_ctx, &lsa_pol);
4138 return NT_STATUS_OK;
4142 * Fetch a list of all server aliases and their members into
4146 static NTSTATUS rpc_aliaslist_internals(const DOM_SID *domain_sid,
4147 const char *domain_name,
4148 struct cli_state *cli,
4149 struct rpc_pipe_client *pipe_hnd,
4150 TALLOC_CTX *mem_ctx,
4155 POLICY_HND connect_pol;
4157 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
4160 if (!NT_STATUS_IS_OK(result))
4163 result = rpc_fetch_domain_aliases(pipe_hnd, mem_ctx, &connect_pol,
4164 &global_sid_Builtin);
4166 if (!NT_STATUS_IS_OK(result))
4169 result = rpc_fetch_domain_aliases(pipe_hnd, mem_ctx, &connect_pol,
4172 rpccli_samr_close(pipe_hnd, mem_ctx, &connect_pol);
4177 static void init_user_token(NT_USER_TOKEN *token, DOM_SID *user_sid)
4179 token->num_sids = 4;
4181 if (!(token->user_sids = SMB_MALLOC_ARRAY(DOM_SID, 4))) {
4182 d_fprintf(stderr, "malloc failed\n");
4183 token->num_sids = 0;
4187 token->user_sids[0] = *user_sid;
4188 sid_copy(&token->user_sids[1], &global_sid_World);
4189 sid_copy(&token->user_sids[2], &global_sid_Network);
4190 sid_copy(&token->user_sids[3], &global_sid_Authenticated_Users);
4193 static void free_user_token(NT_USER_TOKEN *token)
4195 SAFE_FREE(token->user_sids);
4198 static bool is_sid_in_token(NT_USER_TOKEN *token, DOM_SID *sid)
4202 for (i=0; i<token->num_sids; i++) {
4203 if (sid_compare(sid, &token->user_sids[i]) == 0)
4209 static void add_sid_to_token(NT_USER_TOKEN *token, DOM_SID *sid)
4211 if (is_sid_in_token(token, sid))
4214 token->user_sids = SMB_REALLOC_ARRAY(token->user_sids, DOM_SID, token->num_sids+1);
4215 if (!token->user_sids) {
4219 sid_copy(&token->user_sids[token->num_sids], sid);
4221 token->num_sids += 1;
4226 NT_USER_TOKEN token;
4229 static void dump_user_token(struct user_token *token)
4233 d_printf("%s\n", token->name);
4235 for (i=0; i<token->token.num_sids; i++) {
4236 d_printf(" %s\n", sid_string_tos(&token->token.user_sids[i]));
4240 static bool is_alias_member(DOM_SID *sid, struct full_alias *alias)
4244 for (i=0; i<alias->num_members; i++) {
4245 if (sid_compare(sid, &alias->members[i]) == 0)
4252 static void collect_sid_memberships(NT_USER_TOKEN *token, DOM_SID sid)
4256 for (i=0; i<num_server_aliases; i++) {
4257 if (is_alias_member(&sid, &server_aliases[i]))
4258 add_sid_to_token(token, &server_aliases[i].sid);
4263 * We got a user token with all the SIDs we can know about without asking the
4264 * server directly. These are the user and domain group sids. All of these can
4265 * be members of aliases. So scan the list of aliases for each of the SIDs and
4266 * add them to the token.
4269 static void collect_alias_memberships(NT_USER_TOKEN *token)
4271 int num_global_sids = token->num_sids;
4274 for (i=0; i<num_global_sids; i++) {
4275 collect_sid_memberships(token, token->user_sids[i]);
4279 static bool get_user_sids(const char *domain, const char *user, NT_USER_TOKEN *token)
4281 struct winbindd_request request;
4282 struct winbindd_response response;
4290 fstr_sprintf(full_name, "%s%c%s",
4291 domain, *lp_winbind_separator(), user);
4293 /* First let's find out the user sid */
4295 ZERO_STRUCT(request);
4296 ZERO_STRUCT(response);
4298 fstrcpy(request.data.name.dom_name, domain);
4299 fstrcpy(request.data.name.name, user);
4301 result = winbindd_request_response(WINBINDD_LOOKUPNAME, &request, &response);
4303 if (result != NSS_STATUS_SUCCESS) {
4304 DEBUG(1, ("winbind could not find %s\n", full_name));
4308 if (response.data.sid.type != SID_NAME_USER) {
4309 DEBUG(1, ("%s is not a user\n", full_name));
4313 string_to_sid(&user_sid, response.data.sid.sid);
4315 init_user_token(token, &user_sid);
4317 /* And now the groups winbind knows about */
4319 ZERO_STRUCT(response);
4321 fstrcpy(request.data.username, full_name);
4323 result = winbindd_request_response(WINBINDD_GETGROUPS, &request, &response);
4325 if (result != NSS_STATUS_SUCCESS) {
4326 DEBUG(1, ("winbind could not get groups of %s\n", full_name));
4330 for (i = 0; i < response.data.num_entries; i++) {
4331 gid_t gid = ((gid_t *)response.extra_data.data)[i];
4334 struct winbindd_request sidrequest;
4335 struct winbindd_response sidresponse;
4337 ZERO_STRUCT(sidrequest);
4338 ZERO_STRUCT(sidresponse);
4340 sidrequest.data.gid = gid;
4342 result = winbindd_request_response(WINBINDD_GID_TO_SID,
4343 &sidrequest, &sidresponse);
4345 if (result != NSS_STATUS_SUCCESS) {
4346 DEBUG(1, ("winbind could not find SID of gid %d\n",
4351 DEBUG(3, (" %s\n", sidresponse.data.sid.sid));
4353 string_to_sid(&sid, sidresponse.data.sid.sid);
4354 add_sid_to_token(token, &sid);
4357 SAFE_FREE(response.extra_data.data);
4363 * Get a list of all user tokens we want to look at
4366 static bool get_user_tokens(int *num_tokens, struct user_token **user_tokens)
4368 struct winbindd_request request;
4369 struct winbindd_response response;
4370 const char *extra_data;
4373 struct user_token *result;
4374 TALLOC_CTX *frame = NULL;
4376 if (lp_winbind_use_default_domain() &&
4377 (opt_target_workgroup == NULL)) {
4378 d_fprintf(stderr, "winbind use default domain = yes set, "
4379 "please specify a workgroup\n");
4383 /* Send request to winbind daemon */
4385 ZERO_STRUCT(request);
4386 ZERO_STRUCT(response);
4388 if (winbindd_request_response(WINBINDD_LIST_USERS, &request, &response) !=
4392 /* Look through extra data */
4394 if (!response.extra_data.data)
4397 extra_data = (const char *)response.extra_data.data;
4400 frame = talloc_stackframe();
4401 while(next_token_talloc(frame, &extra_data, &name, ",")) {
4405 result = SMB_MALLOC_ARRAY(struct user_token, *num_tokens);
4407 if (result == NULL) {
4408 DEBUG(1, ("Could not malloc sid array\n"));
4413 extra_data = (const char *)response.extra_data.data;
4416 while(next_token_talloc(frame, &extra_data, &name, ",")) {
4417 fstring domain, user;
4420 fstrcpy(result[i].name, name);
4422 p = strchr(name, *lp_winbind_separator());
4424 DEBUG(3, ("%s\n", name));
4427 fstrcpy(domain, opt_target_workgroup);
4428 fstrcpy(user, name);
4431 fstrcpy(domain, name);
4436 get_user_sids(domain, user, &(result[i].token));
4440 SAFE_FREE(response.extra_data.data);
4442 *user_tokens = result;
4447 static bool get_user_tokens_from_file(FILE *f,
4449 struct user_token **tokens)
4451 struct user_token *token = NULL;
4456 if (fgets(line, sizeof(line)-1, f) == NULL) {
4460 if (line[strlen(line)-1] == '\n')
4461 line[strlen(line)-1] = '\0';
4463 if (line[0] == ' ') {
4467 string_to_sid(&sid, &line[1]);
4469 if (token == NULL) {
4470 DEBUG(0, ("File does not begin with username"));
4474 add_sid_to_token(&token->token, &sid);
4478 /* And a new user... */
4481 *tokens = SMB_REALLOC_ARRAY(*tokens, struct user_token, *num_tokens);
4482 if (*tokens == NULL) {
4483 DEBUG(0, ("Could not realloc tokens\n"));
4487 token = &((*tokens)[*num_tokens-1]);
4489 fstrcpy(token->name, line);
4490 token->token.num_sids = 0;
4491 token->token.user_sids = NULL;
4500 * Show the list of all users that have access to a share
4503 static void show_userlist(struct rpc_pipe_client *pipe_hnd,
4504 TALLOC_CTX *mem_ctx,
4505 const char *netname,
4507 struct user_token *tokens)
4510 SEC_DESC *share_sd = NULL;
4511 SEC_DESC *root_sd = NULL;
4512 struct cli_state *cli = pipe_hnd->cli;
4514 SRV_SHARE_INFO info;
4518 result = rpccli_srvsvc_net_share_get_info(pipe_hnd, mem_ctx, netname,
4521 if (!W_ERROR_IS_OK(result)) {
4522 DEBUG(1, ("Coult not query secdesc for share %s\n",
4527 share_sd = info.share.info502.info_502_str.sd;
4528 if (share_sd == NULL) {
4529 DEBUG(1, ("Got no secdesc for share %s\n",
4535 if (!cli_send_tconX(cli, netname, "A:", "", 0)) {
4539 fnum = cli_nt_create(cli, "\\", READ_CONTROL_ACCESS);
4542 root_sd = cli_query_secdesc(cli, fnum, mem_ctx);
4545 for (i=0; i<num_tokens; i++) {
4549 if (share_sd != NULL) {
4550 if (!se_access_check(share_sd, &tokens[i].token,
4551 1, &acc_granted, &status)) {
4552 DEBUG(1, ("Could not check share_sd for "
4558 if (!NT_STATUS_IS_OK(status))
4562 if (root_sd == NULL) {
4563 d_printf(" %s\n", tokens[i].name);
4567 if (!se_access_check(root_sd, &tokens[i].token,
4568 1, &acc_granted, &status)) {
4569 DEBUG(1, ("Could not check root_sd for user %s\n",
4574 if (!NT_STATUS_IS_OK(status))
4577 d_printf(" %s\n", tokens[i].name);
4581 cli_close(cli, fnum);
4593 static void collect_share(const char *name, uint32 m,
4594 const char *comment, void *state)
4596 struct share_list *share_list = (struct share_list *)state;
4598 if (m != STYPE_DISKTREE)
4601 share_list->num_shares += 1;
4602 share_list->shares = SMB_REALLOC_ARRAY(share_list->shares, char *, share_list->num_shares);
4603 if (!share_list->shares) {
4604 share_list->num_shares = 0;
4607 share_list->shares[share_list->num_shares-1] = SMB_STRDUP(name);
4610 static void rpc_share_userlist_usage(void)
4616 * List shares on a remote RPC server, including the security descriptors
4618 * All parameters are provided by the run_rpc_command function, except for
4619 * argc, argv which are passes through.
4621 * @param domain_sid The domain sid acquired from the remote server
4622 * @param cli A cli_state connected to the server.
4623 * @param mem_ctx Talloc context, destoyed on completion of the function.
4624 * @param argc Standard main() style argc
4625 * @param argv Standard main() style argv. Initial components are already
4628 * @return Normal NTSTATUS return.
4631 static NTSTATUS rpc_share_allowedusers_internals(const DOM_SID *domain_sid,
4632 const char *domain_name,
4633 struct cli_state *cli,
4634 struct rpc_pipe_client *pipe_hnd,
4635 TALLOC_CTX *mem_ctx,
4645 struct user_token *tokens = NULL;
4648 struct share_list share_list;
4651 rpc_share_userlist_usage();
4652 return NT_STATUS_UNSUCCESSFUL;
4658 f = fopen(argv[0], "r");
4662 DEBUG(0, ("Could not open userlist: %s\n", strerror(errno)));
4663 return NT_STATUS_UNSUCCESSFUL;
4666 r = get_user_tokens_from_file(f, &num_tokens, &tokens);
4672 DEBUG(0, ("Could not read users from file\n"));
4673 return NT_STATUS_UNSUCCESSFUL;
4676 for (i=0; i<num_tokens; i++)
4677 collect_alias_memberships(&tokens[i].token);
4679 init_enum_hnd(&hnd, 0);
4681 share_list.num_shares = 0;
4682 share_list.shares = NULL;
4684 ret = cli_RNetShareEnum(cli, collect_share, &share_list);
4687 DEBUG(0, ("Error returning browse list: %s\n",
4692 for (i = 0; i < share_list.num_shares; i++) {
4693 char *netname = share_list.shares[i];
4695 if (netname[strlen(netname)-1] == '$')
4698 d_printf("%s\n", netname);
4700 show_userlist(pipe_hnd, mem_ctx, netname,
4701 num_tokens, tokens);
4704 for (i=0; i<num_tokens; i++) {
4705 free_user_token(&tokens[i].token);
4708 SAFE_FREE(share_list.shares);
4710 return NT_STATUS_OK;
4713 static int rpc_share_allowedusers(int argc, const char **argv)
4717 result = run_rpc_command(NULL, PI_SAMR, 0,
4718 rpc_aliaslist_internals,
4723 result = run_rpc_command(NULL, PI_LSARPC, 0,
4729 return run_rpc_command(NULL, PI_SRVSVC, 0,
4730 rpc_share_allowedusers_internals,
4734 int net_usersidlist(int argc, const char **argv)
4737 struct user_token *tokens = NULL;
4741 net_usersidlist_usage(argc, argv);
4745 if (!get_user_tokens(&num_tokens, &tokens)) {
4746 DEBUG(0, ("Could not get the user/sid list\n"));
4750 for (i=0; i<num_tokens; i++) {
4751 dump_user_token(&tokens[i]);
4752 free_user_token(&tokens[i].token);
4759 int net_usersidlist_usage(int argc, const char **argv)
4761 d_printf("net usersidlist\n"
4762 "\tprints out a list of all users the running winbind knows\n"
4763 "\tabout, together with all their SIDs. This is used as\n"
4764 "\tinput to the 'net rpc share allowedusers' command.\n\n");
4766 net_common_flags_usage(argc, argv);
4771 * 'net rpc share' entrypoint.
4772 * @param argc Standard main() style argc
4773 * @param argv Standard main() style argv. Initial components are already
4777 int net_rpc_share(int argc, const char **argv)
4779 struct functable func[] = {
4780 {"add", rpc_share_add},
4781 {"delete", rpc_share_delete},
4782 {"allowedusers", rpc_share_allowedusers},
4783 {"migrate", rpc_share_migrate},
4784 {"list", rpc_share_list},
4789 return run_rpc_command(NULL, PI_SRVSVC, 0,
4790 rpc_share_list_internals,
4793 return net_run_function(argc, argv, func, rpc_share_usage);
4796 static NTSTATUS rpc_sh_share_list(TALLOC_CTX *mem_ctx,
4797 struct rpc_sh_ctx *ctx,
4798 struct rpc_pipe_client *pipe_hnd,
4799 int argc, const char **argv)
4801 return rpc_share_list_internals(ctx->domain_sid, ctx->domain_name,
4802 ctx->cli, pipe_hnd, mem_ctx,
4806 static NTSTATUS rpc_sh_share_add(TALLOC_CTX *mem_ctx,
4807 struct rpc_sh_ctx *ctx,
4808 struct rpc_pipe_client *pipe_hnd,
4809 int argc, const char **argv)
4813 if ((argc < 2) || (argc > 3)) {
4814 d_fprintf(stderr, "usage: %s <share> <path> [comment]\n",
4816 return NT_STATUS_INVALID_PARAMETER;
4819 result = rpccli_srvsvc_net_share_add(
4820 pipe_hnd, mem_ctx, argv[0], STYPE_DISKTREE,
4821 (argc == 3) ? argv[2] : "",
4822 0, 0, 0, argv[1], NULL, 2, NULL);
4824 return werror_to_ntstatus(result);
4827 static NTSTATUS rpc_sh_share_delete(TALLOC_CTX *mem_ctx,
4828 struct rpc_sh_ctx *ctx,
4829 struct rpc_pipe_client *pipe_hnd,
4830 int argc, const char **argv)
4835 d_fprintf(stderr, "usage: %s <share>\n", ctx->whoami);
4836 return NT_STATUS_INVALID_PARAMETER;
4839 result = rpccli_srvsvc_net_share_del(pipe_hnd, mem_ctx, argv[0]);
4840 return werror_to_ntstatus(result);
4843 static NTSTATUS rpc_sh_share_info(TALLOC_CTX *mem_ctx,
4844 struct rpc_sh_ctx *ctx,
4845 struct rpc_pipe_client *pipe_hnd,
4846 int argc, const char **argv)
4848 SRV_SHARE_INFO info;
4849 SRV_SHARE_INFO_2 *info2 = &info.share.info2;
4853 d_fprintf(stderr, "usage: %s <share>\n", ctx->whoami);
4854 return NT_STATUS_INVALID_PARAMETER;
4857 result = rpccli_srvsvc_net_share_get_info(
4858 pipe_hnd, mem_ctx, argv[0], 2, &info);
4859 if (!W_ERROR_IS_OK(result)) {
4863 d_printf("Name: %s\n",
4864 rpcstr_pull_unistr2_talloc(mem_ctx,
4865 &info2->info_2_str.uni_netname));
4866 d_printf("Comment: %s\n",
4867 rpcstr_pull_unistr2_talloc(mem_ctx,
4868 &info2->info_2_str.uni_remark));
4870 d_printf("Path: %s\n",
4871 rpcstr_pull_unistr2_talloc(mem_ctx,
4872 &info2->info_2_str.uni_path));
4873 d_printf("Password: %s\n",
4874 rpcstr_pull_unistr2_talloc(mem_ctx,
4875 &info2->info_2_str.uni_passwd));
4878 return werror_to_ntstatus(result);
4881 struct rpc_sh_cmd *net_rpc_share_cmds(TALLOC_CTX *mem_ctx,
4882 struct rpc_sh_ctx *ctx)
4884 static struct rpc_sh_cmd cmds[] = {
4886 { "list", NULL, PI_SRVSVC, rpc_sh_share_list,
4887 "List available shares" },
4889 { "add", NULL, PI_SRVSVC, rpc_sh_share_add,
4892 { "delete", NULL, PI_SRVSVC, rpc_sh_share_delete,
4895 { "info", NULL, PI_SRVSVC, rpc_sh_share_info,
4896 "Get information about a share" },
4898 { NULL, NULL, 0, NULL, NULL }
4904 /****************************************************************************/
4906 static int rpc_file_usage(int argc, const char **argv)
4908 return net_help_file(argc, argv);
4912 * Close a file on a remote RPC server
4914 * All parameters are provided by the run_rpc_command function, except for
4915 * argc, argv which are passes through.
4917 * @param domain_sid The domain sid acquired from the remote server
4918 * @param cli A cli_state connected to the server.
4919 * @param mem_ctx Talloc context, destoyed on completion of the function.
4920 * @param argc Standard main() style argc
4921 * @param argv Standard main() style argv. Initial components are already
4924 * @return Normal NTSTATUS return.
4926 static NTSTATUS rpc_file_close_internals(const DOM_SID *domain_sid,
4927 const char *domain_name,
4928 struct cli_state *cli,
4929 struct rpc_pipe_client *pipe_hnd,
4930 TALLOC_CTX *mem_ctx,
4934 return rpccli_srvsvc_NetFileClose(pipe_hnd, mem_ctx,
4935 pipe_hnd->cli->desthost,
4936 atoi(argv[0]), NULL);
4940 * Close a file on a remote RPC server
4942 * @param argc Standard main() style argc
4943 * @param argv Standard main() style argv. Initial components are already
4946 * @return A shell status integer (0 for success)
4948 static int rpc_file_close(int argc, const char **argv)
4951 DEBUG(1, ("No fileid given on close\n"));
4952 return(rpc_file_usage(argc, argv));
4955 return run_rpc_command(NULL, PI_SRVSVC, 0,
4956 rpc_file_close_internals,
4961 * Formatted print of open file info
4963 * @param info3 FILE_INFO_3 contents
4964 * @param str3 strings for FILE_INFO_3
4967 static void display_file_info_3( FILE_INFO_3 *info3 )
4969 fstring user = "", path = "";
4971 rpcstr_pull_unistr2_fstring(user, info3->user);
4972 rpcstr_pull_unistr2_fstring(path, info3->path);
4974 d_printf("%-7.1d %-20.20s 0x%-4.2x %-6.1d %s\n",
4975 info3->id, user, info3->perms, info3->num_locks, path);
4979 * List open files on a remote RPC server
4981 * All parameters are provided by the run_rpc_command function, except for
4982 * argc, argv which are passes through.
4984 * @param domain_sid The domain sid acquired from the remote server
4985 * @param cli A cli_state connected to the server.
4986 * @param mem_ctx Talloc context, destoyed on completion of the function.
4987 * @param argc Standard main() style argc
4988 * @param argv Standard main() style argv. Initial components are already
4991 * @return Normal NTSTATUS return.
4994 static NTSTATUS rpc_file_list_internals(const DOM_SID *domain_sid,
4995 const char *domain_name,
4996 struct cli_state *cli,
4997 struct rpc_pipe_client *pipe_hnd,
4998 TALLOC_CTX *mem_ctx,
5002 SRV_FILE_INFO_CTR ctr;
5005 uint32 preferred_len = 0xffffffff, i;
5006 const char *username=NULL;
5008 init_enum_hnd(&hnd, 0);
5010 /* if argc > 0, must be user command */
5012 username = smb_xstrdup(argv[0]);
5014 result = rpccli_srvsvc_net_file_enum(pipe_hnd,
5015 mem_ctx, 3, username, &ctr, preferred_len, &hnd);
5017 if (!W_ERROR_IS_OK(result))
5020 /* Display results */
5023 "\nEnumerating open files on remote server:\n\n"\
5024 "\nFileId Opened by Perms Locks Path"\
5025 "\n------ --------- ----- ----- ---- \n");
5026 for (i = 0; i < ctr.num_entries; i++)
5027 display_file_info_3(&ctr.file.info3[i]);
5029 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
5033 * List files for a user on a remote RPC server
5035 * @param argc Standard main() style argc
5036 * @param argv Standard main() style argv. Initial components are already
5039 * @return A shell status integer (0 for success)
5042 static int rpc_file_user(int argc, const char **argv)
5045 DEBUG(1, ("No username given\n"));
5046 return(rpc_file_usage(argc, argv));
5049 return run_rpc_command(NULL, PI_SRVSVC, 0,
5050 rpc_file_list_internals,
5055 * 'net rpc file' entrypoint.
5056 * @param argc Standard main() style argc
5057 * @param argv Standard main() style argv. Initial components are already
5061 int net_rpc_file(int argc, const char **argv)
5063 struct functable func[] = {
5064 {"close", rpc_file_close},
5065 {"user", rpc_file_user},
5067 {"info", rpc_file_info},
5073 return run_rpc_command(NULL, PI_SRVSVC, 0,
5074 rpc_file_list_internals,
5077 return net_run_function(argc, argv, func, rpc_file_usage);
5081 * ABORT the shutdown of a remote RPC Server over, initshutdown pipe
5083 * All parameters are provided by the run_rpc_command function, except for
5084 * argc, argv which are passed through.
5086 * @param domain_sid The domain sid aquired from the remote server
5087 * @param cli A cli_state connected to the server.
5088 * @param mem_ctx Talloc context, destoyed on compleation of the function.
5089 * @param argc Standard main() style argc
5090 * @param argv Standard main() style argv. Initial components are already
5093 * @return Normal NTSTATUS return.
5096 static NTSTATUS rpc_shutdown_abort_internals(const DOM_SID *domain_sid,
5097 const char *domain_name,
5098 struct cli_state *cli,
5099 struct rpc_pipe_client *pipe_hnd,
5100 TALLOC_CTX *mem_ctx,
5104 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
5106 result = rpccli_initshutdown_Abort(pipe_hnd, mem_ctx, NULL, NULL);
5108 if (NT_STATUS_IS_OK(result)) {
5109 d_printf("\nShutdown successfully aborted\n");
5110 DEBUG(5,("cmd_shutdown_abort: query succeeded\n"));
5112 DEBUG(5,("cmd_shutdown_abort: query failed\n"));
5118 * ABORT the shutdown of a remote RPC Server, over winreg pipe
5120 * All parameters are provided by the run_rpc_command function, except for
5121 * argc, argv which are passed through.
5123 * @param domain_sid The domain sid aquired from the remote server
5124 * @param cli A cli_state connected to the server.
5125 * @param mem_ctx Talloc context, destoyed on compleation of the function.
5126 * @param argc Standard main() style argc
5127 * @param argv Standard main() style argv. Initial components are already
5130 * @return Normal NTSTATUS return.
5133 static NTSTATUS rpc_reg_shutdown_abort_internals(const DOM_SID *domain_sid,
5134 const char *domain_name,
5135 struct cli_state *cli,
5136 struct rpc_pipe_client *pipe_hnd,
5137 TALLOC_CTX *mem_ctx,
5141 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
5143 result = rpccli_winreg_AbortSystemShutdown(pipe_hnd, mem_ctx, NULL, NULL);
5145 if (NT_STATUS_IS_OK(result)) {
5146 d_printf("\nShutdown successfully aborted\n");
5147 DEBUG(5,("cmd_reg_abort_shutdown: query succeeded\n"));
5149 DEBUG(5,("cmd_reg_abort_shutdown: query failed\n"));
5155 * ABORT the Shut down of a remote RPC server
5157 * @param argc Standard main() style argc
5158 * @param argv Standard main() style argv. Initial components are already
5161 * @return A shell status integer (0 for success)
5164 static int rpc_shutdown_abort(int argc, const char **argv)
5166 int rc = run_rpc_command(NULL, PI_INITSHUTDOWN, 0,
5167 rpc_shutdown_abort_internals,
5173 DEBUG(1, ("initshutdown pipe didn't work, trying winreg pipe\n"));
5175 return run_rpc_command(NULL, PI_WINREG, 0,
5176 rpc_reg_shutdown_abort_internals,
5181 * Shut down a remote RPC Server via initshutdown pipe
5183 * All parameters are provided by the run_rpc_command function, except for
5184 * argc, argv which are passes through.
5186 * @param domain_sid The domain sid aquired from the remote server
5187 * @param cli A cli_state connected to the server.
5188 * @param mem_ctx Talloc context, destoyed on compleation of the function.
5189 * @param argc Standard main() style argc
5190 * @param argc Standard main() style argv. Initial components are already
5193 * @return Normal NTSTATUS return.
5196 NTSTATUS rpc_init_shutdown_internals(const DOM_SID *domain_sid,
5197 const char *domain_name,
5198 struct cli_state *cli,
5199 struct rpc_pipe_client *pipe_hnd,
5200 TALLOC_CTX *mem_ctx,
5204 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
5205 const char *msg = "This machine will be shutdown shortly";
5206 uint32 timeout = 20;
5207 struct initshutdown_String msg_string;
5208 struct initshutdown_String_sub s;
5214 timeout = opt_timeout;
5218 msg_string.name = &s;
5220 /* create an entry */
5221 result = rpccli_initshutdown_Init(pipe_hnd, mem_ctx, NULL,
5222 &msg_string, timeout, opt_force, opt_reboot, NULL);
5224 if (NT_STATUS_IS_OK(result)) {
5225 d_printf("\nShutdown of remote machine succeeded\n");
5226 DEBUG(5,("Shutdown of remote machine succeeded\n"));
5228 DEBUG(1,("Shutdown of remote machine failed!\n"));
5234 * Shut down a remote RPC Server via winreg pipe
5236 * All parameters are provided by the run_rpc_command function, except for
5237 * argc, argv which are passes through.
5239 * @param domain_sid The domain sid aquired from the remote server
5240 * @param cli A cli_state connected to the server.
5241 * @param mem_ctx Talloc context, destoyed on compleation of the function.
5242 * @param argc Standard main() style argc
5243 * @param argc Standard main() style argv. Initial components are already
5246 * @return Normal NTSTATUS return.
5249 NTSTATUS rpc_reg_shutdown_internals(const DOM_SID *domain_sid,
5250 const char *domain_name,
5251 struct cli_state *cli,
5252 struct rpc_pipe_client *pipe_hnd,
5253 TALLOC_CTX *mem_ctx,
5257 const char *msg = "This machine will be shutdown shortly";
5258 uint32 timeout = 20;
5259 struct initshutdown_String msg_string;
5260 struct initshutdown_String_sub s;
5268 msg_string.name = &s;
5271 timeout = opt_timeout;
5274 /* create an entry */
5275 result = rpccli_winreg_InitiateSystemShutdown(pipe_hnd, mem_ctx, NULL,
5276 &msg_string, timeout, opt_force, opt_reboot, &werr);
5278 if (NT_STATUS_IS_OK(result)) {
5279 d_printf("\nShutdown of remote machine succeeded\n");
5281 d_fprintf(stderr, "\nShutdown of remote machine failed\n");
5282 if ( W_ERROR_EQUAL(werr, WERR_MACHINE_LOCKED) )
5283 d_fprintf(stderr, "\nMachine locked, use -f switch to force\n");
5285 d_fprintf(stderr, "\nresult was: %s\n", dos_errstr(werr));
5292 * Shut down a remote RPC server
5294 * @param argc Standard main() style argc
5295 * @param argc Standard main() style argv. Initial components are already
5298 * @return A shell status integer (0 for success)
5301 static int rpc_shutdown(int argc, const char **argv)
5303 int rc = run_rpc_command(NULL, PI_INITSHUTDOWN, 0,
5304 rpc_init_shutdown_internals,
5308 DEBUG(1, ("initshutdown pipe failed, trying winreg pipe\n"));
5309 rc = run_rpc_command(NULL, PI_WINREG, 0,
5310 rpc_reg_shutdown_internals, argc, argv);
5316 /***************************************************************************
5317 NT Domain trusts code (i.e. 'net rpc trustdom' functionality)
5319 ***************************************************************************/
5322 * Add interdomain trust account to the RPC server.
5323 * All parameters (except for argc and argv) are passed by run_rpc_command
5326 * @param domain_sid The domain sid acquired from the server
5327 * @param cli A cli_state connected to the server.
5328 * @param mem_ctx Talloc context, destoyed on completion of the function.
5329 * @param argc Standard main() style argc
5330 * @param argc Standard main() style argv. Initial components are already
5333 * @return normal NTSTATUS return code
5336 static NTSTATUS rpc_trustdom_add_internals(const DOM_SID *domain_sid,
5337 const char *domain_name,
5338 struct cli_state *cli,
5339 struct rpc_pipe_client *pipe_hnd,
5340 TALLOC_CTX *mem_ctx,
5344 POLICY_HND connect_pol, domain_pol, user_pol;
5345 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
5348 uint32 acct_flags=0;
5352 d_printf("Usage: net rpc trustdom add <domain_name> <pw>\n");
5353 return NT_STATUS_INVALID_PARAMETER;
5357 * Make valid trusting domain account (ie. uppercased and with '$' appended)
5360 if (asprintf(&acct_name, "%s$", argv[0]) < 0) {
5361 return NT_STATUS_NO_MEMORY;
5364 strupper_m(acct_name);
5366 /* Get samr policy handle */
5367 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
5369 if (!NT_STATUS_IS_OK(result)) {
5373 /* Get domain policy handle */
5374 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
5375 MAXIMUM_ALLOWED_ACCESS,
5376 domain_sid, &domain_pol);
5377 if (!NT_STATUS_IS_OK(result)) {
5381 /* Create trusting domain's account */
5382 acb_info = ACB_NORMAL;
5383 acct_flags = SEC_GENERIC_READ | SEC_GENERIC_WRITE | SEC_GENERIC_EXECUTE |
5384 SEC_STD_WRITE_DAC | SEC_STD_DELETE |
5385 SAMR_USER_ACCESS_SET_PASSWORD |
5386 SAMR_USER_ACCESS_GET_ATTRIBUTES |
5387 SAMR_USER_ACCESS_SET_ATTRIBUTES;
5389 result = rpccli_samr_create_dom_user(pipe_hnd, mem_ctx, &domain_pol,
5390 acct_name, acb_info, acct_flags,
5391 &user_pol, &user_rid);
5392 if (!NT_STATUS_IS_OK(result)) {
5397 SAM_USERINFO_CTR ctr;
5398 SAM_USER_INFO_23 p23;
5404 encode_pw_buffer(pwbuf, argv[1], STR_UNICODE);
5408 ZERO_STRUCT(notime);
5412 memset(hrs.hours, 0xFF, sizeof(hrs.hours));
5413 acb_info = ACB_DOMTRUST;
5415 init_sam_user_info23A(&p23, ¬ime, ¬ime, ¬ime,
5416 ¬ime, ¬ime, ¬ime,
5417 nostr, nostr, nostr, nostr, nostr,
5418 nostr, nostr, nostr, nostr, nostr,
5419 0, 0, acb_info, ACCT_FLAGS, 168, &hrs,
5420 0, 0, (char *)pwbuf);
5421 ctr.switch_value = 23;
5422 ctr.info.id23 = &p23;
5423 p23.passmustchange = 0;
5425 result = rpccli_samr_set_userinfo(pipe_hnd, mem_ctx, &user_pol, 23,
5426 &cli->user_session_key, &ctr);
5428 if (!NT_STATUS_IS_OK(result)) {
5429 DEBUG(0,("Could not set trust account password: %s\n",
5430 nt_errstr(result)));
5436 SAFE_FREE(acct_name);
5441 * Create interdomain trust account for a remote domain.
5443 * @param argc standard argc
5444 * @param argv standard argv without initial components
5446 * @return Integer status (0 means success)
5449 static int rpc_trustdom_add(int argc, const char **argv)
5452 return run_rpc_command(NULL, PI_SAMR, 0, rpc_trustdom_add_internals,
5455 d_printf("Usage: net rpc trustdom add <domain>\n");
5462 * Remove interdomain trust account from the RPC server.
5463 * All parameters (except for argc and argv) are passed by run_rpc_command
5466 * @param domain_sid The domain sid acquired from the server
5467 * @param cli A cli_state connected to the server.
5468 * @param mem_ctx Talloc context, destoyed on completion of the function.
5469 * @param argc Standard main() style argc
5470 * @param argc Standard main() style argv. Initial components are already
5473 * @return normal NTSTATUS return code
5476 static NTSTATUS rpc_trustdom_del_internals(const DOM_SID *domain_sid,
5477 const char *domain_name,
5478 struct cli_state *cli,
5479 struct rpc_pipe_client *pipe_hnd,
5480 TALLOC_CTX *mem_ctx,
5484 POLICY_HND connect_pol, domain_pol, user_pol;
5485 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
5488 DOM_SID trust_acct_sid;
5489 uint32 *user_rids, num_rids, *name_types;
5490 uint32 flags = 0x000003e8; /* Unknown */
5493 d_printf("Usage: net rpc trustdom del <domain_name>\n");
5494 return NT_STATUS_INVALID_PARAMETER;
5498 * Make valid trusting domain account (ie. uppercased and with '$' appended)
5500 acct_name = talloc_asprintf(mem_ctx, "%s$", argv[0]);
5502 if (acct_name == NULL)
5503 return NT_STATUS_NO_MEMORY;
5505 strupper_m(acct_name);
5507 if ((names = TALLOC_ARRAY(mem_ctx, const char *, 1)) == NULL) {
5508 return NT_STATUS_NO_MEMORY;
5510 names[0] = acct_name;
5513 /* Get samr policy handle */
5514 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
5516 if (!NT_STATUS_IS_OK(result)) {
5520 /* Get domain policy handle */
5521 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
5522 MAXIMUM_ALLOWED_ACCESS,
5523 domain_sid, &domain_pol);
5524 if (!NT_STATUS_IS_OK(result)) {
5528 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, flags, 1,
5530 &user_rids, &name_types);
5532 if (!NT_STATUS_IS_OK(result)) {
5536 result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
5537 MAXIMUM_ALLOWED_ACCESS,
5538 user_rids[0], &user_pol);
5540 if (!NT_STATUS_IS_OK(result)) {
5544 /* append the rid to the domain sid */
5545 sid_copy(&trust_acct_sid, domain_sid);
5546 if (!sid_append_rid(&trust_acct_sid, user_rids[0])) {
5550 /* remove the sid */
5552 result = rpccli_samr_remove_sid_foreign_domain(pipe_hnd, mem_ctx, &user_pol,
5555 if (!NT_STATUS_IS_OK(result)) {
5561 result = rpccli_samr_delete_dom_user(pipe_hnd, mem_ctx, &user_pol);
5563 if (!NT_STATUS_IS_OK(result)) {
5567 if (!NT_STATUS_IS_OK(result)) {
5568 DEBUG(0,("Could not set trust account password: %s\n",
5569 nt_errstr(result)));
5578 * Delete interdomain trust account for a remote domain.
5580 * @param argc standard argc
5581 * @param argv standard argv without initial components
5583 * @return Integer status (0 means success)
5586 static int rpc_trustdom_del(int argc, const char **argv)
5589 return run_rpc_command(NULL, PI_SAMR, 0, rpc_trustdom_del_internals,
5592 d_printf("Usage: net rpc trustdom del <domain>\n");
5599 * Establish trust relationship to a trusting domain.
5600 * Interdomain account must already be created on remote PDC.
5602 * @param argc standard argc
5603 * @param argv standard argv without initial components
5605 * @return Integer status (0 means success)
5608 static int rpc_trustdom_establish(int argc, const char **argv)
5610 struct cli_state *cli = NULL;
5611 struct sockaddr_storage server_ss;
5612 struct rpc_pipe_client *pipe_hnd = NULL;
5613 POLICY_HND connect_hnd;
5614 TALLOC_CTX *mem_ctx;
5616 DOM_SID *domain_sid;
5619 const char* domain_name_pol;
5625 * Connect to \\server\ipc$ as 'our domain' account with password
5629 d_printf("Usage: net rpc trustdom establish <domain_name>\n");
5633 domain_name = smb_xstrdup(argv[0]);
5634 strupper_m(domain_name);
5636 /* account name used at first is our domain's name with '$' */
5637 asprintf(&acct_name, "%s$", lp_workgroup());
5638 strupper_m(acct_name);
5641 * opt_workgroup will be used by connection functions further,
5642 * hence it should be set to remote domain name instead of ours
5644 if (opt_workgroup) {
5645 opt_workgroup = smb_xstrdup(domain_name);
5648 opt_user_name = acct_name;
5650 /* find the domain controller */
5651 if (!net_find_pdc(&server_ss, pdc_name, domain_name)) {
5652 DEBUG(0, ("Couldn't find domain controller for domain %s\n", domain_name));
5656 /* connect to ipc$ as username/password */
5657 nt_status = connect_to_ipc(&cli, &server_ss, pdc_name);
5658 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT)) {
5660 /* Is it trusting domain account for sure ? */
5661 DEBUG(0, ("Couldn't verify trusting domain account. Error was %s\n",
5662 nt_errstr(nt_status)));
5666 /* store who we connected to */
5668 saf_store( domain_name, pdc_name );
5671 * Connect to \\server\ipc$ again (this time anonymously)
5674 nt_status = connect_to_ipc_anonymous(&cli, &server_ss, (char*)pdc_name);
5676 if (NT_STATUS_IS_ERR(nt_status)) {
5677 DEBUG(0, ("Couldn't connect to domain %s controller. Error was %s.\n",
5678 domain_name, nt_errstr(nt_status)));
5683 * Use NetServerEnum2 to make sure we're talking to a proper server
5686 if (!cli_get_pdc_name(cli, domain_name, &dc_name)) {
5687 DEBUG(0, ("NetServerEnum2 error: Couldn't find primary domain controller\
5688 for domain %s\n", domain_name));
5694 if (!(mem_ctx = talloc_init("establishing trust relationship to "
5695 "domain %s", domain_name))) {
5696 DEBUG(0, ("talloc_init() failed\n"));
5702 * Call LsaOpenPolicy and LsaQueryInfo
5705 pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_LSARPC, &nt_status);
5707 DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n", nt_errstr(nt_status) ));
5709 talloc_destroy(mem_ctx);
5713 nt_status = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, True, SEC_RIGHTS_QUERY_VALUE,
5715 if (NT_STATUS_IS_ERR(nt_status)) {
5716 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
5717 nt_errstr(nt_status)));
5719 talloc_destroy(mem_ctx);
5723 /* Querying info level 5 */
5725 nt_status = rpccli_lsa_query_info_policy(pipe_hnd, mem_ctx, &connect_hnd,
5727 &domain_name_pol, &domain_sid);
5728 if (NT_STATUS_IS_ERR(nt_status)) {
5729 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
5730 nt_errstr(nt_status)));
5732 talloc_destroy(mem_ctx);
5736 /* There should be actually query info level 3 (following nt serv behaviour),
5737 but I still don't know if it's _really_ necessary */
5740 * Store the password in secrets db
5743 if (!pdb_set_trusteddom_pw(domain_name, opt_password, domain_sid)) {
5744 DEBUG(0, ("Storing password for trusted domain failed.\n"));
5746 talloc_destroy(mem_ctx);
5751 * Close the pipes and clean up
5754 nt_status = rpccli_lsa_Close(pipe_hnd, mem_ctx, &connect_hnd);
5755 if (NT_STATUS_IS_ERR(nt_status)) {
5756 DEBUG(0, ("Couldn't close LSA pipe. Error was %s\n",
5757 nt_errstr(nt_status)));
5759 talloc_destroy(mem_ctx);
5765 talloc_destroy(mem_ctx);
5767 d_printf("Trust to domain %s established\n", domain_name);
5772 * Revoke trust relationship to the remote domain
5774 * @param argc standard argc
5775 * @param argv standard argv without initial components
5777 * @return Integer status (0 means success)
5780 static int rpc_trustdom_revoke(int argc, const char **argv)
5785 if (argc < 1) return -1;
5787 /* generate upper cased domain name */
5788 domain_name = smb_xstrdup(argv[0]);
5789 strupper_m(domain_name);
5791 /* delete password of the trust */
5792 if (!pdb_del_trusteddom_pw(domain_name)) {
5793 DEBUG(0, ("Failed to revoke relationship to the trusted domain %s\n",
5800 SAFE_FREE(domain_name);
5805 * Usage for 'net rpc trustdom' command
5807 * @param argc standard argc
5808 * @param argv standard argv without inital components
5810 * @return Integer status returned to shell
5813 static int rpc_trustdom_usage(int argc, const char **argv)
5815 d_printf(" net rpc trustdom add \t\t add trusting domain's account\n");
5816 d_printf(" net rpc trustdom del \t\t delete trusting domain's account\n");
5817 d_printf(" net rpc trustdom establish \t establish relationship to trusted domain\n");
5818 d_printf(" net rpc trustdom revoke \t abandon relationship to trusted domain\n");
5819 d_printf(" net rpc trustdom list \t show current interdomain trust relationships\n");
5820 d_printf(" net rpc trustdom vampire \t vampire interdomain trust relationships from remote server\n");
5825 static NTSTATUS rpc_query_domain_sid(const DOM_SID *domain_sid,
5826 const char *domain_name,
5827 struct cli_state *cli,
5828 struct rpc_pipe_client *pipe_hnd,
5829 TALLOC_CTX *mem_ctx,
5834 sid_to_fstring(str_sid, domain_sid);
5835 d_printf("%s\n", str_sid);
5836 return NT_STATUS_OK;
5839 static void print_trusted_domain(DOM_SID *dom_sid, const char *trusted_dom_name)
5841 fstring ascii_sid, padding;
5842 int pad_len, col_len = 20;
5844 /* convert sid into ascii string */
5845 sid_to_fstring(ascii_sid, dom_sid);
5847 /* calculate padding space for d_printf to look nicer */
5848 pad_len = col_len - strlen(trusted_dom_name);
5849 padding[pad_len] = 0;
5850 do padding[--pad_len] = ' '; while (pad_len);
5852 d_printf("%s%s%s\n", trusted_dom_name, padding, ascii_sid);
5855 static NTSTATUS vampire_trusted_domain(struct rpc_pipe_client *pipe_hnd,
5856 TALLOC_CTX *mem_ctx,
5859 const char *trusted_dom_name)
5862 union lsa_TrustedDomainInfo info;
5863 char *cleartextpwd = NULL;
5866 nt_status = rpccli_lsa_QueryTrustedDomainInfoBySid(pipe_hnd, mem_ctx,
5869 LSA_TRUSTED_DOMAIN_INFO_PASSWORD,
5871 if (NT_STATUS_IS_ERR(nt_status)) {
5872 DEBUG(0,("Could not query trusted domain info. Error was %s\n",
5873 nt_errstr(nt_status)));
5877 data = data_blob(NULL, info.password.password->length);
5880 info.password.password->data,
5881 info.password.password->length);
5882 data.length = info.password.password->length;
5884 cleartextpwd = decrypt_trustdom_secret(pipe_hnd->cli->pwd.password,
5887 if (cleartextpwd == NULL) {
5888 DEBUG(0,("retrieved NULL password\n"));
5889 nt_status = NT_STATUS_UNSUCCESSFUL;
5893 if (!pdb_set_trusteddom_pw(trusted_dom_name, cleartextpwd, &dom_sid)) {
5894 DEBUG(0, ("Storing password for trusted domain failed.\n"));
5895 nt_status = NT_STATUS_UNSUCCESSFUL;
5899 #ifdef DEBUG_PASSWORD
5900 DEBUG(100,("sucessfully vampired trusted domain [%s], sid: [%s], "
5901 "password: [%s]\n", trusted_dom_name,
5902 sid_string_dbg(&dom_sid), cleartextpwd));
5906 SAFE_FREE(cleartextpwd);
5907 data_blob_free(&data);
5912 static int rpc_trustdom_vampire(int argc, const char **argv)
5914 /* common variables */
5915 TALLOC_CTX* mem_ctx;
5916 struct cli_state *cli = NULL;
5917 struct rpc_pipe_client *pipe_hnd = NULL;
5919 const char *domain_name = NULL;
5920 DOM_SID *queried_dom_sid;
5921 POLICY_HND connect_hnd;
5923 /* trusted domains listing variables */
5924 unsigned int num_domains, enum_ctx = 0;
5926 DOM_SID *domain_sids;
5927 char **trusted_dom_names;
5932 * Listing trusted domains (stored in secrets.tdb, if local)
5935 mem_ctx = talloc_init("trust relationships vampire");
5938 * set domain and pdc name to local samba server (default)
5939 * or to remote one given in command line
5942 if (StrCaseCmp(opt_workgroup, lp_workgroup())) {
5943 domain_name = opt_workgroup;
5944 opt_target_workgroup = opt_workgroup;
5946 fstrcpy(pdc_name, global_myname());
5947 domain_name = talloc_strdup(mem_ctx, lp_workgroup());
5948 opt_target_workgroup = domain_name;
5951 /* open \PIPE\lsarpc and open policy handle */
5952 nt_status = net_make_ipc_connection(NET_FLAGS_PDC, &cli);
5953 if (!NT_STATUS_IS_OK(nt_status)) {
5954 DEBUG(0, ("Couldn't connect to domain controller: %s\n",
5955 nt_errstr(nt_status)));
5956 talloc_destroy(mem_ctx);
5960 pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_LSARPC, &nt_status);
5962 DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n",
5963 nt_errstr(nt_status) ));
5965 talloc_destroy(mem_ctx);
5969 nt_status = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, False, SEC_RIGHTS_QUERY_VALUE,
5971 if (NT_STATUS_IS_ERR(nt_status)) {
5972 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
5973 nt_errstr(nt_status)));
5975 talloc_destroy(mem_ctx);
5979 /* query info level 5 to obtain sid of a domain being queried */
5980 nt_status = rpccli_lsa_query_info_policy(
5981 pipe_hnd, mem_ctx, &connect_hnd, 5 /* info level */,
5982 &dummy, &queried_dom_sid);
5984 if (NT_STATUS_IS_ERR(nt_status)) {
5985 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
5986 nt_errstr(nt_status)));
5988 talloc_destroy(mem_ctx);
5993 * Keep calling LsaEnumTrustdom over opened pipe until
5994 * the end of enumeration is reached
5997 d_printf("Vampire trusted domains:\n\n");
6000 nt_status = rpccli_lsa_enum_trust_dom(pipe_hnd, mem_ctx, &connect_hnd, &enum_ctx,
6002 &trusted_dom_names, &domain_sids);
6004 if (NT_STATUS_IS_ERR(nt_status)) {
6005 DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
6006 nt_errstr(nt_status)));
6008 talloc_destroy(mem_ctx);
6012 for (i = 0; i < num_domains; i++) {
6014 print_trusted_domain(&(domain_sids[i]), trusted_dom_names[i]);
6016 nt_status = vampire_trusted_domain(pipe_hnd, mem_ctx, &connect_hnd,
6017 domain_sids[i], trusted_dom_names[i]);
6018 if (!NT_STATUS_IS_OK(nt_status)) {
6020 talloc_destroy(mem_ctx);
6026 * in case of no trusted domains say something rather
6027 * than just display blank line
6029 if (!num_domains) d_printf("none\n");
6031 } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
6033 /* close this connection before doing next one */
6034 nt_status = rpccli_lsa_Close(pipe_hnd, mem_ctx, &connect_hnd);
6035 if (NT_STATUS_IS_ERR(nt_status)) {
6036 DEBUG(0, ("Couldn't properly close lsa policy handle. Error was %s\n",
6037 nt_errstr(nt_status)));
6039 talloc_destroy(mem_ctx);
6043 /* close lsarpc pipe and connection to IPC$ */
6046 talloc_destroy(mem_ctx);
6050 static int rpc_trustdom_list(int argc, const char **argv)
6052 /* common variables */
6053 TALLOC_CTX* mem_ctx;
6054 struct cli_state *cli = NULL, *remote_cli = NULL;
6055 struct rpc_pipe_client *pipe_hnd = NULL;
6057 const char *domain_name = NULL;
6058 DOM_SID *queried_dom_sid;
6060 int ascii_dom_name_len;
6061 POLICY_HND connect_hnd;
6063 /* trusted domains listing variables */
6064 unsigned int num_domains, enum_ctx = 0;
6065 int i, pad_len, col_len = 20;
6066 DOM_SID *domain_sids;
6067 char **trusted_dom_names;
6071 /* trusting domains listing variables */
6072 POLICY_HND domain_hnd;
6073 char **trusting_dom_names;
6074 uint32 *trusting_dom_rids;
6077 * Listing trusted domains (stored in secrets.tdb, if local)
6080 mem_ctx = talloc_init("trust relationships listing");
6083 * set domain and pdc name to local samba server (default)
6084 * or to remote one given in command line
6087 if (StrCaseCmp(opt_workgroup, lp_workgroup())) {
6088 domain_name = opt_workgroup;
6089 opt_target_workgroup = opt_workgroup;
6091 fstrcpy(pdc_name, global_myname());
6092 domain_name = talloc_strdup(mem_ctx, lp_workgroup());
6093 opt_target_workgroup = domain_name;
6096 /* open \PIPE\lsarpc and open policy handle */
6097 nt_status = net_make_ipc_connection(NET_FLAGS_PDC, &cli);
6098 if (!NT_STATUS_IS_OK(nt_status)) {
6099 DEBUG(0, ("Couldn't connect to domain controller: %s\n",
6100 nt_errstr(nt_status)));
6101 talloc_destroy(mem_ctx);
6105 pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_LSARPC, &nt_status);
6107 DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n",
6108 nt_errstr(nt_status) ));
6110 talloc_destroy(mem_ctx);
6114 nt_status = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, False, SEC_RIGHTS_QUERY_VALUE,
6116 if (NT_STATUS_IS_ERR(nt_status)) {
6117 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
6118 nt_errstr(nt_status)));
6120 talloc_destroy(mem_ctx);
6124 /* query info level 5 to obtain sid of a domain being queried */
6125 nt_status = rpccli_lsa_query_info_policy(
6126 pipe_hnd, mem_ctx, &connect_hnd, 5 /* info level */,
6127 &dummy, &queried_dom_sid);
6129 if (NT_STATUS_IS_ERR(nt_status)) {
6130 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
6131 nt_errstr(nt_status)));
6133 talloc_destroy(mem_ctx);
6138 * Keep calling LsaEnumTrustdom over opened pipe until
6139 * the end of enumeration is reached
6142 d_printf("Trusted domains list:\n\n");
6145 nt_status = rpccli_lsa_enum_trust_dom(pipe_hnd, mem_ctx, &connect_hnd, &enum_ctx,
6147 &trusted_dom_names, &domain_sids);
6149 if (NT_STATUS_IS_ERR(nt_status)) {
6150 DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
6151 nt_errstr(nt_status)));
6153 talloc_destroy(mem_ctx);
6157 for (i = 0; i < num_domains; i++) {
6158 print_trusted_domain(&(domain_sids[i]), trusted_dom_names[i]);
6162 * in case of no trusted domains say something rather
6163 * than just display blank line
6165 if (!num_domains) d_printf("none\n");
6167 } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
6169 /* close this connection before doing next one */
6170 nt_status = rpccli_lsa_Close(pipe_hnd, mem_ctx, &connect_hnd);
6171 if (NT_STATUS_IS_ERR(nt_status)) {
6172 DEBUG(0, ("Couldn't properly close lsa policy handle. Error was %s\n",
6173 nt_errstr(nt_status)));
6175 talloc_destroy(mem_ctx);
6179 cli_rpc_pipe_close(pipe_hnd);
6182 * Listing trusting domains (stored in passdb backend, if local)
6185 d_printf("\nTrusting domains list:\n\n");
6188 * Open \PIPE\samr and get needed policy handles
6190 pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SAMR, &nt_status);
6192 DEBUG(0, ("Could not initialise samr pipe. Error was %s\n", nt_errstr(nt_status)));
6194 talloc_destroy(mem_ctx);
6199 nt_status = rpccli_samr_connect(pipe_hnd, mem_ctx, SA_RIGHT_SAM_OPEN_DOMAIN,
6201 if (!NT_STATUS_IS_OK(nt_status)) {
6202 DEBUG(0, ("Couldn't open SAMR policy handle. Error was %s\n",
6203 nt_errstr(nt_status)));
6205 talloc_destroy(mem_ctx);
6209 /* SamrOpenDomain - we have to open domain policy handle in order to be
6210 able to enumerate accounts*/
6211 nt_status = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_hnd,
6212 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
6213 queried_dom_sid, &domain_hnd);
6214 if (!NT_STATUS_IS_OK(nt_status)) {
6215 DEBUG(0, ("Couldn't open domain object. Error was %s\n",
6216 nt_errstr(nt_status)));
6218 talloc_destroy(mem_ctx);
6223 * perform actual enumeration
6226 enum_ctx = 0; /* reset enumeration context from last enumeration */
6229 nt_status = rpccli_samr_enum_dom_users(pipe_hnd, mem_ctx, &domain_hnd,
6230 &enum_ctx, ACB_DOMTRUST, 0xffff,
6231 &trusting_dom_names, &trusting_dom_rids,
6233 if (NT_STATUS_IS_ERR(nt_status)) {
6234 DEBUG(0, ("Couldn't enumerate accounts. Error was: %s\n",
6235 nt_errstr(nt_status)));
6237 talloc_destroy(mem_ctx);
6241 for (i = 0; i < num_domains; i++) {
6244 * get each single domain's sid (do we _really_ need this ?):
6245 * 1) connect to domain's pdc
6246 * 2) query the pdc for domain's sid
6249 /* get rid of '$' tail */
6250 ascii_dom_name_len = strlen(trusting_dom_names[i]);
6251 if (ascii_dom_name_len && ascii_dom_name_len < FSTRING_LEN)
6252 trusting_dom_names[i][ascii_dom_name_len - 1] = '\0';
6254 /* calculate padding space for d_printf to look nicer */
6255 pad_len = col_len - strlen(trusting_dom_names[i]);
6256 padding[pad_len] = 0;
6257 do padding[--pad_len] = ' '; while (pad_len);
6259 /* set opt_* variables to remote domain */
6260 strupper_m(trusting_dom_names[i]);
6261 opt_workgroup = talloc_strdup(mem_ctx, trusting_dom_names[i]);
6262 opt_target_workgroup = opt_workgroup;
6264 d_printf("%s%s", trusting_dom_names[i], padding);
6266 /* connect to remote domain controller */
6267 nt_status = net_make_ipc_connection(
6268 NET_FLAGS_PDC | NET_FLAGS_ANONYMOUS,
6270 if (NT_STATUS_IS_OK(nt_status)) {
6271 /* query for domain's sid */
6272 if (run_rpc_command(remote_cli, PI_LSARPC, 0, rpc_query_domain_sid, argc, argv))
6273 d_fprintf(stderr, "couldn't get domain's sid\n");
6275 cli_shutdown(remote_cli);
6278 d_fprintf(stderr, "domain controller is not "
6280 nt_errstr(nt_status));
6284 if (!num_domains) d_printf("none\n");
6286 } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
6288 /* close opened samr and domain policy handles */
6289 nt_status = rpccli_samr_close(pipe_hnd, mem_ctx, &domain_hnd);
6290 if (!NT_STATUS_IS_OK(nt_status)) {
6291 DEBUG(0, ("Couldn't properly close domain policy handle for domain %s\n", domain_name));
6294 nt_status = rpccli_samr_close(pipe_hnd, mem_ctx, &connect_hnd);
6295 if (!NT_STATUS_IS_OK(nt_status)) {
6296 DEBUG(0, ("Couldn't properly close samr policy handle for domain %s\n", domain_name));
6299 /* close samr pipe and connection to IPC$ */
6302 talloc_destroy(mem_ctx);
6307 * Entrypoint for 'net rpc trustdom' code
6309 * @param argc standard argc
6310 * @param argv standard argv without initial components
6312 * @return Integer status (0 means success)
6315 static int rpc_trustdom(int argc, const char **argv)
6317 struct functable func[] = {
6318 {"add", rpc_trustdom_add},
6319 {"del", rpc_trustdom_del},
6320 {"establish", rpc_trustdom_establish},
6321 {"revoke", rpc_trustdom_revoke},
6322 {"help", rpc_trustdom_usage},
6323 {"list", rpc_trustdom_list},
6324 {"vampire", rpc_trustdom_vampire},
6329 rpc_trustdom_usage(argc, argv);
6333 return (net_run_function(argc, argv, func, rpc_user_usage));
6337 * Check if a server will take rpc commands
6338 * @param flags Type of server to connect to (PDC, DMB, localhost)
6339 * if the host is not explicitly specified
6340 * @return bool (true means rpc supported)
6342 bool net_rpc_check(unsigned flags)
6344 struct cli_state *cli;
6346 struct sockaddr_storage server_ss;
6347 char *server_name = NULL;
6350 /* flags (i.e. server type) may depend on command */
6351 if (!net_find_server(NULL, flags, &server_ss, &server_name))
6354 if ((cli = cli_initialise()) == NULL) {
6358 status = cli_connect(cli, server_name, &server_ss);
6359 if (!NT_STATUS_IS_OK(status))
6361 if (!attempt_netbios_session_request(&cli, global_myname(),
6362 server_name, &server_ss))
6364 if (!cli_negprot(cli))
6366 if (cli->protocol < PROTOCOL_NT1)
6375 /* dump sam database via samsync rpc calls */
6376 static int rpc_samdump(int argc, const char **argv) {
6377 return run_rpc_command(NULL, PI_NETLOGON, NET_FLAGS_ANONYMOUS, rpc_samdump_internals,
6381 /* syncronise sam database via samsync rpc calls */
6382 static int rpc_vampire(int argc, const char **argv) {
6383 return run_rpc_command(NULL, PI_NETLOGON, NET_FLAGS_ANONYMOUS, rpc_vampire_internals,
6388 * Migrate everything from a print-server
6390 * @param argc Standard main() style argc
6391 * @param argv Standard main() style argv. Initial components are already
6394 * @return A shell status integer (0 for success)
6396 * The order is important !
6397 * To successfully add drivers the print-queues have to exist !
6398 * Applying ACLs should be the last step, because you're easily locked out
6401 static int rpc_printer_migrate_all(int argc, const char **argv)
6406 printf("no server to migrate\n");
6410 ret = run_rpc_command(NULL, PI_SPOOLSS, 0, rpc_printer_migrate_printers_internals, argc, argv);
6414 ret = run_rpc_command(NULL, PI_SPOOLSS, 0, rpc_printer_migrate_drivers_internals, argc, argv);
6418 ret = run_rpc_command(NULL, PI_SPOOLSS, 0, rpc_printer_migrate_forms_internals, argc, argv);
6422 ret = run_rpc_command(NULL, PI_SPOOLSS, 0, rpc_printer_migrate_settings_internals, argc, argv);
6426 return run_rpc_command(NULL, PI_SPOOLSS, 0, rpc_printer_migrate_security_internals, argc, argv);
6431 * Migrate print-drivers from a print-server
6433 * @param argc Standard main() style argc
6434 * @param argv Standard main() style argv. Initial components are already
6437 * @return A shell status integer (0 for success)
6439 static int rpc_printer_migrate_drivers(int argc, const char **argv)
6442 printf("no server to migrate\n");
6446 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6447 rpc_printer_migrate_drivers_internals,
6452 * Migrate print-forms from a print-server
6454 * @param argc Standard main() style argc
6455 * @param argv Standard main() style argv. Initial components are already
6458 * @return A shell status integer (0 for success)
6460 static int rpc_printer_migrate_forms(int argc, const char **argv)
6463 printf("no server to migrate\n");
6467 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6468 rpc_printer_migrate_forms_internals,
6473 * Migrate printers from a print-server
6475 * @param argc Standard main() style argc
6476 * @param argv Standard main() style argv. Initial components are already
6479 * @return A shell status integer (0 for success)
6481 static int rpc_printer_migrate_printers(int argc, const char **argv)
6484 printf("no server to migrate\n");
6488 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6489 rpc_printer_migrate_printers_internals,
6494 * Migrate printer-ACLs from a print-server
6496 * @param argc Standard main() style argc
6497 * @param argv Standard main() style argv. Initial components are already
6500 * @return A shell status integer (0 for success)
6502 static int rpc_printer_migrate_security(int argc, const char **argv)
6505 printf("no server to migrate\n");
6509 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6510 rpc_printer_migrate_security_internals,
6515 * Migrate printer-settings from a print-server
6517 * @param argc Standard main() style argc
6518 * @param argv Standard main() style argv. Initial components are already
6521 * @return A shell status integer (0 for success)
6523 static int rpc_printer_migrate_settings(int argc, const char **argv)
6526 printf("no server to migrate\n");
6530 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6531 rpc_printer_migrate_settings_internals,
6536 * 'net rpc printer' entrypoint.
6537 * @param argc Standard main() style argc
6538 * @param argv Standard main() style argv. Initial components are already
6542 int rpc_printer_migrate(int argc, const char **argv)
6545 /* ouch: when addriver and setdriver are called from within
6546 rpc_printer_migrate_drivers_internals, the printer-queue already
6549 struct functable func[] = {
6550 {"all", rpc_printer_migrate_all},
6551 {"drivers", rpc_printer_migrate_drivers},
6552 {"forms", rpc_printer_migrate_forms},
6553 {"help", rpc_printer_usage},
6554 {"printers", rpc_printer_migrate_printers},
6555 {"security", rpc_printer_migrate_security},
6556 {"settings", rpc_printer_migrate_settings},
6560 return net_run_function(argc, argv, func, rpc_printer_usage);
6565 * List printers on a remote RPC server
6567 * @param argc Standard main() style argc
6568 * @param argv Standard main() style argv. Initial components are already
6571 * @return A shell status integer (0 for success)
6573 static int rpc_printer_list(int argc, const char **argv)
6576 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6577 rpc_printer_list_internals,
6582 * List printer-drivers on a remote RPC server
6584 * @param argc Standard main() style argc
6585 * @param argv Standard main() style argv. Initial components are already
6588 * @return A shell status integer (0 for success)
6590 static int rpc_printer_driver_list(int argc, const char **argv)
6593 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6594 rpc_printer_driver_list_internals,
6599 * Publish printer in ADS via MSRPC
6601 * @param argc Standard main() style argc
6602 * @param argv Standard main() style argv. Initial components are already
6605 * @return A shell status integer (0 for success)
6607 static int rpc_printer_publish_publish(int argc, const char **argv)
6610 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6611 rpc_printer_publish_publish_internals,
6616 * Update printer in ADS via MSRPC
6618 * @param argc Standard main() style argc
6619 * @param argv Standard main() style argv. Initial components are already
6622 * @return A shell status integer (0 for success)
6624 static int rpc_printer_publish_update(int argc, const char **argv)
6627 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6628 rpc_printer_publish_update_internals,
6633 * UnPublish printer in ADS via MSRPC
6635 * @param argc Standard main() style argc
6636 * @param argv Standard main() style argv. Initial components are already
6639 * @return A shell status integer (0 for success)
6641 static int rpc_printer_publish_unpublish(int argc, const char **argv)
6644 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6645 rpc_printer_publish_unpublish_internals,
6650 * List published printers via MSRPC
6652 * @param argc Standard main() style argc
6653 * @param argv Standard main() style argv. Initial components are already
6656 * @return A shell status integer (0 for success)
6658 static int rpc_printer_publish_list(int argc, const char **argv)
6661 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6662 rpc_printer_publish_list_internals,
6668 * Publish printer in ADS
6670 * @param argc Standard main() style argc
6671 * @param argv Standard main() style argv. Initial components are already
6674 * @return A shell status integer (0 for success)
6676 static int rpc_printer_publish(int argc, const char **argv)
6679 struct functable func[] = {
6680 {"publish", rpc_printer_publish_publish},
6681 {"update", rpc_printer_publish_update},
6682 {"unpublish", rpc_printer_publish_unpublish},
6683 {"list", rpc_printer_publish_list},
6684 {"help", rpc_printer_usage},
6689 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6690 rpc_printer_publish_list_internals,
6693 return net_run_function(argc, argv, func, rpc_printer_usage);
6699 * Display rpc printer help page.
6700 * @param argc Standard main() style argc
6701 * @param argv Standard main() style argv. Initial components are already
6704 int rpc_printer_usage(int argc, const char **argv)
6706 return net_help_printer(argc, argv);
6710 * 'net rpc printer' entrypoint.
6711 * @param argc Standard main() style argc
6712 * @param argv Standard main() style argv. Initial components are already
6715 int net_rpc_printer(int argc, const char **argv)
6717 struct functable func[] = {
6718 {"list", rpc_printer_list},
6719 {"migrate", rpc_printer_migrate},
6720 {"driver", rpc_printer_driver_list},
6721 {"publish", rpc_printer_publish},
6726 return run_rpc_command(NULL, PI_SPOOLSS, 0,
6727 rpc_printer_list_internals,
6730 return net_run_function(argc, argv, func, rpc_printer_usage);
6733 /****************************************************************************/
6737 * Basic usage function for 'net rpc'
6738 * @param argc Standard main() style argc
6739 * @param argv Standard main() style argv. Initial components are already
6743 int net_rpc_usage(int argc, const char **argv)
6745 d_printf(" net rpc info \t\t\tshow basic info about a domain \n");
6746 d_printf(" net rpc join \t\t\tto join a domain \n");
6747 d_printf(" net rpc oldjoin \t\tto join a domain created in server manager\n");
6748 d_printf(" net rpc testjoin \t\ttests that a join is valid\n");
6749 d_printf(" net rpc user \t\t\tto add, delete and list users\n");
6750 d_printf(" net rpc password <username> [<password>] -Uadmin_username%%admin_pass\n");
6751 d_printf(" net rpc group \t\tto list groups\n");
6752 d_printf(" net rpc share \t\tto add, delete, list and migrate shares\n");
6753 d_printf(" net rpc printer \t\tto list and migrate printers\n");
6754 d_printf(" net rpc file \t\t\tto list open files\n");
6755 d_printf(" net rpc changetrustpw \tto change the trust account password\n");
6756 d_printf(" net rpc getsid \t\tfetch the domain sid into the local secrets.tdb\n");
6757 d_printf(" net rpc vampire \t\tsyncronise an NT PDC's users and groups into the local passdb\n");
6758 d_printf(" net rpc samdump \t\tdisplay an NT PDC's users, groups and other data\n");
6759 d_printf(" net rpc trustdom \t\tto create trusting domain's account or establish trust\n");
6760 d_printf(" net rpc abortshutdown \tto abort the shutdown of a remote server\n");
6761 d_printf(" net rpc shutdown \t\tto shutdown a remote server\n");
6762 d_printf(" net rpc rights\t\tto manage privileges assigned to SIDs\n");
6763 d_printf(" net rpc registry\t\tto manage registry hives\n");
6764 d_printf(" net rpc service\t\tto start, stop and query services\n");
6765 d_printf(" net rpc audit\t\t\tto modify global auditing settings\n");
6766 d_printf(" net rpc shell\t\t\tto open an interactive shell for remote server/account management\n");
6768 d_printf("'net rpc shutdown' also accepts the following miscellaneous options:\n"); /* misc options */
6769 d_printf("\t-r or --reboot\trequest remote server reboot on shutdown\n");
6770 d_printf("\t-f or --force\trequest the remote server force its shutdown\n");
6771 d_printf("\t-t or --timeout=<timeout>\tnumber of seconds before shutdown\n");
6772 d_printf("\t-C or --comment=<message>\ttext message to display on impending shutdown\n");
6778 * Help function for 'net rpc'. Calls command specific help if requested
6779 * or displays usage of net rpc
6780 * @param argc Standard main() style argc
6781 * @param argv Standard main() style argv. Initial components are already
6785 int net_rpc_help(int argc, const char **argv)
6787 struct functable func[] = {
6788 {"join", rpc_join_usage},
6789 {"user", rpc_user_usage},
6790 {"group", rpc_group_usage},
6791 {"share", rpc_share_usage},
6792 /*{"changetrustpw", rpc_changetrustpw_usage}, */
6793 {"trustdom", rpc_trustdom_usage},
6794 /*{"abortshutdown", rpc_shutdown_abort_usage},*/
6795 /*{"shutdown", rpc_shutdown_usage}, */
6796 {"vampire", rpc_vampire_usage},
6801 net_rpc_usage(argc, argv);
6805 return (net_run_function(argc, argv, func, rpc_user_usage));
6809 * 'net rpc' entrypoint.
6810 * @param argc Standard main() style argc
6811 * @param argv Standard main() style argv. Initial components are already
6815 int net_rpc(int argc, const char **argv)
6817 struct functable func[] = {
6818 {"audit", net_rpc_audit},
6819 {"info", net_rpc_info},
6820 {"join", net_rpc_join},
6821 {"oldjoin", net_rpc_oldjoin},
6822 {"testjoin", net_rpc_testjoin},
6823 {"user", net_rpc_user},
6824 {"password", rpc_user_password},
6825 {"group", net_rpc_group},
6826 {"share", net_rpc_share},
6827 {"file", net_rpc_file},
6828 {"printer", net_rpc_printer},
6829 {"changetrustpw", net_rpc_changetrustpw},
6830 {"trustdom", rpc_trustdom},
6831 {"abortshutdown", rpc_shutdown_abort},
6832 {"shutdown", rpc_shutdown},
6833 {"samdump", rpc_samdump},
6834 {"vampire", rpc_vampire},
6835 {"getsid", net_rpc_getsid},
6836 {"rights", net_rpc_rights},
6837 {"service", net_rpc_service},
6838 {"registry", net_rpc_registry},
6839 {"shell", net_rpc_shell},
6840 {"help", net_rpc_help},
6843 return net_run_function(argc, argv, func, net_rpc_usage);