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,2008 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"
25 #include "../libcli/auth/libcli_auth.h"
26 #include "../librpc/gen_ndr/cli_samr.h"
27 #include "rpc_client/cli_samr.h"
28 #include "../librpc/gen_ndr/cli_lsa.h"
29 #include "rpc_client/cli_lsarpc.h"
30 #include "../librpc/gen_ndr/cli_netlogon.h"
31 #include "../librpc/gen_ndr/cli_srvsvc.h"
32 #include "../librpc/gen_ndr/cli_spoolss.h"
33 #include "../librpc/gen_ndr/cli_initshutdown.h"
34 #include "../librpc/gen_ndr/cli_winreg.h"
36 static int net_mode_share;
37 static bool sync_files(struct copy_clistate *cp_clistate, const char *mask);
42 * @brief RPC based subcommands for the 'net' utility.
44 * This file should contain much of the functionality that used to
45 * be found in rpcclient, execpt that the commands should change
46 * less often, and the fucntionality should be sane (the user is not
47 * expected to know a rid/sid before they conduct an operation etc.)
49 * @todo Perhaps eventually these should be split out into a number
50 * of files, as this could get quite big.
55 * Many of the RPC functions need the domain sid. This function gets
56 * it at the start of every run
58 * @param cli A cli_state already connected to the remote machine
60 * @return The Domain SID of the remote machine.
63 NTSTATUS net_get_remote_domain_sid(struct cli_state *cli, TALLOC_CTX *mem_ctx,
65 const char **domain_name)
67 struct rpc_pipe_client *lsa_pipe = NULL;
68 struct policy_handle pol;
69 NTSTATUS result = NT_STATUS_OK;
70 union lsa_PolicyInformation *info = NULL;
72 result = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc.syntax_id,
74 if (!NT_STATUS_IS_OK(result)) {
75 d_fprintf(stderr, _("Could not initialise lsa pipe\n"));
79 result = rpccli_lsa_open_policy(lsa_pipe, mem_ctx, false,
80 SEC_FLAG_MAXIMUM_ALLOWED,
82 if (!NT_STATUS_IS_OK(result)) {
83 d_fprintf(stderr, "open_policy %s: %s\n",
89 result = rpccli_lsa_QueryInfoPolicy(lsa_pipe, mem_ctx,
91 LSA_POLICY_INFO_ACCOUNT_DOMAIN,
93 if (!NT_STATUS_IS_OK(result)) {
94 d_fprintf(stderr, "lsaquery %s: %s\n",
100 *domain_name = info->account_domain.name.string;
101 *domain_sid = info->account_domain.sid;
103 rpccli_lsa_Close(lsa_pipe, mem_ctx, &pol);
104 TALLOC_FREE(lsa_pipe);
110 * Run a single RPC command, from start to finish.
112 * @param pipe_name the pipe to connect to (usually a PIPE_ constant)
113 * @param conn_flag a NET_FLAG_ combination. Passed to
114 * net_make_ipc_connection.
115 * @param argc Standard main() style argc.
116 * @param argv Standard main() style argv. Initial components are already
118 * @return A shell status integer (0 for success).
121 int run_rpc_command(struct net_context *c,
122 struct cli_state *cli_arg,
123 const struct ndr_syntax_id *interface,
129 struct cli_state *cli = NULL;
130 struct rpc_pipe_client *pipe_hnd = NULL;
134 const char *domain_name;
137 /* make use of cli_state handed over as an argument, if possible */
139 nt_status = net_make_ipc_connection(c, conn_flags, &cli);
140 if (!NT_STATUS_IS_OK(nt_status)) {
141 DEBUG(1, ("failed to make ipc connection: %s\n",
142 nt_errstr(nt_status)));
155 if (!(mem_ctx = talloc_init("run_rpc_command"))) {
156 DEBUG(0, ("talloc_init() failed\n"));
160 nt_status = net_get_remote_domain_sid(cli, mem_ctx, &domain_sid,
162 if (!NT_STATUS_IS_OK(nt_status)) {
166 if (!(conn_flags & NET_FLAGS_NO_PIPE)) {
167 if (lp_client_schannel()
168 && (ndr_syntax_id_equal(interface,
169 &ndr_table_netlogon.syntax_id))) {
170 /* Always try and create an schannel netlogon pipe. */
171 nt_status = cli_rpc_pipe_open_schannel(
172 cli, interface, NCACN_NP,
173 DCERPC_AUTH_LEVEL_PRIVACY, domain_name,
175 if (!NT_STATUS_IS_OK(nt_status)) {
176 DEBUG(0, ("Could not initialise schannel netlogon pipe. Error was %s\n",
177 nt_errstr(nt_status) ));
181 if (conn_flags & NET_FLAGS_SEAL) {
182 nt_status = cli_rpc_pipe_open_ntlmssp(
184 (conn_flags & NET_FLAGS_TCP) ?
185 NCACN_IP_TCP : NCACN_NP,
186 DCERPC_AUTH_LEVEL_PRIVACY,
187 lp_workgroup(), c->opt_user_name,
188 c->opt_password, &pipe_hnd);
190 nt_status = cli_rpc_pipe_open_noauth(
194 if (!NT_STATUS_IS_OK(nt_status)) {
195 DEBUG(0, ("Could not initialise pipe %s. Error was %s\n",
196 get_pipe_name_from_syntax(
197 talloc_tos(), interface),
198 nt_errstr(nt_status) ));
204 nt_status = fn(c, domain_sid, domain_name, cli, pipe_hnd, mem_ctx, argc, argv);
206 if (!NT_STATUS_IS_OK(nt_status)) {
207 DEBUG(1, ("rpc command function failed! (%s)\n", nt_errstr(nt_status)));
210 DEBUG(5, ("rpc command function succedded\n"));
213 if (!(conn_flags & NET_FLAGS_NO_PIPE)) {
215 TALLOC_FREE(pipe_hnd);
220 /* close the connection only if it was opened here */
225 talloc_destroy(mem_ctx);
230 * Force a change of the trust acccount password.
232 * All parameters are provided by the run_rpc_command function, except for
233 * argc, argv which are passed through.
235 * @param domain_sid The domain sid acquired from the remote server.
236 * @param cli A cli_state connected to the server.
237 * @param mem_ctx Talloc context, destroyed on completion of the function.
238 * @param argc Standard main() style argc.
239 * @param argv Standard main() style argv. Initial components are already
242 * @return Normal NTSTATUS return.
245 static NTSTATUS rpc_changetrustpw_internals(struct net_context *c,
246 const DOM_SID *domain_sid,
247 const char *domain_name,
248 struct cli_state *cli,
249 struct rpc_pipe_client *pipe_hnd,
256 status = trust_pw_find_change_and_store_it(pipe_hnd, mem_ctx, c->opt_target_workgroup);
257 if (!NT_STATUS_IS_OK(status)) {
258 d_fprintf(stderr, _("Failed to change machine account password: %s\n"),
267 * Force a change of the trust acccount password.
269 * @param argc Standard main() style argc.
270 * @param argv Standard main() style argv. Initial components are already
273 * @return A shell status integer (0 for success).
276 int net_rpc_changetrustpw(struct net_context *c, int argc, const char **argv)
278 if (c->display_usage) {
280 "net rpc changetrustpw\n"
283 _("Change the machine trust password"));
287 return run_rpc_command(c, NULL, &ndr_table_netlogon.syntax_id,
288 NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC,
289 rpc_changetrustpw_internals,
294 * Join a domain, the old way.
296 * This uses 'machinename' as the inital password, and changes it.
298 * The password should be created with 'server manager' or equiv first.
300 * All parameters are provided by the run_rpc_command function, except for
301 * argc, argv which are passed through.
303 * @param domain_sid The domain sid acquired from the remote server.
304 * @param cli A cli_state connected to the server.
305 * @param mem_ctx Talloc context, destroyed on completion of the function.
306 * @param argc Standard main() style argc.
307 * @param argv Standard main() style argv. Initial components are already
310 * @return Normal NTSTATUS return.
313 static NTSTATUS rpc_oldjoin_internals(struct net_context *c,
314 const DOM_SID *domain_sid,
315 const char *domain_name,
316 struct cli_state *cli,
317 struct rpc_pipe_client *pipe_hnd,
323 fstring trust_passwd;
324 unsigned char orig_trust_passwd_hash[16];
326 enum netr_SchannelType sec_channel_type;
328 result = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
330 if (!NT_STATUS_IS_OK(result)) {
331 DEBUG(0,("rpc_oldjoin_internals: netlogon pipe open to machine %s failed. "
334 nt_errstr(result) ));
339 check what type of join - if the user want's to join as
340 a BDC, the server must agree that we are a BDC.
343 sec_channel_type = get_sec_channel_type(argv[0]);
345 sec_channel_type = get_sec_channel_type(NULL);
348 fstrcpy(trust_passwd, global_myname());
349 strlower_m(trust_passwd);
352 * Machine names can be 15 characters, but the max length on
353 * a password is 14. --jerry
356 trust_passwd[14] = '\0';
358 E_md4hash(trust_passwd, orig_trust_passwd_hash);
360 result = trust_pw_change_and_store_it(pipe_hnd, mem_ctx, c->opt_target_workgroup,
362 orig_trust_passwd_hash,
365 if (NT_STATUS_IS_OK(result))
366 printf(_("Joined domain %s.\n"), c->opt_target_workgroup);
369 if (!secrets_store_domain_sid(c->opt_target_workgroup, domain_sid)) {
370 DEBUG(0, ("error storing domain sid for %s\n", c->opt_target_workgroup));
371 result = NT_STATUS_UNSUCCESSFUL;
378 * Join a domain, the old way.
380 * @param argc Standard main() style argc.
381 * @param argv Standard main() style argv. Initial components are already
384 * @return A shell status integer (0 for success).
387 static int net_rpc_perform_oldjoin(struct net_context *c, int argc, const char **argv)
389 return run_rpc_command(c, NULL, &ndr_table_netlogon.syntax_id,
390 NET_FLAGS_NO_PIPE | NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC,
391 rpc_oldjoin_internals,
396 * Join a domain, the old way. This function exists to allow
397 * the message to be displayed when oldjoin was explicitly
398 * requested, but not when it was implied by "net rpc join".
400 * @param argc Standard main() style argc.
401 * @param argv Standard main() style argv. Initial components are already
404 * @return A shell status integer (0 for success).
407 static int net_rpc_oldjoin(struct net_context *c, int argc, const char **argv)
411 if (c->display_usage) {
416 _("Join a domain the old way"));
420 rc = net_rpc_perform_oldjoin(c, argc, argv);
423 d_fprintf(stderr, _("Failed to join domain\n"));
430 * 'net rpc join' entrypoint.
431 * @param argc Standard main() style argc.
432 * @param argv Standard main() style argv. Initial components are already
435 * Main 'net_rpc_join()' (where the admin username/password is used) is
437 * Try to just change the password, but if that doesn't work, use/prompt
438 * for a username/password.
441 int net_rpc_join(struct net_context *c, int argc, const char **argv)
443 if (c->display_usage) {
446 _("net rpc join -U <username>[%%password] <type>\n"
448 " username\tName of the admin user"
449 " password\tPassword of the admin user, will "
450 "prompt if not specified\n"
451 " type\tCan be one of the following:\n"
452 "\t\tMEMBER\tJoin as member server (default)\n"
453 "\t\tBDC\tJoin as BDC\n"
454 "\t\tPDC\tJoin as PDC\n"));
458 if (lp_server_role() == ROLE_STANDALONE) {
459 d_printf(_("cannot join as standalone machine\n"));
463 if (strlen(global_myname()) > 15) {
464 d_printf(_("Our netbios name can be at most 15 chars long, "
465 "\"%s\" is %u chars long\n"),
466 global_myname(), (unsigned int)strlen(global_myname()));
470 if ((net_rpc_perform_oldjoin(c, argc, argv) == 0))
473 return net_rpc_join_newstyle(c, argc, argv);
477 * display info about a rpc domain
479 * All parameters are provided by the run_rpc_command function, except for
480 * argc, argv which are passed through.
482 * @param domain_sid The domain sid acquired from the remote server
483 * @param cli A cli_state connected to the server.
484 * @param mem_ctx Talloc context, destroyed on completion of the function.
485 * @param argc Standard main() style argc.
486 * @param argv Standard main() style argv. Initial components are already
489 * @return Normal NTSTATUS return.
492 NTSTATUS rpc_info_internals(struct net_context *c,
493 const DOM_SID *domain_sid,
494 const char *domain_name,
495 struct cli_state *cli,
496 struct rpc_pipe_client *pipe_hnd,
501 struct policy_handle connect_pol, domain_pol;
502 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
503 union samr_DomainInfo *info = NULL;
506 sid_to_fstring(sid_str, domain_sid);
508 /* Get sam policy handle */
509 result = rpccli_samr_Connect2(pipe_hnd, mem_ctx,
511 MAXIMUM_ALLOWED_ACCESS,
513 if (!NT_STATUS_IS_OK(result)) {
514 d_fprintf(stderr, _("Could not connect to SAM: %s\n"),
519 /* Get domain policy handle */
520 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
522 MAXIMUM_ALLOWED_ACCESS,
523 CONST_DISCARD(struct dom_sid2 *, domain_sid),
525 if (!NT_STATUS_IS_OK(result)) {
526 d_fprintf(stderr, _("Could not open domain: %s\n"),
531 result = rpccli_samr_QueryDomainInfo(pipe_hnd, mem_ctx,
535 if (NT_STATUS_IS_OK(result)) {
536 d_printf(_("Domain Name: %s\n"),
537 info->general.domain_name.string);
538 d_printf(_("Domain SID: %s\n"), sid_str);
539 d_printf(_("Sequence number: %llu\n"),
540 (unsigned long long)info->general.sequence_num);
541 d_printf(_("Num users: %u\n"), info->general.num_users);
542 d_printf(_("Num domain groups: %u\n"),info->general.num_groups);
543 d_printf(_("Num local groups: %u\n"),info->general.num_aliases);
551 * 'net rpc info' entrypoint.
552 * @param argc Standard main() style argc.
553 * @param argv Standard main() style argv. Initial components are already
557 int net_rpc_info(struct net_context *c, int argc, const char **argv)
559 if (c->display_usage) {
564 _("Display information about the domain"));
568 return run_rpc_command(c, NULL, &ndr_table_samr.syntax_id,
569 NET_FLAGS_PDC, rpc_info_internals,
574 * Fetch domain SID into the local secrets.tdb.
576 * All parameters are provided by the run_rpc_command function, except for
577 * argc, argv which are passed through.
579 * @param domain_sid The domain sid acquired from the remote server.
580 * @param cli A cli_state connected to the server.
581 * @param mem_ctx Talloc context, destroyed on completion of the function.
582 * @param argc Standard main() style argc.
583 * @param argv Standard main() style argv. Initial components are already
586 * @return Normal NTSTATUS return.
589 static NTSTATUS rpc_getsid_internals(struct net_context *c,
590 const DOM_SID *domain_sid,
591 const char *domain_name,
592 struct cli_state *cli,
593 struct rpc_pipe_client *pipe_hnd,
600 sid_to_fstring(sid_str, domain_sid);
601 d_printf(_("Storing SID %s for Domain %s in secrets.tdb\n"),
602 sid_str, domain_name);
604 if (!secrets_store_domain_sid(domain_name, domain_sid)) {
605 DEBUG(0,("Can't store domain SID\n"));
606 return NT_STATUS_UNSUCCESSFUL;
613 * 'net rpc getsid' entrypoint.
614 * @param argc Standard main() style argc.
615 * @param argv Standard main() style argv. Initial components are already
619 int net_rpc_getsid(struct net_context *c, int argc, const char **argv)
621 int conn_flags = NET_FLAGS_PDC;
623 if (!c->opt_user_specified) {
624 conn_flags |= NET_FLAGS_ANONYMOUS;
627 if (c->display_usage) {
632 _("Fetch domain SID into local secrets.tdb"));
636 return run_rpc_command(c, NULL, &ndr_table_samr.syntax_id,
638 rpc_getsid_internals,
642 /****************************************************************************/
645 * Basic usage function for 'net rpc user'.
646 * @param argc Standard main() style argc.
647 * @param argv Standard main() style argv. Initial components are already
651 static int rpc_user_usage(struct net_context *c, int argc, const char **argv)
653 return net_user_usage(c, argc, argv);
657 * Add a new user to a remote RPC server.
659 * @param argc Standard main() style argc.
660 * @param argv Standard main() style argv. Initial components are already
663 * @return A shell status integer (0 for success).
666 static int rpc_user_add(struct net_context *c, int argc, const char **argv)
668 NET_API_STATUS status;
669 struct USER_INFO_1 info1;
670 uint32_t parm_error = 0;
672 if (argc < 1 || c->display_usage) {
673 rpc_user_usage(c, argc, argv);
679 info1.usri1_name = argv[0];
681 info1.usri1_password = argv[1];
684 status = NetUserAdd(c->opt_host, 1, (uint8_t *)&info1, &parm_error);
687 d_fprintf(stderr,_("Failed to add user '%s' with error: %s.\n"),
688 argv[0], libnetapi_get_error_string(c->netapi_ctx,
692 d_printf(_("Added user '%s'.\n"), argv[0]);
699 * Rename a user on 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_rename(struct net_context *c, int argc, const char **argv)
710 NET_API_STATUS status;
711 struct USER_INFO_0 u0;
712 uint32_t parm_err = 0;
714 if (argc != 2 || c->display_usage) {
715 rpc_user_usage(c, argc, argv);
719 u0.usri0_name = argv[1];
721 status = NetUserSetInfo(c->opt_host, argv[0],
722 0, (uint8_t *)&u0, &parm_err);
725 _("Failed to rename user from %s to %s - %s\n"),
727 libnetapi_get_error_string(c->netapi_ctx, status));
729 d_printf(_("Renamed user from %s to %s\n"), argv[0], argv[1]);
736 * Set a user's primary group
738 * @param argc Standard main() style argc.
739 * @param argv Standard main() style argv. Initial components are already
742 * @return A shell status integer (0 for success).
745 static int rpc_user_setprimarygroup(struct net_context *c, int argc,
748 NET_API_STATUS status;
750 struct GROUP_INFO_2 *g2;
751 struct USER_INFO_1051 u1051;
752 uint32_t parm_err = 0;
754 if (argc != 2 || c->display_usage) {
755 rpc_user_usage(c, argc, argv);
759 status = NetGroupGetInfo(c->opt_host, argv[1], 2, &buffer);
761 d_fprintf(stderr, _("Failed to find group name %s -- %s\n"),
763 libnetapi_get_error_string(c->netapi_ctx, status));
766 g2 = (struct GROUP_INFO_2 *)buffer;
768 u1051.usri1051_primary_group_id = g2->grpi2_group_id;
770 NetApiBufferFree(buffer);
772 status = NetUserSetInfo(c->opt_host, argv[0], 1051,
773 (uint8_t *)&u1051, &parm_err);
776 _("Failed to set user's primary group %s to %s - "
777 "%s\n"), argv[0], argv[1],
778 libnetapi_get_error_string(c->netapi_ctx, status));
780 d_printf(_("Set primary group of user %s to %s\n"), argv[0],
787 * Delete a user from a remote RPC server.
789 * @param argc Standard main() style argc.
790 * @param argv Standard main() style argv. Initial components are already
793 * @return A shell status integer (0 for success).
796 static int rpc_user_delete(struct net_context *c, int argc, const char **argv)
798 NET_API_STATUS status;
800 if (argc < 1 || c->display_usage) {
801 rpc_user_usage(c, argc, argv);
805 status = NetUserDel(c->opt_host, argv[0]);
808 d_fprintf(stderr, _("Failed to delete user '%s' with: %s.\n"),
810 libnetapi_get_error_string(c->netapi_ctx, status));
813 d_printf(_("Deleted user '%s'.\n"), argv[0]);
820 * Set a user's password on a remote RPC server.
822 * @param argc Standard main() style argc.
823 * @param argv Standard main() style argv. Initial components are already
826 * @return A shell status integer (0 for success).
829 static int rpc_user_password(struct net_context *c, int argc, const char **argv)
831 NET_API_STATUS status;
833 struct USER_INFO_1003 u1003;
834 uint32_t parm_err = 0;
837 if (argc < 1 || c->display_usage) {
838 rpc_user_usage(c, argc, argv);
843 u1003.usri1003_password = argv[1];
845 ret = asprintf(&prompt, _("Enter new password for %s:"),
850 u1003.usri1003_password = talloc_strdup(c, getpass(prompt));
852 if (u1003.usri1003_password == NULL) {
857 status = NetUserSetInfo(c->opt_host, argv[0], 1003, (uint8_t *)&u1003, &parm_err);
859 /* Display results */
862 _("Failed to set password for '%s' with error: %s.\n"),
863 argv[0], libnetapi_get_error_string(c->netapi_ctx,
872 * List a user's groups from a remote RPC server.
874 * @param argc Standard main() style argc.
875 * @param argv Standard main() style argv. Initial components are already
878 * @return A shell status integer (0 for success)
881 static int rpc_user_info(struct net_context *c, int argc, const char **argv)
884 NET_API_STATUS status;
885 struct GROUP_USERS_INFO_0 *u0 = NULL;
886 uint32_t entries_read = 0;
887 uint32_t total_entries = 0;
891 if (argc < 1 || c->display_usage) {
892 rpc_user_usage(c, argc, argv);
896 status = NetUserGetGroups(c->opt_host,
899 (uint8_t **)(void *)&u0,
905 _("Failed to get groups for '%s' with error: %s.\n"),
906 argv[0], libnetapi_get_error_string(c->netapi_ctx,
911 for (i=0; i < entries_read; i++) {
912 printf("%s\n", u0->grui0_name);
920 * List users on a remote RPC server.
922 * All parameters are provided by the run_rpc_command function, except for
923 * argc, argv which are passed through.
925 * @param domain_sid The domain sid acquired from the remote server.
926 * @param cli A cli_state connected to the server.
927 * @param mem_ctx Talloc context, destroyed on completion of the function.
928 * @param argc Standard main() style argc.
929 * @param argv Standard main() style argv. Initial components are already
932 * @return Normal NTSTATUS return.
935 static int rpc_user_list(struct net_context *c, int argc, const char **argv)
937 NET_API_STATUS status;
938 uint32_t start_idx=0, num_entries, i, loop_count = 0;
939 struct NET_DISPLAY_USER *info = NULL;
942 /* Query domain users */
943 if (c->opt_long_list_entries)
944 d_printf(_("\nUser name Comment"
945 "\n-----------------------------\n"));
947 uint32_t max_entries, max_size;
949 get_query_dispinfo_params(
950 loop_count, &max_entries, &max_size);
952 status = NetQueryDisplayInformation(c->opt_host,
959 if (status != 0 && status != ERROR_MORE_DATA) {
963 info = (struct NET_DISPLAY_USER *)buffer;
965 for (i = 0; i < num_entries; i++) {
967 if (c->opt_long_list_entries)
968 printf("%-21.21s %s\n", info->usri1_name,
969 info->usri1_comment);
971 printf("%s\n", info->usri1_name);
975 NetApiBufferFree(buffer);
978 start_idx += num_entries;
980 } while (status == ERROR_MORE_DATA);
986 * 'net rpc user' entrypoint.
987 * @param argc Standard main() style argc.
988 * @param argv Standard main() style argv. Initial components are already
992 int net_rpc_user(struct net_context *c, int argc, const char **argv)
994 NET_API_STATUS status;
996 struct functable func[] = {
1001 N_("Add specified user"),
1002 N_("net rpc user add\n"
1003 " Add specified user")
1009 N_("List domain groups of user"),
1010 N_("net rpc user info\n"
1011 " Lis domain groups of user")
1017 N_("Remove specified user"),
1018 N_("net rpc user delete\n"
1019 " Remove specified user")
1025 N_("Change user password"),
1026 N_("net rpc user password\n"
1027 " Change user password")
1033 N_("Rename specified user"),
1034 N_("net rpc user rename\n"
1035 " Rename specified user")
1039 rpc_user_setprimarygroup,
1041 "Set a user's primary group",
1042 "net rpc user setprimarygroup\n"
1043 " Set a user's primary group"
1045 {NULL, NULL, 0, NULL, NULL}
1048 status = libnetapi_init(&c->netapi_ctx);
1052 libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
1053 libnetapi_set_password(c->netapi_ctx, c->opt_password);
1054 if (c->opt_kerberos) {
1055 libnetapi_set_use_kerberos(c->netapi_ctx);
1059 if (c->display_usage) {
1064 _("List all users"));
1065 net_display_usage_from_functable(func);
1069 return rpc_user_list(c, argc, argv);
1072 return net_run_function(c, argc, argv, "net rpc user", func);
1075 static NTSTATUS rpc_sh_user_list(struct net_context *c,
1076 TALLOC_CTX *mem_ctx,
1077 struct rpc_sh_ctx *ctx,
1078 struct rpc_pipe_client *pipe_hnd,
1079 int argc, const char **argv)
1081 return werror_to_ntstatus(W_ERROR(rpc_user_list(c, argc, argv)));
1084 static NTSTATUS rpc_sh_user_info(struct net_context *c,
1085 TALLOC_CTX *mem_ctx,
1086 struct rpc_sh_ctx *ctx,
1087 struct rpc_pipe_client *pipe_hnd,
1088 int argc, const char **argv)
1090 return werror_to_ntstatus(W_ERROR(rpc_user_info(c, argc, argv)));
1093 static NTSTATUS rpc_sh_handle_user(struct net_context *c,
1094 TALLOC_CTX *mem_ctx,
1095 struct rpc_sh_ctx *ctx,
1096 struct rpc_pipe_client *pipe_hnd,
1097 int argc, const char **argv,
1099 struct net_context *c,
1100 TALLOC_CTX *mem_ctx,
1101 struct rpc_sh_ctx *ctx,
1102 struct rpc_pipe_client *pipe_hnd,
1103 struct policy_handle *user_hnd,
1104 int argc, const char **argv))
1106 struct policy_handle connect_pol, domain_pol, user_pol;
1107 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1110 enum lsa_SidType type;
1113 d_fprintf(stderr, "%s %s <username>\n", _("Usage:"),
1115 return NT_STATUS_INVALID_PARAMETER;
1118 ZERO_STRUCT(connect_pol);
1119 ZERO_STRUCT(domain_pol);
1120 ZERO_STRUCT(user_pol);
1122 result = net_rpc_lookup_name(c, mem_ctx, rpc_pipe_np_smb_conn(pipe_hnd),
1123 argv[0], NULL, NULL, &sid, &type);
1124 if (!NT_STATUS_IS_OK(result)) {
1125 d_fprintf(stderr, _("Could not lookup %s: %s\n"), argv[0],
1130 if (type != SID_NAME_USER) {
1131 d_fprintf(stderr, _("%s is a %s, not a user\n"), argv[0],
1132 sid_type_lookup(type));
1133 result = NT_STATUS_NO_SUCH_USER;
1137 if (!sid_peek_check_rid(ctx->domain_sid, &sid, &rid)) {
1138 d_fprintf(stderr, _("%s is not in our domain\n"), argv[0]);
1139 result = NT_STATUS_NO_SUCH_USER;
1143 result = rpccli_samr_Connect2(pipe_hnd, mem_ctx,
1145 MAXIMUM_ALLOWED_ACCESS,
1147 if (!NT_STATUS_IS_OK(result)) {
1151 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
1153 MAXIMUM_ALLOWED_ACCESS,
1156 if (!NT_STATUS_IS_OK(result)) {
1160 result = rpccli_samr_OpenUser(pipe_hnd, mem_ctx,
1162 MAXIMUM_ALLOWED_ACCESS,
1165 if (!NT_STATUS_IS_OK(result)) {
1169 result = fn(c, mem_ctx, ctx, pipe_hnd, &user_pol, argc-1, argv+1);
1172 if (is_valid_policy_hnd(&user_pol)) {
1173 rpccli_samr_Close(pipe_hnd, mem_ctx, &user_pol);
1175 if (is_valid_policy_hnd(&domain_pol)) {
1176 rpccli_samr_Close(pipe_hnd, mem_ctx, &domain_pol);
1178 if (is_valid_policy_hnd(&connect_pol)) {
1179 rpccli_samr_Close(pipe_hnd, mem_ctx, &connect_pol);
1184 static NTSTATUS rpc_sh_user_show_internals(struct net_context *c,
1185 TALLOC_CTX *mem_ctx,
1186 struct rpc_sh_ctx *ctx,
1187 struct rpc_pipe_client *pipe_hnd,
1188 struct policy_handle *user_hnd,
1189 int argc, const char **argv)
1192 union samr_UserInfo *info = NULL;
1195 d_fprintf(stderr, "%s %s show <username>\n", _("Usage:"),
1197 return NT_STATUS_INVALID_PARAMETER;
1200 result = rpccli_samr_QueryUserInfo(pipe_hnd, mem_ctx,
1204 if (!NT_STATUS_IS_OK(result)) {
1208 d_printf(_("user rid: %d, group rid: %d\n"),
1210 info->info21.primary_gid);
1215 static NTSTATUS rpc_sh_user_show(struct net_context *c,
1216 TALLOC_CTX *mem_ctx,
1217 struct rpc_sh_ctx *ctx,
1218 struct rpc_pipe_client *pipe_hnd,
1219 int argc, const char **argv)
1221 return rpc_sh_handle_user(c, mem_ctx, ctx, pipe_hnd, argc, argv,
1222 rpc_sh_user_show_internals);
1225 #define FETCHSTR(name, rec) \
1226 do { if (strequal(ctx->thiscmd, name)) { \
1227 oldval = talloc_strdup(mem_ctx, info->info21.rec.string); } \
1230 #define SETSTR(name, rec, flag) \
1231 do { if (strequal(ctx->thiscmd, name)) { \
1232 init_lsa_String(&(info->info21.rec), argv[0]); \
1233 info->info21.fields_present |= SAMR_FIELD_##flag; } \
1236 static NTSTATUS rpc_sh_user_str_edit_internals(struct net_context *c,
1237 TALLOC_CTX *mem_ctx,
1238 struct rpc_sh_ctx *ctx,
1239 struct rpc_pipe_client *pipe_hnd,
1240 struct policy_handle *user_hnd,
1241 int argc, const char **argv)
1244 const char *username;
1245 const char *oldval = "";
1246 union samr_UserInfo *info = NULL;
1249 d_fprintf(stderr, "%s %s <username> [new value|NULL]\n",
1250 _("Usage:"), ctx->whoami);
1251 return NT_STATUS_INVALID_PARAMETER;
1254 result = rpccli_samr_QueryUserInfo(pipe_hnd, mem_ctx,
1258 if (!NT_STATUS_IS_OK(result)) {
1262 username = talloc_strdup(mem_ctx, info->info21.account_name.string);
1264 FETCHSTR("fullname", full_name);
1265 FETCHSTR("homedir", home_directory);
1266 FETCHSTR("homedrive", home_drive);
1267 FETCHSTR("logonscript", logon_script);
1268 FETCHSTR("profilepath", profile_path);
1269 FETCHSTR("description", description);
1272 d_printf(_("%s's %s: [%s]\n"), username, ctx->thiscmd, oldval);
1276 if (strcmp(argv[0], "NULL") == 0) {
1280 ZERO_STRUCT(info->info21);
1282 SETSTR("fullname", full_name, FULL_NAME);
1283 SETSTR("homedir", home_directory, HOME_DIRECTORY);
1284 SETSTR("homedrive", home_drive, HOME_DRIVE);
1285 SETSTR("logonscript", logon_script, LOGON_SCRIPT);
1286 SETSTR("profilepath", profile_path, PROFILE_PATH);
1287 SETSTR("description", description, DESCRIPTION);
1289 result = rpccli_samr_SetUserInfo(pipe_hnd, mem_ctx,
1294 d_printf(_("Set %s's %s from [%s] to [%s]\n"), username,
1295 ctx->thiscmd, oldval, argv[0]);
1302 #define HANDLEFLG(name, rec) \
1303 do { if (strequal(ctx->thiscmd, name)) { \
1304 oldval = (oldflags & ACB_##rec) ? "yes" : "no"; \
1306 newflags = oldflags | ACB_##rec; \
1308 newflags = oldflags & ~ACB_##rec; \
1311 static NTSTATUS rpc_sh_user_str_edit(struct net_context *c,
1312 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_sh_handle_user(c, mem_ctx, ctx, pipe_hnd, argc, argv,
1318 rpc_sh_user_str_edit_internals);
1321 static NTSTATUS rpc_sh_user_flag_edit_internals(struct net_context *c,
1322 TALLOC_CTX *mem_ctx,
1323 struct rpc_sh_ctx *ctx,
1324 struct rpc_pipe_client *pipe_hnd,
1325 struct policy_handle *user_hnd,
1326 int argc, const char **argv)
1329 const char *username;
1330 const char *oldval = "unknown";
1331 uint32 oldflags, newflags;
1333 union samr_UserInfo *info = NULL;
1336 ((argc == 1) && !strequal(argv[0], "yes") &&
1337 !strequal(argv[0], "no"))) {
1338 /* TRANSATORS: The yes|no here are program keywords. Please do
1340 d_fprintf(stderr, _("Usage: %s <username> [yes|no]\n"),
1342 return NT_STATUS_INVALID_PARAMETER;
1345 newval = strequal(argv[0], "yes");
1347 result = rpccli_samr_QueryUserInfo(pipe_hnd, mem_ctx,
1351 if (!NT_STATUS_IS_OK(result)) {
1355 username = talloc_strdup(mem_ctx, info->info21.account_name.string);
1356 oldflags = info->info21.acct_flags;
1357 newflags = info->info21.acct_flags;
1359 HANDLEFLG("disabled", DISABLED);
1360 HANDLEFLG("pwnotreq", PWNOTREQ);
1361 HANDLEFLG("autolock", AUTOLOCK);
1362 HANDLEFLG("pwnoexp", PWNOEXP);
1365 d_printf(_("%s's %s flag: %s\n"), username, ctx->thiscmd,
1370 ZERO_STRUCT(info->info21);
1372 info->info21.acct_flags = newflags;
1373 info->info21.fields_present = SAMR_FIELD_ACCT_FLAGS;
1375 result = rpccli_samr_SetUserInfo(pipe_hnd, mem_ctx,
1380 if (NT_STATUS_IS_OK(result)) {
1381 d_printf(_("Set %s's %s flag from [%s] to [%s]\n"), username,
1382 ctx->thiscmd, oldval, argv[0]);
1390 static NTSTATUS rpc_sh_user_flag_edit(struct net_context *c,
1391 TALLOC_CTX *mem_ctx,
1392 struct rpc_sh_ctx *ctx,
1393 struct rpc_pipe_client *pipe_hnd,
1394 int argc, const char **argv)
1396 return rpc_sh_handle_user(c, mem_ctx, ctx, pipe_hnd, argc, argv,
1397 rpc_sh_user_flag_edit_internals);
1400 struct rpc_sh_cmd *net_rpc_user_edit_cmds(struct net_context *c,
1401 TALLOC_CTX *mem_ctx,
1402 struct rpc_sh_ctx *ctx)
1404 static struct rpc_sh_cmd cmds[] = {
1406 { "fullname", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_str_edit,
1407 N_("Show/Set a user's full name") },
1409 { "homedir", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_str_edit,
1410 N_("Show/Set a user's home directory") },
1412 { "homedrive", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_str_edit,
1413 N_("Show/Set a user's home drive") },
1415 { "logonscript", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_str_edit,
1416 N_("Show/Set a user's logon script") },
1418 { "profilepath", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_str_edit,
1419 N_("Show/Set a user's profile path") },
1421 { "description", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_str_edit,
1422 N_("Show/Set a user's description") },
1424 { "disabled", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_flag_edit,
1425 N_("Show/Set whether a user is disabled") },
1427 { "autolock", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_flag_edit,
1428 N_("Show/Set whether a user locked out") },
1430 { "pwnotreq", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_flag_edit,
1431 N_("Show/Set whether a user does not need a password") },
1433 { "pwnoexp", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_flag_edit,
1434 N_("Show/Set whether a user's password does not expire") },
1436 { NULL, NULL, 0, NULL, NULL }
1442 struct rpc_sh_cmd *net_rpc_user_cmds(struct net_context *c,
1443 TALLOC_CTX *mem_ctx,
1444 struct rpc_sh_ctx *ctx)
1446 static struct rpc_sh_cmd cmds[] = {
1448 { "list", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_list,
1449 N_("List available users") },
1451 { "info", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_info,
1452 N_("List the domain groups a user is member of") },
1454 { "show", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_show,
1455 N_("Show info about a user") },
1457 { "edit", net_rpc_user_edit_cmds, 0, NULL,
1458 N_("Show/Modify a user's fields") },
1460 { NULL, NULL, 0, NULL, NULL }
1466 /****************************************************************************/
1469 * Basic usage function for 'net rpc group'.
1470 * @param argc Standard main() style argc.
1471 * @param argv Standard main() style argv. Initial components are already
1475 static int rpc_group_usage(struct net_context *c, int argc, const char **argv)
1477 return net_group_usage(c, argc, argv);
1481 * Delete group on a remote RPC server.
1483 * All parameters are provided by the run_rpc_command function, except for
1484 * argc, argv which are passed through.
1486 * @param domain_sid The domain sid acquired from the remote server.
1487 * @param cli A cli_state connected to the server.
1488 * @param mem_ctx Talloc context, destroyed on completion of the function.
1489 * @param argc Standard main() style argc.
1490 * @param argv Standard main() style argv. Initial components are already
1493 * @return Normal NTSTATUS return.
1496 static NTSTATUS rpc_group_delete_internals(struct net_context *c,
1497 const DOM_SID *domain_sid,
1498 const char *domain_name,
1499 struct cli_state *cli,
1500 struct rpc_pipe_client *pipe_hnd,
1501 TALLOC_CTX *mem_ctx,
1505 struct policy_handle connect_pol, domain_pol, group_pol, user_pol;
1506 bool group_is_primary = false;
1507 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1509 struct samr_RidTypeArray *rids = NULL;
1512 /* struct samr_RidWithAttribute *user_gids; */
1514 struct samr_Ids group_rids, name_types;
1515 struct lsa_String lsa_acct_name;
1516 union samr_UserInfo *info = NULL;
1518 if (argc < 1 || c->display_usage) {
1519 rpc_group_usage(c, argc,argv);
1520 return NT_STATUS_OK; /* ok? */
1523 result = rpccli_samr_Connect2(pipe_hnd, mem_ctx,
1525 MAXIMUM_ALLOWED_ACCESS,
1528 if (!NT_STATUS_IS_OK(result)) {
1529 d_fprintf(stderr, _("Request samr_Connect2 failed\n"));
1533 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
1535 MAXIMUM_ALLOWED_ACCESS,
1536 CONST_DISCARD(struct dom_sid2 *, domain_sid),
1539 if (!NT_STATUS_IS_OK(result)) {
1540 d_fprintf(stderr, _("Request open_domain failed\n"));
1544 init_lsa_String(&lsa_acct_name, argv[0]);
1546 result = rpccli_samr_LookupNames(pipe_hnd, mem_ctx,
1552 if (!NT_STATUS_IS_OK(result)) {
1553 d_fprintf(stderr, _("Lookup of '%s' failed\n"),argv[0]);
1557 switch (name_types.ids[0])
1559 case SID_NAME_DOM_GRP:
1560 result = rpccli_samr_OpenGroup(pipe_hnd, mem_ctx,
1562 MAXIMUM_ALLOWED_ACCESS,
1565 if (!NT_STATUS_IS_OK(result)) {
1566 d_fprintf(stderr, _("Request open_group failed"));
1570 group_rid = group_rids.ids[0];
1572 result = rpccli_samr_QueryGroupMember(pipe_hnd, mem_ctx,
1576 if (!NT_STATUS_IS_OK(result)) {
1578 _("Unable to query group members of %s"),
1583 if (c->opt_verbose) {
1585 _("Domain Group %s (rid: %d) has %d members\n"),
1586 argv[0],group_rid, rids->count);
1589 /* Check if group is anyone's primary group */
1590 for (i = 0; i < rids->count; i++)
1592 result = rpccli_samr_OpenUser(pipe_hnd, mem_ctx,
1594 MAXIMUM_ALLOWED_ACCESS,
1598 if (!NT_STATUS_IS_OK(result)) {
1600 _("Unable to open group member %d\n"),
1605 result = rpccli_samr_QueryUserInfo(pipe_hnd, mem_ctx,
1610 if (!NT_STATUS_IS_OK(result)) {
1612 _("Unable to lookup userinfo for group "
1618 if (info->info21.primary_gid == group_rid) {
1619 if (c->opt_verbose) {
1620 d_printf(_("Group is primary group "
1622 info->info21.account_name.string);
1624 group_is_primary = true;
1627 rpccli_samr_Close(pipe_hnd, mem_ctx, &user_pol);
1630 if (group_is_primary) {
1631 d_fprintf(stderr, _("Unable to delete group because "
1632 "some of it's members have it as primary "
1634 result = NT_STATUS_MEMBERS_PRIMARY_GROUP;
1638 /* remove all group members */
1639 for (i = 0; i < rids->count; i++)
1642 d_printf(_("Remove group member %d..."),
1644 result = rpccli_samr_DeleteGroupMember(pipe_hnd, mem_ctx,
1648 if (NT_STATUS_IS_OK(result)) {
1650 d_printf(_("ok\n"));
1653 d_printf("%s\n", _("failed"));
1658 result = rpccli_samr_DeleteDomainGroup(pipe_hnd, mem_ctx,
1662 /* removing a local group is easier... */
1663 case SID_NAME_ALIAS:
1664 result = rpccli_samr_OpenAlias(pipe_hnd, mem_ctx,
1666 MAXIMUM_ALLOWED_ACCESS,
1670 if (!NT_STATUS_IS_OK(result)) {
1671 d_fprintf(stderr, _("Request open_alias failed\n"));
1675 result = rpccli_samr_DeleteDomAlias(pipe_hnd, mem_ctx,
1679 d_fprintf(stderr, _("%s is of type %s. This command is only "
1680 "for deleting local or global groups\n"),
1681 argv[0],sid_type_lookup(name_types.ids[0]));
1682 result = NT_STATUS_UNSUCCESSFUL;
1686 if (NT_STATUS_IS_OK(result)) {
1688 d_printf(_("Deleted %s '%s'\n"),
1689 sid_type_lookup(name_types.ids[0]), argv[0]);
1691 d_fprintf(stderr, _("Deleting of %s failed: %s\n"), argv[0],
1692 get_friendly_nt_error_msg(result));
1700 static int rpc_group_delete(struct net_context *c, int argc, const char **argv)
1702 return run_rpc_command(c, NULL, &ndr_table_samr.syntax_id, 0,
1703 rpc_group_delete_internals, argc,argv);
1706 static int rpc_group_add_internals(struct net_context *c, int argc, const char **argv)
1708 NET_API_STATUS status;
1709 struct GROUP_INFO_1 info1;
1710 uint32_t parm_error = 0;
1712 if (argc != 1 || c->display_usage) {
1713 rpc_group_usage(c, argc, argv);
1719 info1.grpi1_name = argv[0];
1720 if (c->opt_comment && strlen(c->opt_comment) > 0) {
1721 info1.grpi1_comment = c->opt_comment;
1724 status = NetGroupAdd(c->opt_host, 1, (uint8_t *)&info1, &parm_error);
1728 _("Failed to add group '%s' with error: %s.\n"),
1729 argv[0], libnetapi_get_error_string(c->netapi_ctx,
1733 d_printf(_("Added group '%s'.\n"), argv[0]);
1739 static int rpc_alias_add_internals(struct net_context *c, int argc, const char **argv)
1741 NET_API_STATUS status;
1742 struct LOCALGROUP_INFO_1 info1;
1743 uint32_t parm_error = 0;
1745 if (argc != 1 || c->display_usage) {
1746 rpc_group_usage(c, argc, argv);
1752 info1.lgrpi1_name = argv[0];
1753 if (c->opt_comment && strlen(c->opt_comment) > 0) {
1754 info1.lgrpi1_comment = c->opt_comment;
1757 status = NetLocalGroupAdd(c->opt_host, 1, (uint8_t *)&info1, &parm_error);
1761 _("Failed to add alias '%s' with error: %s.\n"),
1762 argv[0], libnetapi_get_error_string(c->netapi_ctx,
1766 d_printf(_("Added alias '%s'.\n"), argv[0]);
1772 static int rpc_group_add(struct net_context *c, int argc, const char **argv)
1774 if (c->opt_localgroup)
1775 return rpc_alias_add_internals(c, argc, argv);
1777 return rpc_group_add_internals(c, argc, argv);
1780 static NTSTATUS get_sid_from_name(struct cli_state *cli,
1781 TALLOC_CTX *mem_ctx,
1784 enum lsa_SidType *type)
1786 DOM_SID *sids = NULL;
1787 enum lsa_SidType *types = NULL;
1788 struct rpc_pipe_client *pipe_hnd = NULL;
1789 struct policy_handle lsa_pol;
1790 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1792 result = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc.syntax_id,
1794 if (!NT_STATUS_IS_OK(result)) {
1798 result = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, false,
1799 SEC_FLAG_MAXIMUM_ALLOWED, &lsa_pol);
1801 if (!NT_STATUS_IS_OK(result)) {
1805 result = rpccli_lsa_lookup_names(pipe_hnd, mem_ctx, &lsa_pol, 1,
1806 &name, NULL, 1, &sids, &types);
1808 if (NT_STATUS_IS_OK(result)) {
1809 sid_copy(sid, &sids[0]);
1813 rpccli_lsa_Close(pipe_hnd, mem_ctx, &lsa_pol);
1817 TALLOC_FREE(pipe_hnd);
1820 if (!NT_STATUS_IS_OK(result) && (StrnCaseCmp(name, "S-", 2) == 0)) {
1822 /* Try as S-1-5-whatever */
1826 if (string_to_sid(&tmp_sid, name)) {
1827 sid_copy(sid, &tmp_sid);
1828 *type = SID_NAME_UNKNOWN;
1829 result = NT_STATUS_OK;
1836 static NTSTATUS rpc_add_groupmem(struct rpc_pipe_client *pipe_hnd,
1837 TALLOC_CTX *mem_ctx,
1838 const DOM_SID *group_sid,
1841 struct policy_handle connect_pol, domain_pol;
1844 struct policy_handle group_pol;
1846 struct samr_Ids rids, rid_types;
1847 struct lsa_String lsa_acct_name;
1851 sid_copy(&sid, group_sid);
1853 if (!sid_split_rid(&sid, &group_rid)) {
1854 return NT_STATUS_UNSUCCESSFUL;
1857 /* Get sam policy handle */
1858 result = rpccli_samr_Connect2(pipe_hnd, mem_ctx,
1860 MAXIMUM_ALLOWED_ACCESS,
1862 if (!NT_STATUS_IS_OK(result)) {
1866 /* Get domain policy handle */
1867 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
1869 MAXIMUM_ALLOWED_ACCESS,
1872 if (!NT_STATUS_IS_OK(result)) {
1876 init_lsa_String(&lsa_acct_name, member);
1878 result = rpccli_samr_LookupNames(pipe_hnd, mem_ctx,
1885 if (!NT_STATUS_IS_OK(result)) {
1886 d_fprintf(stderr, _("Could not lookup up group member %s\n"),
1891 result = rpccli_samr_OpenGroup(pipe_hnd, mem_ctx,
1893 MAXIMUM_ALLOWED_ACCESS,
1897 if (!NT_STATUS_IS_OK(result)) {
1901 result = rpccli_samr_AddGroupMember(pipe_hnd, mem_ctx,
1904 0x0005); /* unknown flags */
1907 rpccli_samr_Close(pipe_hnd, mem_ctx, &connect_pol);
1911 static NTSTATUS rpc_add_aliasmem(struct rpc_pipe_client *pipe_hnd,
1912 TALLOC_CTX *mem_ctx,
1913 const DOM_SID *alias_sid,
1916 struct policy_handle connect_pol, domain_pol;
1919 struct policy_handle alias_pol;
1922 enum lsa_SidType member_type;
1926 sid_copy(&sid, alias_sid);
1928 if (!sid_split_rid(&sid, &alias_rid)) {
1929 return NT_STATUS_UNSUCCESSFUL;
1932 result = get_sid_from_name(rpc_pipe_np_smb_conn(pipe_hnd), mem_ctx,
1933 member, &member_sid, &member_type);
1935 if (!NT_STATUS_IS_OK(result)) {
1936 d_fprintf(stderr, _("Could not lookup up group member %s\n"),
1941 /* Get sam policy handle */
1942 result = rpccli_samr_Connect2(pipe_hnd, mem_ctx,
1944 MAXIMUM_ALLOWED_ACCESS,
1946 if (!NT_STATUS_IS_OK(result)) {
1950 /* Get domain policy handle */
1951 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
1953 MAXIMUM_ALLOWED_ACCESS,
1956 if (!NT_STATUS_IS_OK(result)) {
1960 result = rpccli_samr_OpenAlias(pipe_hnd, mem_ctx,
1962 MAXIMUM_ALLOWED_ACCESS,
1966 if (!NT_STATUS_IS_OK(result)) {
1970 result = rpccli_samr_AddAliasMember(pipe_hnd, mem_ctx,
1974 if (!NT_STATUS_IS_OK(result)) {
1979 rpccli_samr_Close(pipe_hnd, mem_ctx, &connect_pol);
1983 static NTSTATUS rpc_group_addmem_internals(struct net_context *c,
1984 const DOM_SID *domain_sid,
1985 const char *domain_name,
1986 struct cli_state *cli,
1987 struct rpc_pipe_client *pipe_hnd,
1988 TALLOC_CTX *mem_ctx,
1993 enum lsa_SidType group_type;
1995 if (argc != 2 || c->display_usage) {
1998 _("net rpc group addmem <group> <member>\n"
1999 " Add a member to a group\n"
2000 " group\tGroup to add member to\n"
2001 " member\tMember to add to group\n"));
2002 return NT_STATUS_UNSUCCESSFUL;
2005 if (!NT_STATUS_IS_OK(get_sid_from_name(cli, mem_ctx, argv[0],
2006 &group_sid, &group_type))) {
2007 d_fprintf(stderr, _("Could not lookup group name %s\n"),
2009 return NT_STATUS_UNSUCCESSFUL;
2012 if (group_type == SID_NAME_DOM_GRP) {
2013 NTSTATUS result = rpc_add_groupmem(pipe_hnd, mem_ctx,
2014 &group_sid, argv[1]);
2016 if (!NT_STATUS_IS_OK(result)) {
2017 d_fprintf(stderr, _("Could not add %s to %s: %s\n"),
2018 argv[1], argv[0], nt_errstr(result));
2023 if (group_type == SID_NAME_ALIAS) {
2024 NTSTATUS result = rpc_add_aliasmem(pipe_hnd, mem_ctx,
2025 &group_sid, argv[1]);
2027 if (!NT_STATUS_IS_OK(result)) {
2028 d_fprintf(stderr, _("Could not add %s to %s: %s\n"),
2029 argv[1], argv[0], nt_errstr(result));
2034 d_fprintf(stderr, _("Can only add members to global or local groups "
2035 "which %s is not\n"), argv[0]);
2037 return NT_STATUS_UNSUCCESSFUL;
2040 static int rpc_group_addmem(struct net_context *c, int argc, const char **argv)
2042 return run_rpc_command(c, NULL, &ndr_table_samr.syntax_id, 0,
2043 rpc_group_addmem_internals,
2047 static NTSTATUS rpc_del_groupmem(struct net_context *c,
2048 struct rpc_pipe_client *pipe_hnd,
2049 TALLOC_CTX *mem_ctx,
2050 const DOM_SID *group_sid,
2053 struct policy_handle connect_pol, domain_pol;
2056 struct policy_handle group_pol;
2058 struct samr_Ids rids, rid_types;
2059 struct lsa_String lsa_acct_name;
2063 sid_copy(&sid, group_sid);
2065 if (!sid_split_rid(&sid, &group_rid))
2066 return NT_STATUS_UNSUCCESSFUL;
2068 /* Get sam policy handle */
2069 result = rpccli_samr_Connect2(pipe_hnd, mem_ctx,
2071 MAXIMUM_ALLOWED_ACCESS,
2073 if (!NT_STATUS_IS_OK(result))
2076 /* Get domain policy handle */
2077 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
2079 MAXIMUM_ALLOWED_ACCESS,
2082 if (!NT_STATUS_IS_OK(result))
2085 init_lsa_String(&lsa_acct_name, member);
2087 result = rpccli_samr_LookupNames(pipe_hnd, mem_ctx,
2093 if (!NT_STATUS_IS_OK(result)) {
2094 d_fprintf(stderr, _("Could not lookup up group member %s\n"),
2099 result = rpccli_samr_OpenGroup(pipe_hnd, mem_ctx,
2101 MAXIMUM_ALLOWED_ACCESS,
2105 if (!NT_STATUS_IS_OK(result))
2108 result = rpccli_samr_DeleteGroupMember(pipe_hnd, mem_ctx,
2113 rpccli_samr_Close(pipe_hnd, mem_ctx, &connect_pol);
2117 static NTSTATUS rpc_del_aliasmem(struct rpc_pipe_client *pipe_hnd,
2118 TALLOC_CTX *mem_ctx,
2119 const DOM_SID *alias_sid,
2122 struct policy_handle connect_pol, domain_pol;
2125 struct policy_handle alias_pol;
2128 enum lsa_SidType member_type;
2132 sid_copy(&sid, alias_sid);
2134 if (!sid_split_rid(&sid, &alias_rid))
2135 return NT_STATUS_UNSUCCESSFUL;
2137 result = get_sid_from_name(rpc_pipe_np_smb_conn(pipe_hnd), mem_ctx,
2138 member, &member_sid, &member_type);
2140 if (!NT_STATUS_IS_OK(result)) {
2141 d_fprintf(stderr, _("Could not lookup up group member %s\n"),
2146 /* Get sam policy handle */
2147 result = rpccli_samr_Connect2(pipe_hnd, mem_ctx,
2149 MAXIMUM_ALLOWED_ACCESS,
2151 if (!NT_STATUS_IS_OK(result)) {
2155 /* Get domain policy handle */
2156 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
2158 MAXIMUM_ALLOWED_ACCESS,
2161 if (!NT_STATUS_IS_OK(result)) {
2165 result = rpccli_samr_OpenAlias(pipe_hnd, mem_ctx,
2167 MAXIMUM_ALLOWED_ACCESS,
2171 if (!NT_STATUS_IS_OK(result))
2174 result = rpccli_samr_DeleteAliasMember(pipe_hnd, mem_ctx,
2178 if (!NT_STATUS_IS_OK(result))
2182 rpccli_samr_Close(pipe_hnd, mem_ctx, &connect_pol);
2186 static NTSTATUS rpc_group_delmem_internals(struct net_context *c,
2187 const DOM_SID *domain_sid,
2188 const char *domain_name,
2189 struct cli_state *cli,
2190 struct rpc_pipe_client *pipe_hnd,
2191 TALLOC_CTX *mem_ctx,
2196 enum lsa_SidType group_type;
2198 if (argc != 2 || c->display_usage) {
2201 _("net rpc group delmem <group> <member>\n"
2202 " Delete a member from a group\n"
2203 " group\tGroup to delete member from\n"
2204 " member\tMember to delete from group\n"));
2205 return NT_STATUS_UNSUCCESSFUL;
2208 if (!NT_STATUS_IS_OK(get_sid_from_name(cli, mem_ctx, argv[0],
2209 &group_sid, &group_type))) {
2210 d_fprintf(stderr, _("Could not lookup group name %s\n"),
2212 return NT_STATUS_UNSUCCESSFUL;
2215 if (group_type == SID_NAME_DOM_GRP) {
2216 NTSTATUS result = rpc_del_groupmem(c, pipe_hnd, mem_ctx,
2217 &group_sid, argv[1]);
2219 if (!NT_STATUS_IS_OK(result)) {
2220 d_fprintf(stderr, _("Could not del %s from %s: %s\n"),
2221 argv[1], argv[0], nt_errstr(result));
2226 if (group_type == SID_NAME_ALIAS) {
2227 NTSTATUS result = rpc_del_aliasmem(pipe_hnd, mem_ctx,
2228 &group_sid, argv[1]);
2230 if (!NT_STATUS_IS_OK(result)) {
2231 d_fprintf(stderr, _("Could not del %s from %s: %s\n"),
2232 argv[1], argv[0], nt_errstr(result));
2237 d_fprintf(stderr, _("Can only delete members from global or local "
2238 "groups which %s is not\n"), argv[0]);
2240 return NT_STATUS_UNSUCCESSFUL;
2243 static int rpc_group_delmem(struct net_context *c, int argc, const char **argv)
2245 return run_rpc_command(c, NULL, &ndr_table_samr.syntax_id, 0,
2246 rpc_group_delmem_internals,
2251 * List groups on a remote RPC server.
2253 * All parameters are provided by the run_rpc_command function, except for
2254 * argc, argv which are passes through.
2256 * @param domain_sid The domain sid acquired from the remote server.
2257 * @param cli A cli_state connected to the server.
2258 * @param mem_ctx Talloc context, destroyed on completion of the function.
2259 * @param argc Standard main() style argc.
2260 * @param argv Standard main() style argv. Initial components are already
2263 * @return Normal NTSTATUS return.
2266 static NTSTATUS rpc_group_list_internals(struct net_context *c,
2267 const DOM_SID *domain_sid,
2268 const char *domain_name,
2269 struct cli_state *cli,
2270 struct rpc_pipe_client *pipe_hnd,
2271 TALLOC_CTX *mem_ctx,
2275 struct policy_handle connect_pol, domain_pol;
2276 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2277 uint32 start_idx=0, max_entries=250, num_entries, i, loop_count = 0;
2278 struct samr_SamArray *groups = NULL;
2279 bool global = false;
2281 bool builtin = false;
2283 if (c->display_usage) {
2286 _("net rpc group list [global] [local] [builtin]\n"
2287 " List groups on RPC server\n"
2288 " global\tList global groups\n"
2289 " local\tList local groups\n"
2290 " builtin\tList builtin groups\n"
2291 " If none of global, local or builtin is "
2292 "specified, all three options are considered "
2294 return NT_STATUS_OK;
2303 for (i=0; i<argc; i++) {
2304 if (strequal(argv[i], "global"))
2307 if (strequal(argv[i], "local"))
2310 if (strequal(argv[i], "builtin"))
2314 /* Get sam policy handle */
2316 result = rpccli_samr_Connect2(pipe_hnd, mem_ctx,
2318 MAXIMUM_ALLOWED_ACCESS,
2320 if (!NT_STATUS_IS_OK(result)) {
2324 /* Get domain policy handle */
2326 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
2328 MAXIMUM_ALLOWED_ACCESS,
2329 CONST_DISCARD(struct dom_sid2 *, domain_sid),
2331 if (!NT_STATUS_IS_OK(result)) {
2335 /* Query domain groups */
2336 if (c->opt_long_list_entries)
2337 d_printf(_("\nGroup name Comment"
2338 "\n-----------------------------\n"));
2340 uint32_t max_size, total_size, returned_size;
2341 union samr_DispInfo info;
2345 get_query_dispinfo_params(
2346 loop_count, &max_entries, &max_size);
2348 result = rpccli_samr_QueryDisplayInfo(pipe_hnd, mem_ctx,
2357 num_entries = info.info3.count;
2358 start_idx += info.info3.count;
2360 if (!NT_STATUS_IS_OK(result) &&
2361 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
2364 for (i = 0; i < num_entries; i++) {
2366 const char *group = NULL;
2367 const char *desc = NULL;
2369 group = info.info3.entries[i].account_name.string;
2370 desc = info.info3.entries[i].description.string;
2372 if (c->opt_long_list_entries)
2373 printf("%-21.21s %-50.50s\n",
2376 printf("%s\n", group);
2378 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
2379 /* query domain aliases */
2384 result = rpccli_samr_EnumDomainAliases(pipe_hnd, mem_ctx,
2390 if (!NT_STATUS_IS_OK(result) &&
2391 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
2394 for (i = 0; i < num_entries; i++) {
2396 const char *description = NULL;
2398 if (c->opt_long_list_entries) {
2400 struct policy_handle alias_pol;
2401 union samr_AliasInfo *info = NULL;
2403 if ((NT_STATUS_IS_OK(rpccli_samr_OpenAlias(pipe_hnd, mem_ctx,
2406 groups->entries[i].idx,
2408 (NT_STATUS_IS_OK(rpccli_samr_QueryAliasInfo(pipe_hnd, mem_ctx,
2412 (NT_STATUS_IS_OK(rpccli_samr_Close(pipe_hnd, mem_ctx,
2414 description = info->description.string;
2418 if (description != NULL) {
2419 printf("%-21.21s %-50.50s\n",
2420 groups->entries[i].name.string,
2423 printf("%s\n", groups->entries[i].name.string);
2426 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
2427 rpccli_samr_Close(pipe_hnd, mem_ctx, &domain_pol);
2428 /* Get builtin policy handle */
2430 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
2432 MAXIMUM_ALLOWED_ACCESS,
2433 CONST_DISCARD(struct dom_sid2 *, &global_sid_Builtin),
2435 if (!NT_STATUS_IS_OK(result)) {
2438 /* query builtin aliases */
2441 if (!builtin) break;
2443 result = rpccli_samr_EnumDomainAliases(pipe_hnd, mem_ctx,
2449 if (!NT_STATUS_IS_OK(result) &&
2450 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
2453 for (i = 0; i < num_entries; i++) {
2455 const char *description = NULL;
2457 if (c->opt_long_list_entries) {
2459 struct policy_handle alias_pol;
2460 union samr_AliasInfo *info = NULL;
2462 if ((NT_STATUS_IS_OK(rpccli_samr_OpenAlias(pipe_hnd, mem_ctx,
2465 groups->entries[i].idx,
2467 (NT_STATUS_IS_OK(rpccli_samr_QueryAliasInfo(pipe_hnd, mem_ctx,
2471 (NT_STATUS_IS_OK(rpccli_samr_Close(pipe_hnd, mem_ctx,
2473 description = info->description.string;
2477 if (description != NULL) {
2478 printf("%-21.21s %-50.50s\n",
2479 groups->entries[i].name.string,
2482 printf("%s\n", groups->entries[i].name.string);
2485 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
2491 static int rpc_group_list(struct net_context *c, int argc, const char **argv)
2493 return run_rpc_command(c, NULL, &ndr_table_samr.syntax_id, 0,
2494 rpc_group_list_internals,
2498 static NTSTATUS rpc_list_group_members(struct net_context *c,
2499 struct rpc_pipe_client *pipe_hnd,
2500 TALLOC_CTX *mem_ctx,
2501 const char *domain_name,
2502 const DOM_SID *domain_sid,
2503 struct policy_handle *domain_pol,
2507 struct policy_handle group_pol;
2508 uint32 num_members, *group_rids;
2510 struct samr_RidTypeArray *rids = NULL;
2511 struct lsa_Strings names;
2512 struct samr_Ids types;
2515 sid_to_fstring(sid_str, domain_sid);
2517 result = rpccli_samr_OpenGroup(pipe_hnd, mem_ctx,
2519 MAXIMUM_ALLOWED_ACCESS,
2523 if (!NT_STATUS_IS_OK(result))
2526 result = rpccli_samr_QueryGroupMember(pipe_hnd, mem_ctx,
2530 if (!NT_STATUS_IS_OK(result))
2533 num_members = rids->count;
2534 group_rids = rids->rids;
2536 while (num_members > 0) {
2537 int this_time = 512;
2539 if (num_members < this_time)
2540 this_time = num_members;
2542 result = rpccli_samr_LookupRids(pipe_hnd, mem_ctx,
2549 if (!NT_STATUS_IS_OK(result))
2552 /* We only have users as members, but make the output
2553 the same as the output of alias members */
2555 for (i = 0; i < this_time; i++) {
2557 if (c->opt_long_list_entries) {
2558 printf("%s-%d %s\\%s %d\n", sid_str,
2559 group_rids[i], domain_name,
2560 names.names[i].string,
2563 printf("%s\\%s\n", domain_name,
2564 names.names[i].string);
2568 num_members -= this_time;
2572 return NT_STATUS_OK;
2575 static NTSTATUS rpc_list_alias_members(struct net_context *c,
2576 struct rpc_pipe_client *pipe_hnd,
2577 TALLOC_CTX *mem_ctx,
2578 struct policy_handle *domain_pol,
2582 struct rpc_pipe_client *lsa_pipe;
2583 struct policy_handle alias_pol, lsa_pol;
2585 DOM_SID *alias_sids;
2588 enum lsa_SidType *types;
2590 struct lsa_SidArray sid_array;
2592 result = rpccli_samr_OpenAlias(pipe_hnd, mem_ctx,
2594 MAXIMUM_ALLOWED_ACCESS,
2598 if (!NT_STATUS_IS_OK(result))
2601 result = rpccli_samr_GetMembersInAlias(pipe_hnd, mem_ctx,
2605 if (!NT_STATUS_IS_OK(result)) {
2606 d_fprintf(stderr, _("Couldn't list alias members\n"));
2610 num_members = sid_array.num_sids;
2612 if (num_members == 0) {
2613 return NT_STATUS_OK;
2616 result = cli_rpc_pipe_open_noauth(rpc_pipe_np_smb_conn(pipe_hnd),
2617 &ndr_table_lsarpc.syntax_id,
2619 if (!NT_STATUS_IS_OK(result)) {
2620 d_fprintf(stderr, _("Couldn't open LSA pipe. Error was %s\n"),
2621 nt_errstr(result) );
2625 result = rpccli_lsa_open_policy(lsa_pipe, mem_ctx, true,
2626 SEC_FLAG_MAXIMUM_ALLOWED, &lsa_pol);
2628 if (!NT_STATUS_IS_OK(result)) {
2629 d_fprintf(stderr, _("Couldn't open LSA policy handle\n"));
2630 TALLOC_FREE(lsa_pipe);
2634 alias_sids = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, num_members);
2636 d_fprintf(stderr, _("Out of memory\n"));
2637 TALLOC_FREE(lsa_pipe);
2638 return NT_STATUS_NO_MEMORY;
2641 for (i=0; i<num_members; i++) {
2642 sid_copy(&alias_sids[i], sid_array.sids[i].sid);
2645 result = rpccli_lsa_lookup_sids(lsa_pipe, mem_ctx, &lsa_pol,
2646 num_members, alias_sids,
2647 &domains, &names, &types);
2649 if (!NT_STATUS_IS_OK(result) &&
2650 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
2651 d_fprintf(stderr, _("Couldn't lookup SIDs\n"));
2652 TALLOC_FREE(lsa_pipe);
2656 for (i = 0; i < num_members; i++) {
2658 sid_to_fstring(sid_str, &alias_sids[i]);
2660 if (c->opt_long_list_entries) {
2661 printf("%s %s\\%s %d\n", sid_str,
2662 domains[i] ? domains[i] : _("*unknown*"),
2663 names[i] ? names[i] : _("*unknown*"), types[i]);
2666 printf("%s\\%s\n", domains[i], names[i]);
2668 printf("%s\n", sid_str);
2672 TALLOC_FREE(lsa_pipe);
2673 return NT_STATUS_OK;
2676 static NTSTATUS rpc_group_members_internals(struct net_context *c,
2677 const DOM_SID *domain_sid,
2678 const char *domain_name,
2679 struct cli_state *cli,
2680 struct rpc_pipe_client *pipe_hnd,
2681 TALLOC_CTX *mem_ctx,
2686 struct policy_handle connect_pol, domain_pol;
2687 struct samr_Ids rids, rid_types;
2688 struct lsa_String lsa_acct_name;
2690 /* Get sam policy handle */
2692 result = rpccli_samr_Connect2(pipe_hnd, mem_ctx,
2694 MAXIMUM_ALLOWED_ACCESS,
2697 if (!NT_STATUS_IS_OK(result))
2700 /* Get domain policy handle */
2702 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
2704 MAXIMUM_ALLOWED_ACCESS,
2705 CONST_DISCARD(struct dom_sid2 *, domain_sid),
2708 if (!NT_STATUS_IS_OK(result))
2711 init_lsa_String(&lsa_acct_name, argv[0]); /* sure? */
2713 result = rpccli_samr_LookupNames(pipe_hnd, mem_ctx,
2720 if (!NT_STATUS_IS_OK(result)) {
2722 /* Ok, did not find it in the global sam, try with builtin */
2724 DOM_SID sid_Builtin;
2726 rpccli_samr_Close(pipe_hnd, mem_ctx, &domain_pol);
2728 sid_copy(&sid_Builtin, &global_sid_Builtin);
2730 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
2732 MAXIMUM_ALLOWED_ACCESS,
2736 if (!NT_STATUS_IS_OK(result)) {
2737 d_fprintf(stderr, _("Couldn't find group %s\n"),
2742 result = rpccli_samr_LookupNames(pipe_hnd, mem_ctx,
2749 if (!NT_STATUS_IS_OK(result)) {
2750 d_fprintf(stderr, _("Couldn't find group %s\n"),
2756 if (rids.count != 1) {
2757 d_fprintf(stderr, _("Couldn't find group %s\n"),
2762 if (rid_types.ids[0] == SID_NAME_DOM_GRP) {
2763 return rpc_list_group_members(c, pipe_hnd, mem_ctx, domain_name,
2764 domain_sid, &domain_pol,
2768 if (rid_types.ids[0] == SID_NAME_ALIAS) {
2769 return rpc_list_alias_members(c, pipe_hnd, mem_ctx, &domain_pol,
2773 return NT_STATUS_NO_SUCH_GROUP;
2776 static int rpc_group_members(struct net_context *c, int argc, const char **argv)
2778 if (argc != 1 || c->display_usage) {
2779 return rpc_group_usage(c, argc, argv);
2782 return run_rpc_command(c, NULL, &ndr_table_samr.syntax_id, 0,
2783 rpc_group_members_internals,
2787 static int rpc_group_rename_internals(struct net_context *c, int argc, const char **argv)
2789 NET_API_STATUS status;
2790 struct GROUP_INFO_0 g0;
2794 d_printf(_("Usage:\n"));
2795 d_printf("net rpc group rename group newname\n");
2799 g0.grpi0_name = argv[1];
2801 status = NetGroupSetInfo(c->opt_host,
2808 d_fprintf(stderr, _("Renaming group %s failed with: %s\n"),
2809 argv[0], libnetapi_get_error_string(c->netapi_ctx,
2817 static int rpc_group_rename(struct net_context *c, int argc, const char **argv)
2819 if (argc != 2 || c->display_usage) {
2820 return rpc_group_usage(c, argc, argv);
2823 return rpc_group_rename_internals(c, argc, argv);
2827 * 'net rpc group' entrypoint.
2828 * @param argc Standard main() style argc.
2829 * @param argv Standard main() style argv. Initial components are already
2833 int net_rpc_group(struct net_context *c, int argc, const char **argv)
2835 NET_API_STATUS status;
2837 struct functable func[] = {
2842 N_("Create specified group"),
2843 N_("net rpc group add\n"
2844 " Create specified group")
2850 N_("Delete specified group"),
2851 N_("net rpc group delete\n"
2852 " Delete specified group")
2858 N_("Add member to group"),
2859 N_("net rpc group addmem\n"
2860 " Add member to group")
2866 N_("Remove member from group"),
2867 N_("net rpc group delmem\n"
2868 " Remove member from group")
2875 N_("net rpc group list\n"
2882 N_("List group members"),
2883 N_("net rpc group members\n"
2884 " List group members")
2891 N_("net rpc group rename\n"
2894 {NULL, NULL, 0, NULL, NULL}
2897 status = libnetapi_init(&c->netapi_ctx);
2901 libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
2902 libnetapi_set_password(c->netapi_ctx, c->opt_password);
2903 if (c->opt_kerberos) {
2904 libnetapi_set_use_kerberos(c->netapi_ctx);
2908 if (c->display_usage) {
2909 d_printf(_("Usage:\n"));
2910 d_printf(_("net rpc group\n"
2911 " Alias for net rpc group list global "
2912 "local builtin\n"));
2913 net_display_usage_from_functable(func);
2917 return run_rpc_command(c, NULL, &ndr_table_samr.syntax_id, 0,
2918 rpc_group_list_internals,
2922 return net_run_function(c, argc, argv, "net rpc group", func);
2925 /****************************************************************************/
2927 static int rpc_share_usage(struct net_context *c, int argc, const char **argv)
2929 return net_share_usage(c, argc, argv);
2933 * Add a share on a remote RPC server.
2935 * @param argc Standard main() style argc.
2936 * @param argv Standard main() style argv. Initial components are already
2939 * @return A shell status integer (0 for success).
2942 static int rpc_share_add(struct net_context *c, int argc, const char **argv)
2944 NET_API_STATUS status;
2947 uint32 type = STYPE_DISKTREE; /* only allow disk shares to be added */
2948 uint32 num_users=0, perms=0;
2949 char *password=NULL; /* don't allow a share password */
2950 struct SHARE_INFO_2 i2;
2951 uint32_t parm_error = 0;
2953 if ((argc < 1) || !strchr(argv[0], '=') || c->display_usage) {
2954 return rpc_share_usage(c, argc, argv);
2957 if ((sharename = talloc_strdup(c, argv[0])) == NULL) {
2961 path = strchr(sharename, '=');
2968 i2.shi2_netname = sharename;
2969 i2.shi2_type = type;
2970 i2.shi2_remark = c->opt_comment;
2971 i2.shi2_permissions = perms;
2972 i2.shi2_max_uses = c->opt_maxusers;
2973 i2.shi2_current_uses = num_users;
2974 i2.shi2_path = path;
2975 i2.shi2_passwd = password;
2977 status = NetShareAdd(c->opt_host,
2982 printf(_("NetShareAdd failed with: %s\n"),
2983 libnetapi_get_error_string(c->netapi_ctx, status));
2990 * Delete a share on a remote RPC server.
2992 * @param domain_sid The domain sid acquired from the remote server.
2993 * @param argc Standard main() style argc.
2994 * @param argv Standard main() style argv. Initial components are already
2997 * @return A shell status integer (0 for success).
2999 static int rpc_share_delete(struct net_context *c, int argc, const char **argv)
3001 if (argc < 1 || c->display_usage) {
3002 return rpc_share_usage(c, argc, argv);
3005 return NetShareDel(c->opt_host, argv[0], 0);
3009 * Formatted print of share info
3011 * @param r pointer to SHARE_INFO_1 to format
3014 static void display_share_info_1(struct net_context *c,
3015 struct SHARE_INFO_1 *r)
3017 if (c->opt_long_list_entries) {
3018 d_printf("%-12s %-8.8s %-50s\n",
3020 net_share_type_str(r->shi1_type & ~(STYPE_TEMPORARY|STYPE_HIDDEN)),
3023 d_printf("%s\n", r->shi1_netname);
3027 static WERROR get_share_info(struct net_context *c,
3028 struct rpc_pipe_client *pipe_hnd,
3029 TALLOC_CTX *mem_ctx,
3033 struct srvsvc_NetShareInfoCtr *info_ctr)
3037 union srvsvc_NetShareInfo info;
3039 /* no specific share requested, enumerate all */
3042 uint32_t preferred_len = 0xffffffff;
3043 uint32_t total_entries = 0;
3044 uint32_t resume_handle = 0;
3046 info_ctr->level = level;
3048 status = rpccli_srvsvc_NetShareEnumAll(pipe_hnd, mem_ctx,
3058 /* request just one share */
3059 status = rpccli_srvsvc_NetShareGetInfo(pipe_hnd, mem_ctx,
3066 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
3071 ZERO_STRUCTP(info_ctr);
3073 info_ctr->level = level;
3078 struct srvsvc_NetShareCtr1 *ctr1;
3080 ctr1 = TALLOC_ZERO_P(mem_ctx, struct srvsvc_NetShareCtr1);
3081 W_ERROR_HAVE_NO_MEMORY(ctr1);
3084 ctr1->array = info.info1;
3086 info_ctr->ctr.ctr1 = ctr1;
3090 struct srvsvc_NetShareCtr2 *ctr2;
3092 ctr2 = TALLOC_ZERO_P(mem_ctx, struct srvsvc_NetShareCtr2);
3093 W_ERROR_HAVE_NO_MEMORY(ctr2);
3096 ctr2->array = info.info2;
3098 info_ctr->ctr.ctr2 = ctr2;
3102 struct srvsvc_NetShareCtr502 *ctr502;
3104 ctr502 = TALLOC_ZERO_P(mem_ctx, struct srvsvc_NetShareCtr502);
3105 W_ERROR_HAVE_NO_MEMORY(ctr502);
3108 ctr502->array = info.info502;
3110 info_ctr->ctr.ctr502 = ctr502;
3118 * 'net rpc share list' entrypoint.
3119 * @param argc Standard main() style argc.
3120 * @param argv Standard main() style argv. Initial components are already
3123 static int rpc_share_list(struct net_context *c, int argc, const char **argv)
3125 NET_API_STATUS status;
3126 struct SHARE_INFO_1 *i1 = NULL;
3127 uint32_t entries_read = 0;
3128 uint32_t total_entries = 0;
3129 uint32_t resume_handle = 0;
3130 uint32_t i, level = 1;
3132 if (c->display_usage) {
3134 "net rpc share list\n"
3137 _("List shares on remote server"));
3141 status = NetShareEnum(c->opt_host,
3143 (uint8_t **)(void *)&i1,
3152 /* Display results */
3154 if (c->opt_long_list_entries) {
3156 "\nEnumerating shared resources (exports) on remote server:\n\n"
3157 "\nShare name Type Description\n"
3158 "---------- ---- -----------\n"));
3160 for (i = 0; i < entries_read; i++)
3161 display_share_info_1(c, &i1[i]);
3166 static bool check_share_availability(struct cli_state *cli, const char *netname)
3170 status = cli_tcon_andx(cli, netname, "A:", "", 0);
3171 if (!NT_STATUS_IS_OK(status)) {
3172 d_printf(_("skipping [%s]: not a file share.\n"), netname);
3176 status = cli_tdis(cli);
3177 if (!NT_STATUS_IS_OK(status)) {
3178 d_printf(_("cli_tdis returned %s\n"), nt_errstr(status));
3185 static bool check_share_sanity(struct net_context *c, struct cli_state *cli,
3186 const char *netname, uint32 type)
3188 /* only support disk shares */
3189 if (! ( type == STYPE_DISKTREE || type == (STYPE_DISKTREE | STYPE_HIDDEN)) ) {
3190 printf(_("share [%s] is not a diskshare (type: %x)\n"), netname,
3195 /* skip builtin shares */
3196 /* FIXME: should print$ be added too ? */
3197 if (strequal(netname,"IPC$") || strequal(netname,"ADMIN$") ||
3198 strequal(netname,"global"))
3201 if (c->opt_exclude && in_list(netname, c->opt_exclude, false)) {
3202 printf(_("excluding [%s]\n"), netname);
3206 return check_share_availability(cli, netname);
3210 * Migrate shares from a remote RPC server to the local RPC server.
3212 * All parameters are provided by the run_rpc_command function, except for
3213 * argc, argv which are passed through.
3215 * @param domain_sid The domain sid acquired from the remote server.
3216 * @param cli A cli_state connected to the server.
3217 * @param mem_ctx Talloc context, destroyed on completion of the function.
3218 * @param argc Standard main() style argc.
3219 * @param argv Standard main() style argv. Initial components are already
3222 * @return Normal NTSTATUS return.
3225 static NTSTATUS rpc_share_migrate_shares_internals(struct net_context *c,
3226 const DOM_SID *domain_sid,
3227 const char *domain_name,
3228 struct cli_state *cli,
3229 struct rpc_pipe_client *pipe_hnd,
3230 TALLOC_CTX *mem_ctx,
3235 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
3236 struct srvsvc_NetShareInfoCtr ctr_src;
3238 struct rpc_pipe_client *srvsvc_pipe = NULL;
3239 struct cli_state *cli_dst = NULL;
3240 uint32 level = 502; /* includes secdesc */
3241 uint32_t parm_error = 0;
3243 result = get_share_info(c, pipe_hnd, mem_ctx, level, argc, argv,
3245 if (!W_ERROR_IS_OK(result))
3248 /* connect destination PI_SRVSVC */
3249 nt_status = connect_dst_pipe(c, &cli_dst, &srvsvc_pipe,
3250 &ndr_table_srvsvc.syntax_id);
3251 if (!NT_STATUS_IS_OK(nt_status))
3255 for (i = 0; i < ctr_src.ctr.ctr502->count; i++) {
3257 union srvsvc_NetShareInfo info;
3258 struct srvsvc_NetShareInfo502 info502 =
3259 ctr_src.ctr.ctr502->array[i];
3261 /* reset error-code */
3262 nt_status = NT_STATUS_UNSUCCESSFUL;
3264 if (!check_share_sanity(c, cli, info502.name, info502.type))
3267 /* finally add the share on the dst server */
3269 printf(_("migrating: [%s], path: %s, comment: %s, without "
3271 info502.name, info502.path, info502.comment);
3273 info.info502 = &info502;
3275 nt_status = rpccli_srvsvc_NetShareAdd(srvsvc_pipe, mem_ctx,
3276 srvsvc_pipe->desthost,
3282 if (W_ERROR_V(result) == W_ERROR_V(WERR_FILE_EXISTS)) {
3283 printf(_(" [%s] does already exist\n"),
3288 if (!NT_STATUS_IS_OK(nt_status) || !W_ERROR_IS_OK(result)) {
3289 printf(_("cannot add share: %s\n"), win_errstr(result));
3295 nt_status = NT_STATUS_OK;
3299 cli_shutdown(cli_dst);
3307 * Migrate shares from a RPC server to another.
3309 * @param argc Standard main() style argc.
3310 * @param argv Standard main() style argv. Initial components are already
3313 * @return A shell status integer (0 for success).
3315 static int rpc_share_migrate_shares(struct net_context *c, int argc,
3318 if (c->display_usage) {
3320 "net rpc share migrate shares\n"
3323 _("Migrate shares to local server"));
3328 printf(_("no server to migrate\n"));
3332 return run_rpc_command(c, NULL, &ndr_table_srvsvc.syntax_id, 0,
3333 rpc_share_migrate_shares_internals,
3340 * @param f file_info
3341 * @param mask current search mask
3342 * @param state arg-pointer
3345 static void copy_fn(const char *mnt, file_info *f,
3346 const char *mask, void *state)
3348 static NTSTATUS nt_status;
3349 static struct copy_clistate *local_state;
3350 static fstring filename, new_mask;
3353 struct net_context *c;
3355 local_state = (struct copy_clistate *)state;
3356 nt_status = NT_STATUS_UNSUCCESSFUL;
3360 if (strequal(f->name, ".") || strequal(f->name, ".."))
3363 DEBUG(3,("got mask: %s, name: %s\n", mask, f->name));
3366 if (f->mode & aDIR) {
3368 DEBUG(3,("got dir: %s\n", f->name));
3370 fstrcpy(dir, local_state->cwd);
3372 fstrcat(dir, f->name);
3374 switch (net_mode_share)
3376 case NET_MODE_SHARE_MIGRATE:
3377 /* create that directory */
3378 nt_status = net_copy_file(c, local_state->mem_ctx,
3379 local_state->cli_share_src,
3380 local_state->cli_share_dst,
3382 c->opt_acls? true : false,
3383 c->opt_attrs? true : false,
3384 c->opt_timestamps? true:false,
3388 d_fprintf(stderr, _("Unsupported mode %d\n"), net_mode_share);
3392 if (!NT_STATUS_IS_OK(nt_status))
3393 printf(_("could not handle dir %s: %s\n"),
3394 dir, nt_errstr(nt_status));
3396 /* search below that directory */
3397 fstrcpy(new_mask, dir);
3398 fstrcat(new_mask, "\\*");
3400 old_dir = local_state->cwd;
3401 local_state->cwd = dir;
3402 if (!sync_files(local_state, new_mask))
3403 printf(_("could not handle files\n"));
3404 local_state->cwd = old_dir;
3411 fstrcpy(filename, local_state->cwd);
3412 fstrcat(filename, "\\");
3413 fstrcat(filename, f->name);
3415 DEBUG(3,("got file: %s\n", filename));
3417 switch (net_mode_share)
3419 case NET_MODE_SHARE_MIGRATE:
3420 nt_status = net_copy_file(c, local_state->mem_ctx,
3421 local_state->cli_share_src,
3422 local_state->cli_share_dst,
3424 c->opt_acls? true : false,
3425 c->opt_attrs? true : false,
3426 c->opt_timestamps? true: false,
3430 d_fprintf(stderr, _("Unsupported file mode %d\n"),
3435 if (!NT_STATUS_IS_OK(nt_status))
3436 printf(_("could not handle file %s: %s\n"),
3437 filename, nt_errstr(nt_status));
3442 * sync files, can be called recursivly to list files
3443 * and then call copy_fn for each file
3445 * @param cp_clistate pointer to the copy_clistate we work with
3446 * @param mask the current search mask
3448 * @return Boolean result
3450 static bool sync_files(struct copy_clistate *cp_clistate, const char *mask)
3452 struct cli_state *targetcli;
3453 char *targetpath = NULL;
3455 DEBUG(3,("calling cli_list with mask: %s\n", mask));
3457 if ( !cli_resolve_path(talloc_tos(), "", NULL, cp_clistate->cli_share_src,
3458 mask, &targetcli, &targetpath ) ) {
3459 d_fprintf(stderr, _("cli_resolve_path %s failed with error: "
3461 mask, cli_errstr(cp_clistate->cli_share_src));
3465 if (cli_list(targetcli, targetpath, cp_clistate->attribute, copy_fn, cp_clistate) == -1) {
3466 d_fprintf(stderr, _("listing %s failed with error: %s\n"),
3467 mask, cli_errstr(targetcli));
3476 * Set the top level directory permissions before we do any further copies.
3477 * Should set up ACL inheritance.
3480 bool copy_top_level_perms(struct net_context *c,
3481 struct copy_clistate *cp_clistate,
3482 const char *sharename)
3484 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
3486 switch (net_mode_share) {
3487 case NET_MODE_SHARE_MIGRATE:
3488 DEBUG(3,("calling net_copy_fileattr for '.' directory in share %s\n", sharename));
3489 nt_status = net_copy_fileattr(c,
3490 cp_clistate->mem_ctx,
3491 cp_clistate->cli_share_src,
3492 cp_clistate->cli_share_dst,
3494 c->opt_acls? true : false,
3495 c->opt_attrs? true : false,
3496 c->opt_timestamps? true: false,
3500 d_fprintf(stderr, _("Unsupported mode %d\n"), net_mode_share);
3504 if (!NT_STATUS_IS_OK(nt_status)) {
3505 printf(_("Could handle directory attributes for top level "
3506 "directory of share %s. Error %s\n"),
3507 sharename, nt_errstr(nt_status));
3515 * Sync all files inside a remote share to another share (over smb).
3517 * All parameters are provided by the run_rpc_command function, except for
3518 * argc, argv which are passed through.
3520 * @param domain_sid The domain sid acquired from the remote server.
3521 * @param cli A cli_state connected to the server.
3522 * @param mem_ctx Talloc context, destroyed on completion of the function.
3523 * @param argc Standard main() style argc.
3524 * @param argv Standard main() style argv. Initial components are already
3527 * @return Normal NTSTATUS return.
3530 static NTSTATUS rpc_share_migrate_files_internals(struct net_context *c,
3531 const DOM_SID *domain_sid,
3532 const char *domain_name,
3533 struct cli_state *cli,
3534 struct rpc_pipe_client *pipe_hnd,
3535 TALLOC_CTX *mem_ctx,
3540 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
3541 struct srvsvc_NetShareInfoCtr ctr_src;
3544 struct copy_clistate cp_clistate;
3545 bool got_src_share = false;
3546 bool got_dst_share = false;
3547 const char *mask = "\\*";
3550 dst = SMB_STRDUP(c->opt_destination?c->opt_destination:"127.0.0.1");
3552 nt_status = NT_STATUS_NO_MEMORY;
3556 result = get_share_info(c, pipe_hnd, mem_ctx, level, argc, argv,
3559 if (!W_ERROR_IS_OK(result))
3562 for (i = 0; i < ctr_src.ctr.ctr502->count; i++) {
3564 struct srvsvc_NetShareInfo502 info502 =
3565 ctr_src.ctr.ctr502->array[i];
3567 if (!check_share_sanity(c, cli, info502.name, info502.type))
3570 /* one might not want to mirror whole discs :) */
3571 if (strequal(info502.name, "print$") || info502.name[1] == '$') {
3572 d_printf(_("skipping [%s]: builtin/hidden share\n"),
3577 switch (net_mode_share)
3579 case NET_MODE_SHARE_MIGRATE:
3583 d_fprintf(stderr, _("Unsupported mode %d\n"),
3587 printf(_(" [%s] files and directories %s ACLs, %s DOS "
3590 c->opt_acls ? _("including") : _("without"),
3591 c->opt_attrs ? _("including") : _("without"),
3592 c->opt_timestamps ? _("(preserving timestamps)") : "");
3594 cp_clistate.mem_ctx = mem_ctx;
3595 cp_clistate.cli_share_src = NULL;
3596 cp_clistate.cli_share_dst = NULL;
3597 cp_clistate.cwd = NULL;
3598 cp_clistate.attribute = aSYSTEM | aHIDDEN | aDIR;
3601 /* open share source */
3602 nt_status = connect_to_service(c, &cp_clistate.cli_share_src,
3603 &cli->dest_ss, cli->desthost,
3604 info502.name, "A:");
3605 if (!NT_STATUS_IS_OK(nt_status))
3608 got_src_share = true;
3610 if (net_mode_share == NET_MODE_SHARE_MIGRATE) {
3611 /* open share destination */
3612 nt_status = connect_to_service(c, &cp_clistate.cli_share_dst,
3613 NULL, dst, info502.name, "A:");
3614 if (!NT_STATUS_IS_OK(nt_status))
3617 got_dst_share = true;
3620 if (!copy_top_level_perms(c, &cp_clistate, info502.name)) {
3621 d_fprintf(stderr, _("Could not handle the top level "
3622 "directory permissions for the "
3623 "share: %s\n"), info502.name);
3624 nt_status = NT_STATUS_UNSUCCESSFUL;
3628 if (!sync_files(&cp_clistate, mask)) {
3629 d_fprintf(stderr, _("could not handle files for share: "
3630 "%s\n"), info502.name);
3631 nt_status = NT_STATUS_UNSUCCESSFUL;
3636 nt_status = NT_STATUS_OK;
3641 cli_shutdown(cp_clistate.cli_share_src);
3644 cli_shutdown(cp_clistate.cli_share_dst);
3651 static int rpc_share_migrate_files(struct net_context *c, int argc, const char **argv)
3653 if (c->display_usage) {
3655 "net share migrate files\n"
3658 _("Migrate files to local server"));
3663 d_printf(_("no server to migrate\n"));
3667 return run_rpc_command(c, NULL, &ndr_table_srvsvc.syntax_id, 0,
3668 rpc_share_migrate_files_internals,
3673 * Migrate share-ACLs from a remote RPC server to the local RPC server.
3675 * All parameters are provided by the run_rpc_command function, except for
3676 * argc, argv which are passed through.
3678 * @param domain_sid The domain sid acquired from the remote server.
3679 * @param cli A cli_state connected to the server.
3680 * @param mem_ctx Talloc context, destroyed on completion of the function.
3681 * @param argc Standard main() style argc.
3682 * @param argv Standard main() style argv. Initial components are already
3685 * @return Normal NTSTATUS return.
3688 static NTSTATUS rpc_share_migrate_security_internals(struct net_context *c,
3689 const DOM_SID *domain_sid,
3690 const char *domain_name,
3691 struct cli_state *cli,
3692 struct rpc_pipe_client *pipe_hnd,
3693 TALLOC_CTX *mem_ctx,
3698 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
3699 struct srvsvc_NetShareInfoCtr ctr_src;
3700 union srvsvc_NetShareInfo info;
3702 struct rpc_pipe_client *srvsvc_pipe = NULL;
3703 struct cli_state *cli_dst = NULL;
3704 uint32 level = 502; /* includes secdesc */
3705 uint32_t parm_error = 0;
3707 result = get_share_info(c, pipe_hnd, mem_ctx, level, argc, argv,
3710 if (!W_ERROR_IS_OK(result))
3713 /* connect destination PI_SRVSVC */
3714 nt_status = connect_dst_pipe(c, &cli_dst, &srvsvc_pipe,
3715 &ndr_table_srvsvc.syntax_id);
3716 if (!NT_STATUS_IS_OK(nt_status))
3720 for (i = 0; i < ctr_src.ctr.ctr502->count; i++) {
3722 struct srvsvc_NetShareInfo502 info502 =
3723 ctr_src.ctr.ctr502->array[i];
3725 /* reset error-code */
3726 nt_status = NT_STATUS_UNSUCCESSFUL;
3728 if (!check_share_sanity(c, cli, info502.name, info502.type))
3731 printf(_("migrating: [%s], path: %s, comment: %s, including "
3733 info502.name, info502.path, info502.comment);
3736 display_sec_desc(info502.sd_buf.sd);
3738 /* FIXME: shouldn't we be able to just set the security descriptor ? */
3739 info.info502 = &info502;
3741 /* finally modify the share on the dst server */
3742 nt_status = rpccli_srvsvc_NetShareSetInfo(srvsvc_pipe, mem_ctx,
3743 srvsvc_pipe->desthost,
3749 if (!NT_STATUS_IS_OK(nt_status) || !W_ERROR_IS_OK(result)) {
3750 printf(_("cannot set share-acl: %s\n"),
3751 win_errstr(result));
3757 nt_status = NT_STATUS_OK;
3761 cli_shutdown(cli_dst);
3769 * Migrate share-acls from a RPC server to another.
3771 * @param argc Standard main() style argc.
3772 * @param argv Standard main() style argv. Initial components are already
3775 * @return A shell status integer (0 for success).
3777 static int rpc_share_migrate_security(struct net_context *c, int argc,
3780 if (c->display_usage) {
3782 "net rpc share migrate security\n"
3785 _("Migrate share-acls to local server"));
3790 d_printf(_("no server to migrate\n"));
3794 return run_rpc_command(c, NULL, &ndr_table_srvsvc.syntax_id, 0,
3795 rpc_share_migrate_security_internals,
3800 * Migrate shares (including share-definitions, share-acls and files with acls/attrs)
3801 * from one server to another.
3803 * @param argc Standard main() style argc.
3804 * @param argv Standard main() style argv. Initial components are already
3807 * @return A shell status integer (0 for success).
3810 static int rpc_share_migrate_all(struct net_context *c, int argc,
3815 if (c->display_usage) {
3817 "net rpc share migrate all\n"
3820 _("Migrates shares including all share settings"));
3825 d_printf(_("no server to migrate\n"));
3829 /* order is important. we don't want to be locked out by the share-acl
3830 * before copying files - gd */
3832 ret = run_rpc_command(c, NULL, &ndr_table_srvsvc.syntax_id, 0,
3833 rpc_share_migrate_shares_internals, argc, argv);
3837 ret = run_rpc_command(c, NULL, &ndr_table_srvsvc.syntax_id, 0,
3838 rpc_share_migrate_files_internals, argc, argv);
3842 return run_rpc_command(c, NULL, &ndr_table_srvsvc.syntax_id, 0,
3843 rpc_share_migrate_security_internals, argc,
3849 * 'net rpc share migrate' entrypoint.
3850 * @param argc Standard main() style argc.
3851 * @param argv Standard main() style argv. Initial components are already
3854 static int rpc_share_migrate(struct net_context *c, int argc, const char **argv)
3857 struct functable func[] = {
3860 rpc_share_migrate_all,
3862 N_("Migrate shares from remote to local server"),
3863 N_("net rpc share migrate all\n"
3864 " Migrate shares from remote to local server")
3868 rpc_share_migrate_files,
3870 N_("Migrate files from remote to local server"),
3871 N_("net rpc share migrate files\n"
3872 " Migrate files from remote to local server")
3876 rpc_share_migrate_security,
3878 N_("Migrate share-ACLs from remote to local server"),
3879 N_("net rpc share migrate security\n"
3880 " Migrate share-ACLs from remote to local server")
3884 rpc_share_migrate_shares,
3886 N_("Migrate shares from remote to local server"),
3887 N_("net rpc share migrate shares\n"
3888 " Migrate shares from remote to local server")
3890 {NULL, NULL, 0, NULL, NULL}
3893 net_mode_share = NET_MODE_SHARE_MIGRATE;
3895 return net_run_function(c, argc, argv, "net rpc share migrate", func);
3904 static int num_server_aliases;
3905 static struct full_alias *server_aliases;
3908 * Add an alias to the static list.
3910 static void push_alias(TALLOC_CTX *mem_ctx, struct full_alias *alias)
3912 if (server_aliases == NULL)
3913 server_aliases = SMB_MALLOC_ARRAY(struct full_alias, 100);
3915 server_aliases[num_server_aliases] = *alias;
3916 num_server_aliases += 1;
3920 * For a specific domain on the server, fetch all the aliases
3921 * and their members. Add all of them to the server_aliases.
3924 static NTSTATUS rpc_fetch_domain_aliases(struct rpc_pipe_client *pipe_hnd,
3925 TALLOC_CTX *mem_ctx,
3926 struct policy_handle *connect_pol,
3927 const DOM_SID *domain_sid)
3929 uint32 start_idx, max_entries, num_entries, i;
3930 struct samr_SamArray *groups = NULL;
3932 struct policy_handle domain_pol;
3934 /* Get domain policy handle */
3936 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
3938 MAXIMUM_ALLOWED_ACCESS,
3939 CONST_DISCARD(struct dom_sid2 *, domain_sid),
3941 if (!NT_STATUS_IS_OK(result))
3948 result = rpccli_samr_EnumDomainAliases(pipe_hnd, mem_ctx,
3954 for (i = 0; i < num_entries; i++) {
3956 struct policy_handle alias_pol;
3957 struct full_alias alias;
3958 struct lsa_SidArray sid_array;
3961 result = rpccli_samr_OpenAlias(pipe_hnd, mem_ctx,
3963 MAXIMUM_ALLOWED_ACCESS,
3964 groups->entries[i].idx,
3966 if (!NT_STATUS_IS_OK(result))
3969 result = rpccli_samr_GetMembersInAlias(pipe_hnd, mem_ctx,
3972 if (!NT_STATUS_IS_OK(result))
3975 alias.num_members = sid_array.num_sids;
3977 result = rpccli_samr_Close(pipe_hnd, mem_ctx, &alias_pol);
3978 if (!NT_STATUS_IS_OK(result))
3981 alias.members = NULL;
3983 if (alias.num_members > 0) {
3984 alias.members = SMB_MALLOC_ARRAY(DOM_SID, alias.num_members);
3986 for (j = 0; j < alias.num_members; j++)
3987 sid_copy(&alias.members[j],
3988 sid_array.sids[j].sid);
3991 sid_compose(&alias.sid, domain_sid,
3992 groups->entries[i].idx);
3994 push_alias(mem_ctx, &alias);
3996 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
3998 result = NT_STATUS_OK;
4001 rpccli_samr_Close(pipe_hnd, mem_ctx, &domain_pol);
4007 * Dump server_aliases as names for debugging purposes.
4010 static NTSTATUS rpc_aliaslist_dump(struct net_context *c,
4011 const DOM_SID *domain_sid,
4012 const char *domain_name,
4013 struct cli_state *cli,
4014 struct rpc_pipe_client *pipe_hnd,
4015 TALLOC_CTX *mem_ctx,
4021 struct policy_handle lsa_pol;
4023 result = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, true,
4024 SEC_FLAG_MAXIMUM_ALLOWED,
4026 if (!NT_STATUS_IS_OK(result))
4029 for (i=0; i<num_server_aliases; i++) {
4032 enum lsa_SidType *types;
4035 struct full_alias *alias = &server_aliases[i];
4037 result = rpccli_lsa_lookup_sids(pipe_hnd, mem_ctx, &lsa_pol, 1,
4039 &domains, &names, &types);
4040 if (!NT_STATUS_IS_OK(result))
4043 DEBUG(1, ("%s\\%s %d: ", domains[0], names[0], types[0]));
4045 if (alias->num_members == 0) {
4050 result = rpccli_lsa_lookup_sids(pipe_hnd, mem_ctx, &lsa_pol,
4053 &domains, &names, &types);
4055 if (!NT_STATUS_IS_OK(result) &&
4056 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
4059 for (j=0; j<alias->num_members; j++)
4060 DEBUG(1, ("%s\\%s (%d); ",
4061 domains[j] ? domains[j] : "*unknown*",
4062 names[j] ? names[j] : "*unknown*",types[j]));
4066 rpccli_lsa_Close(pipe_hnd, mem_ctx, &lsa_pol);
4068 return NT_STATUS_OK;
4072 * Fetch a list of all server aliases and their members into
4076 static NTSTATUS rpc_aliaslist_internals(struct net_context *c,
4077 const DOM_SID *domain_sid,
4078 const char *domain_name,
4079 struct cli_state *cli,
4080 struct rpc_pipe_client *pipe_hnd,
4081 TALLOC_CTX *mem_ctx,
4086 struct policy_handle connect_pol;
4088 result = rpccli_samr_Connect2(pipe_hnd, mem_ctx,
4090 MAXIMUM_ALLOWED_ACCESS,
4093 if (!NT_STATUS_IS_OK(result))
4096 result = rpc_fetch_domain_aliases(pipe_hnd, mem_ctx, &connect_pol,
4097 &global_sid_Builtin);
4099 if (!NT_STATUS_IS_OK(result))
4102 result = rpc_fetch_domain_aliases(pipe_hnd, mem_ctx, &connect_pol,
4105 rpccli_samr_Close(pipe_hnd, mem_ctx, &connect_pol);
4110 static void init_user_token(NT_USER_TOKEN *token, DOM_SID *user_sid)
4112 token->num_sids = 4;
4114 if (!(token->user_sids = SMB_MALLOC_ARRAY(DOM_SID, 4))) {
4115 d_fprintf(stderr, "malloc %s\n",_("failed"));
4116 token->num_sids = 0;
4120 token->user_sids[0] = *user_sid;
4121 sid_copy(&token->user_sids[1], &global_sid_World);
4122 sid_copy(&token->user_sids[2], &global_sid_Network);
4123 sid_copy(&token->user_sids[3], &global_sid_Authenticated_Users);
4126 static void free_user_token(NT_USER_TOKEN *token)
4128 SAFE_FREE(token->user_sids);
4131 static void add_sid_to_token(NT_USER_TOKEN *token, DOM_SID *sid)
4133 if (is_sid_in_token(token, sid))
4136 token->user_sids = SMB_REALLOC_ARRAY(token->user_sids, DOM_SID, token->num_sids+1);
4137 if (!token->user_sids) {
4141 sid_copy(&token->user_sids[token->num_sids], sid);
4143 token->num_sids += 1;
4148 NT_USER_TOKEN token;
4151 static void dump_user_token(struct user_token *token)
4155 d_printf("%s\n", token->name);
4157 for (i=0; i<token->token.num_sids; i++) {
4158 d_printf(" %s\n", sid_string_tos(&token->token.user_sids[i]));
4162 static bool is_alias_member(DOM_SID *sid, struct full_alias *alias)
4166 for (i=0; i<alias->num_members; i++) {
4167 if (sid_compare(sid, &alias->members[i]) == 0)
4174 static void collect_sid_memberships(NT_USER_TOKEN *token, DOM_SID sid)
4178 for (i=0; i<num_server_aliases; i++) {
4179 if (is_alias_member(&sid, &server_aliases[i]))
4180 add_sid_to_token(token, &server_aliases[i].sid);
4185 * We got a user token with all the SIDs we can know about without asking the
4186 * server directly. These are the user and domain group sids. All of these can
4187 * be members of aliases. So scan the list of aliases for each of the SIDs and
4188 * add them to the token.
4191 static void collect_alias_memberships(NT_USER_TOKEN *token)
4193 int num_global_sids = token->num_sids;
4196 for (i=0; i<num_global_sids; i++) {
4197 collect_sid_memberships(token, token->user_sids[i]);
4201 static bool get_user_sids(const char *domain, const char *user, NT_USER_TOKEN *token)
4203 wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
4204 enum wbcSidType type;
4206 struct wbcDomainSid wsid;
4207 char *sid_str = NULL;
4209 uint32_t num_groups;
4210 gid_t *groups = NULL;
4213 fstr_sprintf(full_name, "%s%c%s",
4214 domain, *lp_winbind_separator(), user);
4216 /* First let's find out the user sid */
4218 wbc_status = wbcLookupName(domain, user, &wsid, &type);
4220 if (!WBC_ERROR_IS_OK(wbc_status)) {
4221 DEBUG(1, ("winbind could not find %s: %s\n",
4222 full_name, wbcErrorString(wbc_status)));
4226 wbc_status = wbcSidToString(&wsid, &sid_str);
4227 if (!WBC_ERROR_IS_OK(wbc_status)) {
4231 if (type != SID_NAME_USER) {
4232 wbcFreeMemory(sid_str);
4233 DEBUG(1, ("%s is not a user\n", full_name));
4237 if (!string_to_sid(&user_sid, sid_str)) {
4238 DEBUG(1,("Could not convert sid %s from string\n", sid_str));
4242 wbcFreeMemory(sid_str);
4245 init_user_token(token, &user_sid);
4247 /* And now the groups winbind knows about */
4249 wbc_status = wbcGetGroups(full_name, &num_groups, &groups);
4250 if (!WBC_ERROR_IS_OK(wbc_status)) {
4251 DEBUG(1, ("winbind could not get groups of %s: %s\n",
4252 full_name, wbcErrorString(wbc_status)));
4256 for (i = 0; i < num_groups; i++) {
4257 gid_t gid = groups[i];
4260 wbc_status = wbcGidToSid(gid, &wsid);
4261 if (!WBC_ERROR_IS_OK(wbc_status)) {
4262 DEBUG(1, ("winbind could not find SID of gid %u: %s\n",
4263 (unsigned int)gid, wbcErrorString(wbc_status)));
4264 wbcFreeMemory(groups);
4268 wbc_status = wbcSidToString(&wsid, &sid_str);
4269 if (!WBC_ERROR_IS_OK(wbc_status)) {
4270 wbcFreeMemory(groups);
4274 DEBUG(3, (" %s\n", sid_str));
4276 string_to_sid(&sid, sid_str);
4277 wbcFreeMemory(sid_str);
4280 add_sid_to_token(token, &sid);
4282 wbcFreeMemory(groups);
4288 * Get a list of all user tokens we want to look at
4291 static bool get_user_tokens(struct net_context *c, int *num_tokens,
4292 struct user_token **user_tokens)
4294 wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
4295 uint32_t i, num_users;
4297 struct user_token *result;
4298 TALLOC_CTX *frame = NULL;
4300 if (lp_winbind_use_default_domain() &&
4301 (c->opt_target_workgroup == NULL)) {
4302 d_fprintf(stderr, _("winbind use default domain = yes set, "
4303 "please specify a workgroup\n"));
4307 /* Send request to winbind daemon */
4309 wbc_status = wbcListUsers(NULL, &num_users, &users);
4310 if (!WBC_ERROR_IS_OK(wbc_status)) {
4311 DEBUG(1, (_("winbind could not list users: %s\n"),
4312 wbcErrorString(wbc_status)));
4316 result = SMB_MALLOC_ARRAY(struct user_token, num_users);
4318 if (result == NULL) {
4319 DEBUG(1, ("Could not malloc sid array\n"));
4320 wbcFreeMemory(users);
4324 frame = talloc_stackframe();
4325 for (i=0; i < num_users; i++) {
4326 fstring domain, user;
4329 fstrcpy(result[i].name, users[i]);
4331 p = strchr(users[i], *lp_winbind_separator());
4333 DEBUG(3, ("%s\n", users[i]));
4336 fstrcpy(domain, c->opt_target_workgroup);
4337 fstrcpy(user, users[i]);
4340 fstrcpy(domain, users[i]);
4345 get_user_sids(domain, user, &(result[i].token));
4349 wbcFreeMemory(users);
4351 *num_tokens = num_users;
4352 *user_tokens = result;
4357 static bool get_user_tokens_from_file(FILE *f,
4359 struct user_token **tokens)
4361 struct user_token *token = NULL;
4366 if (fgets(line, sizeof(line)-1, f) == NULL) {
4370 if ((strlen(line) > 0) && (line[strlen(line)-1] == '\n')) {
4371 line[strlen(line)-1] = '\0';
4374 if (line[0] == ' ') {
4378 if(!string_to_sid(&sid, &line[1])) {
4379 DEBUG(1,("get_user_tokens_from_file: Could "
4380 "not convert sid %s \n",&line[1]));
4384 if (token == NULL) {
4385 DEBUG(0, ("File does not begin with username"));
4389 add_sid_to_token(&token->token, &sid);
4393 /* And a new user... */
4396 *tokens = SMB_REALLOC_ARRAY(*tokens, struct user_token, *num_tokens);
4397 if (*tokens == NULL) {
4398 DEBUG(0, ("Could not realloc tokens\n"));
4402 token = &((*tokens)[*num_tokens-1]);
4404 fstrcpy(token->name, line);
4405 token->token.num_sids = 0;
4406 token->token.user_sids = NULL;
4415 * Show the list of all users that have access to a share
4418 static void show_userlist(struct rpc_pipe_client *pipe_hnd,
4419 TALLOC_CTX *mem_ctx,
4420 const char *netname,
4422 struct user_token *tokens)
4425 struct security_descriptor *share_sd = NULL;
4426 struct security_descriptor *root_sd = NULL;
4427 struct cli_state *cli = rpc_pipe_np_smb_conn(pipe_hnd);
4429 union srvsvc_NetShareInfo info;
4434 status = rpccli_srvsvc_NetShareGetInfo(pipe_hnd, mem_ctx,
4441 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
4442 DEBUG(1, ("Coult not query secdesc for share %s\n",
4447 share_sd = info.info502->sd_buf.sd;
4448 if (share_sd == NULL) {
4449 DEBUG(1, ("Got no secdesc for share %s\n",
4455 if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, netname, "A:", "", 0))) {
4459 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, "\\", 0, READ_CONTROL_ACCESS, 0,
4460 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0x0, 0x0, &fnum))) {
4461 root_sd = cli_query_secdesc(cli, fnum, mem_ctx);
4464 for (i=0; i<num_tokens; i++) {
4467 if (share_sd != NULL) {
4468 status = se_access_check(share_sd, &tokens[i].token,
4471 if (!NT_STATUS_IS_OK(status)) {
4472 DEBUG(1, ("Could not check share_sd for "
4479 if (root_sd == NULL) {
4480 d_printf(" %s\n", tokens[i].name);
4484 status = se_access_check(root_sd, &tokens[i].token,
4486 if (!NT_STATUS_IS_OK(status)) {
4487 DEBUG(1, ("Could not check root_sd for user %s\n",
4491 d_printf(" %s\n", tokens[i].name);
4494 if (fnum != (uint16_t)-1)
4495 cli_close(cli, fnum);
4507 static void collect_share(const char *name, uint32 m,
4508 const char *comment, void *state)
4510 struct share_list *share_list = (struct share_list *)state;
4512 if (m != STYPE_DISKTREE)
4515 share_list->num_shares += 1;
4516 share_list->shares = SMB_REALLOC_ARRAY(share_list->shares, char *, share_list->num_shares);
4517 if (!share_list->shares) {
4518 share_list->num_shares = 0;
4521 share_list->shares[share_list->num_shares-1] = SMB_STRDUP(name);
4525 * List shares on a remote RPC server, including the security descriptors.
4527 * All parameters are provided by the run_rpc_command function, except for
4528 * argc, argv which are passed through.
4530 * @param domain_sid The domain sid acquired from the remote server.
4531 * @param cli A cli_state connected to the server.
4532 * @param mem_ctx Talloc context, destroyed on completion of the function.
4533 * @param argc Standard main() style argc.
4534 * @param argv Standard main() style argv. Initial components are already
4537 * @return Normal NTSTATUS return.
4540 static NTSTATUS rpc_share_allowedusers_internals(struct net_context *c,
4541 const DOM_SID *domain_sid,
4542 const char *domain_name,
4543 struct cli_state *cli,
4544 struct rpc_pipe_client *pipe_hnd,
4545 TALLOC_CTX *mem_ctx,
4554 struct user_token *tokens = NULL;
4557 struct share_list share_list;
4562 f = fopen(argv[0], "r");
4566 DEBUG(0, ("Could not open userlist: %s\n", strerror(errno)));
4567 return NT_STATUS_UNSUCCESSFUL;
4570 r = get_user_tokens_from_file(f, &num_tokens, &tokens);
4576 DEBUG(0, ("Could not read users from file\n"));
4577 return NT_STATUS_UNSUCCESSFUL;
4580 for (i=0; i<num_tokens; i++)
4581 collect_alias_memberships(&tokens[i].token);
4583 share_list.num_shares = 0;
4584 share_list.shares = NULL;
4586 ret = cli_RNetShareEnum(cli, collect_share, &share_list);
4589 DEBUG(0, ("Error returning browse list: %s\n",
4594 for (i = 0; i < share_list.num_shares; i++) {
4595 char *netname = share_list.shares[i];
4597 if (netname[strlen(netname)-1] == '$')
4600 d_printf("%s\n", netname);
4602 show_userlist(pipe_hnd, mem_ctx, netname,
4603 num_tokens, tokens);
4606 for (i=0; i<num_tokens; i++) {
4607 free_user_token(&tokens[i].token);
4610 SAFE_FREE(share_list.shares);
4612 return NT_STATUS_OK;
4615 static int rpc_share_allowedusers(struct net_context *c, int argc,
4620 if (c->display_usage) {
4622 "net rpc share allowedusers\n"
4625 _("List allowed users"));
4629 result = run_rpc_command(c, NULL, &ndr_table_samr.syntax_id, 0,
4630 rpc_aliaslist_internals,
4635 result = run_rpc_command(c, NULL, &ndr_table_lsarpc.syntax_id, 0,
4641 return run_rpc_command(c, NULL, &ndr_table_srvsvc.syntax_id, 0,
4642 rpc_share_allowedusers_internals,
4646 int net_usersidlist(struct net_context *c, int argc, const char **argv)
4649 struct user_token *tokens = NULL;
4653 net_usersidlist_usage(c, argc, argv);
4657 if (!get_user_tokens(c, &num_tokens, &tokens)) {
4658 DEBUG(0, ("Could not get the user/sid list\n"));
4662 for (i=0; i<num_tokens; i++) {
4663 dump_user_token(&tokens[i]);
4664 free_user_token(&tokens[i].token);
4671 int net_usersidlist_usage(struct net_context *c, int argc, const char **argv)
4673 d_printf(_("net usersidlist\n"
4674 "\tprints out a list of all users the running winbind knows\n"
4675 "\tabout, together with all their SIDs. This is used as\n"
4676 "\tinput to the 'net rpc share allowedusers' command.\n\n"));
4678 net_common_flags_usage(c, argc, argv);
4683 * 'net rpc share' entrypoint.
4684 * @param argc Standard main() style argc.
4685 * @param argv Standard main() style argv. Initial components are already
4689 int net_rpc_share(struct net_context *c, int argc, const char **argv)
4691 NET_API_STATUS status;
4693 struct functable func[] = {
4699 N_("net rpc share add\n"
4707 N_("net rpc share delete\n"
4712 rpc_share_allowedusers,
4714 N_("Modify allowed users"),
4715 N_("net rpc share allowedusers\n"
4716 " Modify allowed users")
4722 N_("Migrate share to local server"),
4723 N_("net rpc share migrate\n"
4724 " Migrate share to local server")
4731 N_("net rpc share list\n"
4734 {NULL, NULL, 0, NULL, NULL}
4737 status = libnetapi_init(&c->netapi_ctx);
4741 libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
4742 libnetapi_set_password(c->netapi_ctx, c->opt_password);
4743 if (c->opt_kerberos) {
4744 libnetapi_set_use_kerberos(c->netapi_ctx);
4748 if (c->display_usage) {
4753 " Alias for net rpc share list\n"));
4754 net_display_usage_from_functable(func);
4758 return rpc_share_list(c, argc, argv);
4761 return net_run_function(c, argc, argv, "net rpc share", func);
4764 static NTSTATUS rpc_sh_share_list(struct net_context *c,
4765 TALLOC_CTX *mem_ctx,
4766 struct rpc_sh_ctx *ctx,
4767 struct rpc_pipe_client *pipe_hnd,
4768 int argc, const char **argv)
4771 return werror_to_ntstatus(W_ERROR(rpc_share_list(c, argc, argv)));
4774 static NTSTATUS rpc_sh_share_add(struct net_context *c,
4775 TALLOC_CTX *mem_ctx,
4776 struct rpc_sh_ctx *ctx,
4777 struct rpc_pipe_client *pipe_hnd,
4778 int argc, const char **argv)
4780 NET_API_STATUS status;
4781 uint32_t parm_err = 0;
4782 struct SHARE_INFO_2 i2;
4784 if ((argc < 2) || (argc > 3)) {
4785 d_fprintf(stderr, _("Usage: %s <share> <path> [comment]\n"),
4787 return NT_STATUS_INVALID_PARAMETER;
4790 i2.shi2_netname = argv[0];
4791 i2.shi2_type = STYPE_DISKTREE;
4792 i2.shi2_remark = (argc == 3) ? argv[2] : "";
4793 i2.shi2_permissions = 0;
4794 i2.shi2_max_uses = 0;
4795 i2.shi2_current_uses = 0;
4796 i2.shi2_path = argv[1];
4797 i2.shi2_passwd = NULL;
4799 status = NetShareAdd(pipe_hnd->desthost,
4804 return werror_to_ntstatus(W_ERROR(status));
4807 static NTSTATUS rpc_sh_share_delete(struct net_context *c,
4808 TALLOC_CTX *mem_ctx,
4809 struct rpc_sh_ctx *ctx,
4810 struct rpc_pipe_client *pipe_hnd,
4811 int argc, const char **argv)
4814 d_fprintf(stderr, "%s %s <share>\n", _("Usage:"), ctx->whoami);
4815 return NT_STATUS_INVALID_PARAMETER;
4818 return werror_to_ntstatus(W_ERROR(NetShareDel(pipe_hnd->desthost, argv[0], 0)));
4821 static NTSTATUS rpc_sh_share_info(struct net_context *c,
4822 TALLOC_CTX *mem_ctx,
4823 struct rpc_sh_ctx *ctx,
4824 struct rpc_pipe_client *pipe_hnd,
4825 int argc, const char **argv)
4827 union srvsvc_NetShareInfo info;
4832 d_fprintf(stderr, "%s %s <share>\n", _("Usage:"), ctx->whoami);
4833 return NT_STATUS_INVALID_PARAMETER;
4836 status = rpccli_srvsvc_NetShareGetInfo(pipe_hnd, mem_ctx,
4842 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
4846 d_printf(_("Name: %s\n"), info.info2->name);
4847 d_printf(_("Comment: %s\n"), info.info2->comment);
4848 d_printf(_("Path: %s\n"), info.info2->path);
4849 d_printf(_("Password: %s\n"), info.info2->password);
4852 return werror_to_ntstatus(result);
4855 struct rpc_sh_cmd *net_rpc_share_cmds(struct net_context *c, TALLOC_CTX *mem_ctx,
4856 struct rpc_sh_ctx *ctx)
4858 static struct rpc_sh_cmd cmds[] = {
4860 { "list", NULL, &ndr_table_srvsvc.syntax_id, rpc_sh_share_list,
4861 N_("List available shares") },
4863 { "add", NULL, &ndr_table_srvsvc.syntax_id, rpc_sh_share_add,
4864 N_("Add a share") },
4866 { "delete", NULL, &ndr_table_srvsvc.syntax_id, rpc_sh_share_delete,
4867 N_("Delete a share") },
4869 { "info", NULL, &ndr_table_srvsvc.syntax_id, rpc_sh_share_info,
4870 N_("Get information about a share") },
4872 { NULL, NULL, 0, NULL, NULL }
4878 /****************************************************************************/
4880 static int rpc_file_usage(struct net_context *c, int argc, const char **argv)
4882 return net_file_usage(c, argc, argv);
4886 * Close a file on a remote RPC server.
4888 * @param argc Standard main() style argc.
4889 * @param argv Standard main() style argv. Initial components are already
4892 * @return A shell status integer (0 for success).
4894 static int rpc_file_close(struct net_context *c, int argc, const char **argv)
4896 if (argc < 1 || c->display_usage) {
4897 return rpc_file_usage(c, argc, argv);
4900 return NetFileClose(c->opt_host, atoi(argv[0]));
4904 * Formatted print of open file info
4906 * @param r struct FILE_INFO_3 contents
4909 static void display_file_info_3(struct FILE_INFO_3 *r)
4911 d_printf("%-7.1d %-20.20s 0x%-4.2x %-6.1d %s\n",
4912 r->fi3_id, r->fi3_username, r->fi3_permissions,
4913 r->fi3_num_locks, r->fi3_pathname);
4917 * List files for a user on a remote RPC server.
4919 * @param argc Standard main() style argc.
4920 * @param argv Standard main() style argv. Initial components are already
4923 * @return A shell status integer (0 for success)..
4926 static int rpc_file_user(struct net_context *c, int argc, const char **argv)
4928 NET_API_STATUS status;
4929 uint32 preferred_len = 0xffffffff, i;
4930 const char *username=NULL;
4931 uint32_t total_entries = 0;
4932 uint32_t entries_read = 0;
4933 uint32_t resume_handle = 0;
4934 struct FILE_INFO_3 *i3 = NULL;
4936 if (c->display_usage) {
4937 return rpc_file_usage(c, argc, argv);
4940 /* if argc > 0, must be user command */
4942 username = smb_xstrdup(argv[0]);
4945 status = NetFileEnum(c->opt_host,
4949 (uint8_t **)(void *)&i3,
4959 /* Display results */
4962 "\nEnumerating open files on remote server:\n\n"
4963 "\nFileId Opened by Perms Locks Path"
4964 "\n------ --------- ----- ----- ---- \n"));
4965 for (i = 0; i < entries_read; i++) {
4966 display_file_info_3(&i3[i]);
4973 * 'net rpc file' entrypoint.
4974 * @param argc Standard main() style argc.
4975 * @param argv Standard main() style argv. Initial components are already
4979 int net_rpc_file(struct net_context *c, int argc, const char **argv)
4981 NET_API_STATUS status;
4983 struct functable func[] = {
4988 N_("Close opened file"),
4989 N_("net rpc file close\n"
4990 " Close opened file")
4996 N_("List files opened by user"),
4997 N_("net rpc file user\n"
4998 " List files opened by user")
5005 N_("Display information about opened file"),
5006 N_("net rpc file info\n"
5007 " Display information about opened file")
5010 {NULL, NULL, 0, NULL, NULL}
5013 status = libnetapi_init(&c->netapi_ctx);
5017 libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
5018 libnetapi_set_password(c->netapi_ctx, c->opt_password);
5019 if (c->opt_kerberos) {
5020 libnetapi_set_use_kerberos(c->netapi_ctx);
5024 if (c->display_usage) {
5025 d_printf(_("Usage:\n"));
5026 d_printf(_("net rpc file\n"
5027 " List opened files\n"));
5028 net_display_usage_from_functable(func);
5032 return rpc_file_user(c, argc, argv);
5035 return net_run_function(c, argc, argv, "net rpc file", func);
5039 * ABORT the shutdown of a remote RPC Server, over initshutdown pipe.
5041 * All parameters are provided by the run_rpc_command function, except for
5042 * argc, argv which are passed through.
5044 * @param c A net_context structure.
5045 * @param domain_sid The domain sid acquired from the remote server.
5046 * @param cli A cli_state connected to the server.
5047 * @param mem_ctx Talloc context, destroyed on completion of the function.
5048 * @param argc Standard main() style argc.
5049 * @param argv Standard main() style argv. Initial components are already
5052 * @return Normal NTSTATUS return.
5055 static NTSTATUS rpc_shutdown_abort_internals(struct net_context *c,
5056 const DOM_SID *domain_sid,
5057 const char *domain_name,
5058 struct cli_state *cli,
5059 struct rpc_pipe_client *pipe_hnd,
5060 TALLOC_CTX *mem_ctx,
5064 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
5066 result = rpccli_initshutdown_Abort(pipe_hnd, mem_ctx, NULL, NULL);
5068 if (NT_STATUS_IS_OK(result)) {
5069 d_printf(_("\nShutdown successfully aborted\n"));
5070 DEBUG(5,("cmd_shutdown_abort: query succeeded\n"));
5072 DEBUG(5,("cmd_shutdown_abort: query failed\n"));
5078 * ABORT the shutdown of a remote RPC Server, over winreg pipe.
5080 * All parameters are provided by the run_rpc_command function, except for
5081 * argc, argv which are passed through.
5083 * @param c A net_context structure.
5084 * @param domain_sid The domain sid acquired from the remote server.
5085 * @param cli A cli_state connected to the server.
5086 * @param mem_ctx Talloc context, destroyed on completion of the function.
5087 * @param argc Standard main() style argc.
5088 * @param argv Standard main() style argv. Initial components are already
5091 * @return Normal NTSTATUS return.
5094 static NTSTATUS rpc_reg_shutdown_abort_internals(struct net_context *c,
5095 const DOM_SID *domain_sid,
5096 const char *domain_name,
5097 struct cli_state *cli,
5098 struct rpc_pipe_client *pipe_hnd,
5099 TALLOC_CTX *mem_ctx,
5103 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
5105 result = rpccli_winreg_AbortSystemShutdown(pipe_hnd, mem_ctx, NULL, NULL);
5107 if (NT_STATUS_IS_OK(result)) {
5108 d_printf(_("\nShutdown successfully aborted\n"));
5109 DEBUG(5,("cmd_reg_abort_shutdown: query succeeded\n"));
5111 DEBUG(5,("cmd_reg_abort_shutdown: query failed\n"));
5117 * ABORT the shutdown of a remote RPC server.
5119 * @param argc Standard main() style argc.
5120 * @param argv Standard main() style argv. Initial components are already
5123 * @return A shell status integer (0 for success).
5126 static int rpc_shutdown_abort(struct net_context *c, int argc,
5131 if (c->display_usage) {
5133 "net rpc abortshutdown\n"
5136 _("Abort a scheduled shutdown"));
5140 rc = run_rpc_command(c, NULL, &ndr_table_initshutdown.syntax_id, 0,
5141 rpc_shutdown_abort_internals, argc, argv);
5146 DEBUG(1, ("initshutdown pipe didn't work, trying winreg pipe\n"));
5148 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
5149 rpc_reg_shutdown_abort_internals,
5154 * Shut down a remote RPC Server via initshutdown pipe.
5156 * All parameters are provided by the run_rpc_command function, except for
5157 * argc, argv which are passed through.
5159 * @param c A net_context structure.
5160 * @param domain_sid The domain sid acquired from the remote server.
5161 * @param cli A cli_state connected to the server.
5162 * @param mem_ctx Talloc context, destroyed on completion of the function.
5163 * @param argc Standard main() style argc.
5164 * @param argv Standard main() style argv. Initial components are already
5167 * @return Normal NTSTATUS return.
5170 NTSTATUS rpc_init_shutdown_internals(struct net_context *c,
5171 const DOM_SID *domain_sid,
5172 const char *domain_name,
5173 struct cli_state *cli,
5174 struct rpc_pipe_client *pipe_hnd,
5175 TALLOC_CTX *mem_ctx,
5179 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
5180 const char *msg = N_("This machine will be shutdown shortly");
5181 uint32 timeout = 20;
5182 struct lsa_StringLarge msg_string;
5184 if (c->opt_comment) {
5185 msg = c->opt_comment;
5187 if (c->opt_timeout) {
5188 timeout = c->opt_timeout;
5191 msg_string.string = msg;
5193 /* create an entry */
5194 result = rpccli_initshutdown_Init(pipe_hnd, mem_ctx, NULL,
5195 &msg_string, timeout, c->opt_force, c->opt_reboot,
5198 if (NT_STATUS_IS_OK(result)) {
5199 d_printf(_("\nShutdown of remote machine succeeded\n"));
5200 DEBUG(5,("Shutdown of remote machine succeeded\n"));
5202 DEBUG(1,("Shutdown of remote machine failed!\n"));
5208 * Shut down a remote RPC Server via winreg pipe.
5210 * All parameters are provided by the run_rpc_command function, except for
5211 * argc, argv which are passed through.
5213 * @param c A net_context structure.
5214 * @param domain_sid The domain sid acquired from the remote server.
5215 * @param cli A cli_state connected to the server.
5216 * @param mem_ctx Talloc context, destroyed on completion of the function.
5217 * @param argc Standard main() style argc.
5218 * @param argv Standard main() style argv. Initial components are already
5221 * @return Normal NTSTATUS return.
5224 NTSTATUS rpc_reg_shutdown_internals(struct net_context *c,
5225 const DOM_SID *domain_sid,
5226 const char *domain_name,
5227 struct cli_state *cli,
5228 struct rpc_pipe_client *pipe_hnd,
5229 TALLOC_CTX *mem_ctx,
5233 const char *msg = N_("This machine will be shutdown shortly");
5234 uint32 timeout = 20;
5235 struct lsa_StringLarge msg_string;
5239 if (c->opt_comment) {
5240 msg = c->opt_comment;
5242 msg_string.string = msg;
5244 if (c->opt_timeout) {
5245 timeout = c->opt_timeout;
5248 /* create an entry */
5249 result = rpccli_winreg_InitiateSystemShutdown(pipe_hnd, mem_ctx, NULL,
5250 &msg_string, timeout, c->opt_force, c->opt_reboot,
5253 if (NT_STATUS_IS_OK(result)) {
5254 d_printf(_("\nShutdown of remote machine succeeded\n"));
5256 d_fprintf(stderr, "\nShutdown of remote machine failed\n");
5257 if ( W_ERROR_EQUAL(werr, WERR_MACHINE_LOCKED) )
5258 d_fprintf(stderr, "\nMachine locked, use -f switch to force\n");
5260 d_fprintf(stderr, "\nresult was: %s\n", win_errstr(werr));
5267 * Shut down a remote RPC server.
5269 * @param argc Standard main() style argc.
5270 * @param argv Standard main() style argv. Initial components are already
5273 * @return A shell status integer (0 for success).
5276 static int rpc_shutdown(struct net_context *c, int argc, const char **argv)
5280 if (c->display_usage) {
5282 "net rpc shutdown\n"
5285 _("Shut down a remote RPC server"));
5289 rc = run_rpc_command(c, NULL, &ndr_table_initshutdown.syntax_id, 0,
5290 rpc_init_shutdown_internals, argc, argv);
5293 DEBUG(1, ("initshutdown pipe failed, trying winreg pipe\n"));
5294 rc = run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
5295 rpc_reg_shutdown_internals, argc, argv);
5301 /***************************************************************************
5302 NT Domain trusts code (i.e. 'net rpc trustdom' functionality)
5303 ***************************************************************************/
5306 * Add interdomain trust account to the RPC server.
5307 * All parameters (except for argc and argv) are passed by run_rpc_command
5310 * @param c A net_context structure.
5311 * @param domain_sid The domain sid acquired from the server.
5312 * @param cli A cli_state connected to the server.
5313 * @param mem_ctx Talloc context, destroyed on completion of the function.
5314 * @param argc Standard main() style argc.
5315 * @param argv Standard main() style argv. Initial components are already
5318 * @return normal NTSTATUS return code.
5321 static NTSTATUS rpc_trustdom_add_internals(struct net_context *c,
5322 const DOM_SID *domain_sid,
5323 const char *domain_name,
5324 struct cli_state *cli,
5325 struct rpc_pipe_client *pipe_hnd,
5326 TALLOC_CTX *mem_ctx,
5330 struct policy_handle connect_pol, domain_pol, user_pol;
5331 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
5333 struct lsa_String lsa_acct_name;
5335 uint32 acct_flags=0;
5337 uint32_t access_granted = 0;
5338 union samr_UserInfo info;
5339 unsigned int orig_timeout;
5344 _(" net rpc trustdom add <domain_name> "
5345 "<trust password>\n"));
5346 return NT_STATUS_INVALID_PARAMETER;
5350 * Make valid trusting domain account (ie. uppercased and with '$' appended)
5353 if (asprintf(&acct_name, "%s$", argv[0]) < 0) {
5354 return NT_STATUS_NO_MEMORY;
5357 strupper_m(acct_name);
5359 init_lsa_String(&lsa_acct_name, acct_name);
5361 /* Get samr policy handle */
5362 result = rpccli_samr_Connect2(pipe_hnd, mem_ctx,
5364 MAXIMUM_ALLOWED_ACCESS,
5366 if (!NT_STATUS_IS_OK(result)) {
5370 /* Get domain policy handle */
5371 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
5373 MAXIMUM_ALLOWED_ACCESS,
5374 CONST_DISCARD(struct dom_sid2 *, domain_sid),
5376 if (!NT_STATUS_IS_OK(result)) {
5380 /* This call can take a long time - allow the server to time out.
5381 * 35 seconds should do it. */
5383 orig_timeout = rpccli_set_timeout(pipe_hnd, 35000);
5385 /* Create trusting domain's account */
5386 acb_info = ACB_NORMAL;
5387 acct_flags = SEC_GENERIC_READ | SEC_GENERIC_WRITE | SEC_GENERIC_EXECUTE |
5388 SEC_STD_WRITE_DAC | SEC_STD_DELETE |
5389 SAMR_USER_ACCESS_SET_PASSWORD |
5390 SAMR_USER_ACCESS_GET_ATTRIBUTES |
5391 SAMR_USER_ACCESS_SET_ATTRIBUTES;
5393 result = rpccli_samr_CreateUser2(pipe_hnd, mem_ctx,
5402 /* And restore our original timeout. */
5403 rpccli_set_timeout(pipe_hnd, orig_timeout);
5405 if (!NT_STATUS_IS_OK(result)) {
5406 d_printf(_("net rpc trustdom add: create user %s failed %s\n"),
5407 acct_name, nt_errstr(result));
5412 struct samr_CryptPassword crypt_pwd;
5414 ZERO_STRUCT(info.info23);
5416 init_samr_CryptPassword(argv[1],
5417 &cli->user_session_key,
5420 info.info23.info.fields_present = SAMR_FIELD_ACCT_FLAGS |
5421 SAMR_FIELD_NT_PASSWORD_PRESENT;
5422 info.info23.info.acct_flags = ACB_DOMTRUST;
5423 info.info23.password = crypt_pwd;
5425 result = rpccli_samr_SetUserInfo2(pipe_hnd, mem_ctx,
5430 if (!NT_STATUS_IS_OK(result)) {
5431 DEBUG(0,("Could not set trust account password: %s\n",
5432 nt_errstr(result)));
5438 SAFE_FREE(acct_name);
5443 * Create interdomain trust account for a remote domain.
5445 * @param argc Standard argc.
5446 * @param argv Standard argv without initial components.
5448 * @return Integer status (0 means success).
5451 static int rpc_trustdom_add(struct net_context *c, int argc, const char **argv)
5453 if (argc > 0 && !c->display_usage) {
5454 return run_rpc_command(c, NULL, &ndr_table_samr.syntax_id, 0,
5455 rpc_trustdom_add_internals, argc, argv);
5459 _("net rpc trustdom add <domain_name> <trust "
5467 * Remove interdomain trust account from the RPC server.
5468 * All parameters (except for argc and argv) are passed by run_rpc_command
5471 * @param c A net_context structure.
5472 * @param domain_sid The domain sid acquired from the server.
5473 * @param cli A cli_state connected to the server.
5474 * @param mem_ctx Talloc context, destroyed on completion of the function.
5475 * @param argc Standard main() style argc.
5476 * @param argv Standard main() style argv. Initial components are already
5479 * @return normal NTSTATUS return code.
5482 static NTSTATUS rpc_trustdom_del_internals(struct net_context *c,
5483 const DOM_SID *domain_sid,
5484 const char *domain_name,
5485 struct cli_state *cli,
5486 struct rpc_pipe_client *pipe_hnd,
5487 TALLOC_CTX *mem_ctx,
5491 struct policy_handle connect_pol, domain_pol, user_pol;
5492 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
5494 DOM_SID trust_acct_sid;
5495 struct samr_Ids user_rids, name_types;
5496 struct lsa_String lsa_acct_name;
5501 _(" net rpc trustdom del <domain_name>\n"));
5502 return NT_STATUS_INVALID_PARAMETER;
5506 * Make valid trusting domain account (ie. uppercased and with '$' appended)
5508 acct_name = talloc_asprintf(mem_ctx, "%s$", argv[0]);
5510 if (acct_name == NULL)
5511 return NT_STATUS_NO_MEMORY;
5513 strupper_m(acct_name);
5515 /* Get samr policy handle */
5516 result = rpccli_samr_Connect2(pipe_hnd, mem_ctx,
5518 MAXIMUM_ALLOWED_ACCESS,
5520 if (!NT_STATUS_IS_OK(result)) {
5524 /* Get domain policy handle */
5525 result = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
5527 MAXIMUM_ALLOWED_ACCESS,
5528 CONST_DISCARD(struct dom_sid2 *, domain_sid),
5530 if (!NT_STATUS_IS_OK(result)) {
5534 init_lsa_String(&lsa_acct_name, acct_name);
5536 result = rpccli_samr_LookupNames(pipe_hnd, mem_ctx,
5543 if (!NT_STATUS_IS_OK(result)) {
5544 d_printf(_("net rpc trustdom del: LookupNames on user %s "
5546 acct_name, nt_errstr(result) );
5550 result = rpccli_samr_OpenUser(pipe_hnd, mem_ctx,
5552 MAXIMUM_ALLOWED_ACCESS,
5556 if (!NT_STATUS_IS_OK(result)) {
5557 d_printf(_("net rpc trustdom del: OpenUser on user %s failed "
5559 acct_name, nt_errstr(result) );
5563 /* append the rid to the domain sid */
5564 if (!sid_compose(&trust_acct_sid, domain_sid, user_rids.ids[0])) {
5568 /* remove the sid */
5570 result = rpccli_samr_RemoveMemberFromForeignDomain(pipe_hnd, mem_ctx,
5573 if (!NT_STATUS_IS_OK(result)) {
5574 d_printf(_("net rpc trustdom del: RemoveMemberFromForeignDomain"
5575 " on user %s failed %s\n"),
5576 acct_name, nt_errstr(result) );
5582 result = rpccli_samr_DeleteUser(pipe_hnd, mem_ctx,
5585 if (!NT_STATUS_IS_OK(result)) {
5586 d_printf(_("net rpc trustdom del: DeleteUser on user %s failed "
5588 acct_name, nt_errstr(result) );
5592 if (!NT_STATUS_IS_OK(result)) {
5593 d_printf(_("Could not set trust account password: %s\n"),
5603 * Delete interdomain trust account for a remote domain.
5605 * @param argc Standard argc.
5606 * @param argv Standard argv without initial components.
5608 * @return Integer status (0 means success).
5611 static int rpc_trustdom_del(struct net_context *c, int argc, const char **argv)
5613 if (argc > 0 && !c->display_usage) {
5614 return run_rpc_command(c, NULL, &ndr_table_samr.syntax_id, 0,
5615 rpc_trustdom_del_internals, argc, argv);
5619 _("net rpc trustdom del <domain>\n"));
5624 static NTSTATUS rpc_trustdom_get_pdc(struct net_context *c,
5625 struct cli_state *cli,
5626 TALLOC_CTX *mem_ctx,
5627 const char *domain_name)
5629 char *dc_name = NULL;
5630 const char *buffer = NULL;
5631 struct rpc_pipe_client *netr;
5634 /* Use NetServerEnum2 */
5636 if (cli_get_pdc_name(cli, domain_name, &dc_name)) {
5638 return NT_STATUS_OK;
5641 DEBUG(1,("NetServerEnum2 error: Couldn't find primary domain controller\
5642 for domain %s\n", domain_name));
5644 /* Try netr_GetDcName */
5646 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
5648 if (!NT_STATUS_IS_OK(status)) {
5652 status = rpccli_netr_GetDcName(netr, mem_ctx,
5659 if (NT_STATUS_IS_OK(status)) {
5663 DEBUG(1,("netr_GetDcName error: Couldn't find primary domain controller\
5664 for domain %s\n", domain_name));
5670 * Establish trust relationship to a trusting domain.
5671 * Interdomain account must already be created on remote PDC.
5673 * @param c A net_context structure.
5674 * @param argc Standard argc.
5675 * @param argv Standard argv without initial components.
5677 * @return Integer status (0 means success).
5680 static int rpc_trustdom_establish(struct net_context *c, int argc,
5683 struct cli_state *cli = NULL;
5684 struct sockaddr_storage server_ss;
5685 struct rpc_pipe_client *pipe_hnd = NULL;
5686 struct policy_handle connect_hnd;
5687 TALLOC_CTX *mem_ctx;
5689 DOM_SID *domain_sid;
5694 union lsa_PolicyInformation *info = NULL;
5697 * Connect to \\server\ipc$ as 'our domain' account with password
5700 if (argc != 1 || c->display_usage) {
5703 _("net rpc trustdom establish <domain_name>\n"));
5707 domain_name = smb_xstrdup(argv[0]);
5708 strupper_m(domain_name);
5710 /* account name used at first is our domain's name with '$' */
5711 if (asprintf(&acct_name, "%s$", lp_workgroup()) == -1) {
5714 strupper_m(acct_name);
5717 * opt_workgroup will be used by connection functions further,
5718 * hence it should be set to remote domain name instead of ours
5720 if (c->opt_workgroup) {
5721 c->opt_workgroup = smb_xstrdup(domain_name);
5724 c->opt_user_name = acct_name;
5726 /* find the domain controller */
5727 if (!net_find_pdc(&server_ss, pdc_name, domain_name)) {
5728 DEBUG(0, ("Couldn't find domain controller for domain %s\n", domain_name));
5732 /* connect to ipc$ as username/password */
5733 nt_status = connect_to_ipc(c, &cli, &server_ss, pdc_name);
5734 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT)) {
5736 /* Is it trusting domain account for sure ? */
5737 DEBUG(0, ("Couldn't verify trusting domain account. Error was %s\n",
5738 nt_errstr(nt_status)));
5742 /* store who we connected to */
5744 saf_store( domain_name, pdc_name );
5747 * Connect to \\server\ipc$ again (this time anonymously)
5750 nt_status = connect_to_ipc_anonymous(c, &cli, &server_ss,
5753 if (NT_STATUS_IS_ERR(nt_status)) {
5754 DEBUG(0, ("Couldn't connect to domain %s controller. Error was %s.\n",
5755 domain_name, nt_errstr(nt_status)));
5759 if (!(mem_ctx = talloc_init("establishing trust relationship to "
5760 "domain %s", domain_name))) {
5761 DEBUG(0, ("talloc_init() failed\n"));
5766 /* Make sure we're talking to a proper server */
5768 nt_status = rpc_trustdom_get_pdc(c, cli, mem_ctx, domain_name);
5769 if (!NT_STATUS_IS_OK(nt_status)) {
5771 talloc_destroy(mem_ctx);
5776 * Call LsaOpenPolicy and LsaQueryInfo
5779 nt_status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc.syntax_id,
5781 if (!NT_STATUS_IS_OK(nt_status)) {
5782 DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n", nt_errstr(nt_status) ));
5784 talloc_destroy(mem_ctx);
5788 nt_status = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, true, KEY_QUERY_VALUE,
5790 if (NT_STATUS_IS_ERR(nt_status)) {
5791 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
5792 nt_errstr(nt_status)));
5794 talloc_destroy(mem_ctx);
5798 /* Querying info level 5 */
5800 nt_status = rpccli_lsa_QueryInfoPolicy(pipe_hnd, mem_ctx,
5802 LSA_POLICY_INFO_ACCOUNT_DOMAIN,
5804 if (NT_STATUS_IS_ERR(nt_status)) {
5805 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
5806 nt_errstr(nt_status)));
5808 talloc_destroy(mem_ctx);
5812 domain_sid = info->account_domain.sid;
5814 /* There should be actually query info level 3 (following nt serv behaviour),
5815 but I still don't know if it's _really_ necessary */
5818 * Store the password in secrets db
5821 if (!pdb_set_trusteddom_pw(domain_name, c->opt_password, domain_sid)) {
5822 DEBUG(0, ("Storing password for trusted domain failed.\n"));
5824 talloc_destroy(mem_ctx);
5829 * Close the pipes and clean up
5832 nt_status = rpccli_lsa_Close(pipe_hnd, mem_ctx, &connect_hnd);
5833 if (NT_STATUS_IS_ERR(nt_status)) {
5834 DEBUG(0, ("Couldn't close LSA pipe. Error was %s\n",
5835 nt_errstr(nt_status)));
5837 talloc_destroy(mem_ctx);
5843 talloc_destroy(mem_ctx);
5845 d_printf(_("Trust to domain %s established\n"), domain_name);
5850 * Revoke trust relationship to the remote domain.
5852 * @param c A net_context structure.
5853 * @param argc Standard argc.
5854 * @param argv Standard argv without initial components.
5856 * @return Integer status (0 means success).
5859 static int rpc_trustdom_revoke(struct net_context *c, int argc,
5865 if (argc < 1 || c->display_usage) {
5868 _("net rpc trustdom revoke <domain_name>\n"
5869 " Revoke trust relationship\n"
5870 " domain_name\tName of domain to revoke trust\n"));
5874 /* generate upper cased domain name */
5875 domain_name = smb_xstrdup(argv[0]);
5876 strupper_m(domain_name);
5878 /* delete password of the trust */
5879 if (!pdb_del_trusteddom_pw(domain_name)) {
5880 DEBUG(0, ("Failed to revoke relationship to the trusted domain %s\n",
5887 SAFE_FREE(domain_name);
5891 static NTSTATUS rpc_query_domain_sid(struct net_context *c,
5892 const DOM_SID *domain_sid,
5893 const char *domain_name,
5894 struct cli_state *cli,
5895 struct rpc_pipe_client *pipe_hnd,
5896 TALLOC_CTX *mem_ctx,
5901 if (!sid_to_fstring(str_sid, domain_sid)) {
5902 return NT_STATUS_UNSUCCESSFUL;
5904 d_printf("%s\n", str_sid);
5905 return NT_STATUS_OK;
5908 static void print_trusted_domain(DOM_SID *dom_sid, const char *trusted_dom_name)
5912 /* convert sid into ascii string */
5913 sid_to_fstring(ascii_sid, dom_sid);
5915 d_printf("%-20s%s\n", trusted_dom_name, ascii_sid);
5918 static NTSTATUS vampire_trusted_domain(struct rpc_pipe_client *pipe_hnd,
5919 TALLOC_CTX *mem_ctx,
5920 struct policy_handle *pol,
5922 const char *trusted_dom_name)
5925 union lsa_TrustedDomainInfo *info = NULL;
5926 char *cleartextpwd = NULL;
5927 uint8_t session_key[16];
5928 DATA_BLOB session_key_blob;
5929 DATA_BLOB data = data_blob_null;
5931 nt_status = rpccli_lsa_QueryTrustedDomainInfoBySid(pipe_hnd, mem_ctx,
5934 LSA_TRUSTED_DOMAIN_INFO_PASSWORD,
5936 if (NT_STATUS_IS_ERR(nt_status)) {
5937 DEBUG(0,("Could not query trusted domain info. Error was %s\n",
5938 nt_errstr(nt_status)));
5942 data = data_blob(info->password.password->data,
5943 info->password.password->length);
5945 if (!rpccli_get_pwd_hash(pipe_hnd, session_key)) {
5946 DEBUG(0, ("Could not retrieve password hash\n"));
5950 session_key_blob = data_blob_const(session_key, sizeof(session_key));
5951 cleartextpwd = sess_decrypt_string(mem_ctx, &data, &session_key_blob);
5953 if (cleartextpwd == NULL) {
5954 DEBUG(0,("retrieved NULL password\n"));
5955 nt_status = NT_STATUS_UNSUCCESSFUL;
5959 if (!pdb_set_trusteddom_pw(trusted_dom_name, cleartextpwd, &dom_sid)) {
5960 DEBUG(0, ("Storing password for trusted domain failed.\n"));
5961 nt_status = NT_STATUS_UNSUCCESSFUL;
5965 #ifdef DEBUG_PASSWORD
5966 DEBUG(100,("successfully vampired trusted domain [%s], sid: [%s], "
5967 "password: [%s]\n", trusted_dom_name,
5968 sid_string_dbg(&dom_sid), cleartextpwd));
5972 SAFE_FREE(cleartextpwd);
5973 data_blob_free(&data);
5978 static int rpc_trustdom_vampire(struct net_context *c, int argc,
5981 /* common variables */
5982 TALLOC_CTX* mem_ctx;
5983 struct cli_state *cli = NULL;
5984 struct rpc_pipe_client *pipe_hnd = NULL;
5986 const char *domain_name = NULL;
5987 DOM_SID *queried_dom_sid;
5988 struct policy_handle connect_hnd;
5989 union lsa_PolicyInformation *info = NULL;
5991 /* trusted domains listing variables */
5992 unsigned int enum_ctx = 0;
5994 struct lsa_DomainList dom_list;
5997 if (c->display_usage) {
5999 "net rpc trustdom vampire\n"
6002 _("Vampire trust relationship from remote server"));
6007 * Listing trusted domains (stored in secrets.tdb, if local)
6010 mem_ctx = talloc_init("trust relationships vampire");
6013 * set domain and pdc name to local samba server (default)
6014 * or to remote one given in command line
6017 if (StrCaseCmp(c->opt_workgroup, lp_workgroup())) {
6018 domain_name = c->opt_workgroup;
6019 c->opt_target_workgroup = c->opt_workgroup;
6021 fstrcpy(pdc_name, global_myname());
6022 domain_name = talloc_strdup(mem_ctx, lp_workgroup());
6023 c->opt_target_workgroup = domain_name;
6026 /* open \PIPE\lsarpc and open policy handle */
6027 nt_status = net_make_ipc_connection(c, NET_FLAGS_PDC, &cli);
6028 if (!NT_STATUS_IS_OK(nt_status)) {
6029 DEBUG(0, ("Couldn't connect to domain controller: %s\n",
6030 nt_errstr(nt_status)));
6031 talloc_destroy(mem_ctx);
6035 nt_status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc.syntax_id,
6037 if (!NT_STATUS_IS_OK(nt_status)) {
6038 DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n",
6039 nt_errstr(nt_status) ));
6041 talloc_destroy(mem_ctx);
6045 nt_status = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, false, KEY_QUERY_VALUE,
6047 if (NT_STATUS_IS_ERR(nt_status)) {
6048 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
6049 nt_errstr(nt_status)));
6051 talloc_destroy(mem_ctx);
6055 /* query info level 5 to obtain sid of a domain being queried */
6056 nt_status = rpccli_lsa_QueryInfoPolicy(pipe_hnd, mem_ctx,
6058 LSA_POLICY_INFO_ACCOUNT_DOMAIN,
6061 if (NT_STATUS_IS_ERR(nt_status)) {
6062 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
6063 nt_errstr(nt_status)));
6065 talloc_destroy(mem_ctx);
6069 queried_dom_sid = info->account_domain.sid;
6072 * Keep calling LsaEnumTrustdom over opened pipe until
6073 * the end of enumeration is reached
6076 d_printf(_("Vampire trusted domains:\n\n"));
6079 nt_status = rpccli_lsa_EnumTrustDom(pipe_hnd, mem_ctx,
6084 if (NT_STATUS_IS_ERR(nt_status)) {
6085 DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
6086 nt_errstr(nt_status)));
6088 talloc_destroy(mem_ctx);
6092 for (i = 0; i < dom_list.count; i++) {
6094 print_trusted_domain(dom_list.domains[i].sid,
6095 dom_list.domains[i].name.string);
6097 nt_status = vampire_trusted_domain(pipe_hnd, mem_ctx, &connect_hnd,
6098 *dom_list.domains[i].sid,
6099 dom_list.domains[i].name.string);
6100 if (!NT_STATUS_IS_OK(nt_status)) {
6102 talloc_destroy(mem_ctx);
6108 * in case of no trusted domains say something rather
6109 * than just display blank line
6111 if (!dom_list.count) d_printf(_("none\n"));
6113 } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
6115 /* close this connection before doing next one */
6116 nt_status = rpccli_lsa_Close(pipe_hnd, mem_ctx, &connect_hnd);
6117 if (NT_STATUS_IS_ERR(nt_status)) {
6118 DEBUG(0, ("Couldn't properly close lsa policy handle. Error was %s\n",
6119 nt_errstr(nt_status)));
6121 talloc_destroy(mem_ctx);
6125 /* close lsarpc pipe and connection to IPC$ */
6128 talloc_destroy(mem_ctx);
6132 static int rpc_trustdom_list(struct net_context *c, int argc, const char **argv)
6134 /* common variables */
6135 TALLOC_CTX* mem_ctx;
6136 struct cli_state *cli = NULL, *remote_cli = NULL;
6137 struct rpc_pipe_client *pipe_hnd = NULL;
6139 const char *domain_name = NULL;
6140 DOM_SID *queried_dom_sid;
6141 int ascii_dom_name_len;
6142 struct policy_handle connect_hnd;
6143 union lsa_PolicyInformation *info = NULL;
6145 /* trusted domains listing variables */
6146 unsigned int num_domains, enum_ctx = 0;
6148 struct lsa_DomainList dom_list;
6152 /* trusting domains listing variables */
6153 struct policy_handle domain_hnd;
6154 struct samr_SamArray *trusts = NULL;
6156 if (c->display_usage) {
6158 "net rpc trustdom list\n"
6161 _("List incoming and outgoing trust relationships"));
6166 * Listing trusted domains (stored in secrets.tdb, if local)
6169 mem_ctx = talloc_init("trust relationships listing");
6172 * set domain and pdc name to local samba server (default)
6173 * or to remote one given in command line
6176 if (StrCaseCmp(c->opt_workgroup, lp_workgroup())) {
6177 domain_name = c->opt_workgroup;
6178 c->opt_target_workgroup = c->opt_workgroup;
6180 fstrcpy(pdc_name, global_myname());
6181 domain_name = talloc_strdup(mem_ctx, lp_workgroup());
6182 c->opt_target_workgroup = domain_name;
6185 /* open \PIPE\lsarpc and open policy handle */
6186 nt_status = net_make_ipc_connection(c, NET_FLAGS_PDC, &cli);
6187 if (!NT_STATUS_IS_OK(nt_status)) {
6188 DEBUG(0, ("Couldn't connect to domain controller: %s\n",
6189 nt_errstr(nt_status)));
6190 talloc_destroy(mem_ctx);
6194 nt_status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc.syntax_id,
6196 if (!NT_STATUS_IS_OK(nt_status)) {
6197 DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n",
6198 nt_errstr(nt_status) ));
6200 talloc_destroy(mem_ctx);
6204 nt_status = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, false, KEY_QUERY_VALUE,
6206 if (NT_STATUS_IS_ERR(nt_status)) {
6207 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
6208 nt_errstr(nt_status)));
6210 talloc_destroy(mem_ctx);
6214 /* query info level 5 to obtain sid of a domain being queried */
6215 nt_status = rpccli_lsa_QueryInfoPolicy(pipe_hnd, mem_ctx,
6217 LSA_POLICY_INFO_ACCOUNT_DOMAIN,
6220 if (NT_STATUS_IS_ERR(nt_status)) {
6221 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
6222 nt_errstr(nt_status)));
6224 talloc_destroy(mem_ctx);
6228 queried_dom_sid = info->account_domain.sid;
6231 * Keep calling LsaEnumTrustdom over opened pipe until
6232 * the end of enumeration is reached
6235 d_printf(_("Trusted domains list:\n\n"));
6237 found_domain = false;
6240 nt_status = rpccli_lsa_EnumTrustDom(pipe_hnd, mem_ctx,
6245 if (NT_STATUS_IS_ERR(nt_status)) {
6246 DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
6247 nt_errstr(nt_status)));
6249 talloc_destroy(mem_ctx);
6253 for (i = 0; i < dom_list.count; i++) {
6254 print_trusted_domain(dom_list.domains[i].sid,
6255 dom_list.domains[i].name.string);
6256 found_domain = true;
6260 } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
6263 * in case of no trusted domains say something rather
6264 * than just display blank line
6266 if (!found_domain) {
6267 d_printf(_("none\n"));
6270 /* close this connection before doing next one */
6271 nt_status = rpccli_lsa_Close(pipe_hnd, mem_ctx, &connect_hnd);
6272 if (NT_STATUS_IS_ERR(nt_status)) {
6273 DEBUG(0, ("Couldn't properly close lsa policy handle. Error was %s\n",
6274 nt_errstr(nt_status)));
6276 talloc_destroy(mem_ctx);
6280 TALLOC_FREE(pipe_hnd);
6283 * Listing trusting domains (stored in passdb backend, if local)
6286 d_printf(_("\nTrusting domains list:\n\n"));
6289 * Open \PIPE\samr and get needed policy handles
6291 nt_status = cli_rpc_pipe_open_noauth(cli, &ndr_table_samr.syntax_id,
6293 if (!NT_STATUS_IS_OK(nt_status)) {
6294 DEBUG(0, ("Could not initialise samr pipe. Error was %s\n", nt_errstr(nt_status)));
6296 talloc_destroy(mem_ctx);
6301 nt_status = rpccli_samr_Connect2(pipe_hnd, mem_ctx,
6303 SAMR_ACCESS_LOOKUP_DOMAIN,
6305 if (!NT_STATUS_IS_OK(nt_status)) {
6306 DEBUG(0, ("Couldn't open SAMR policy handle. Error was %s\n",
6307 nt_errstr(nt_status)));
6309 talloc_destroy(mem_ctx);
6313 /* SamrOpenDomain - we have to open domain policy handle in order to be
6314 able to enumerate accounts*/
6315 nt_status = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
6317 SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
6320 if (!NT_STATUS_IS_OK(nt_status)) {
6321 DEBUG(0, ("Couldn't open domain object. Error was %s\n",
6322 nt_errstr(nt_status)));
6324 talloc_destroy(mem_ctx);
6329 * perform actual enumeration
6332 found_domain = false;
6334 enum_ctx = 0; /* reset enumeration context from last enumeration */
6337 nt_status = rpccli_samr_EnumDomainUsers(pipe_hnd, mem_ctx,
6344 if (NT_STATUS_IS_ERR(nt_status)) {
6345 DEBUG(0, ("Couldn't enumerate accounts. Error was: %s\n",
6346 nt_errstr(nt_status)));
6348 talloc_destroy(mem_ctx);
6352 for (i = 0; i < num_domains; i++) {
6354 char *str = CONST_DISCARD(char *, trusts->entries[i].name.string);
6356 found_domain = true;
6359 * get each single domain's sid (do we _really_ need this ?):
6360 * 1) connect to domain's pdc
6361 * 2) query the pdc for domain's sid
6364 /* get rid of '$' tail */
6365 ascii_dom_name_len = strlen(str);
6366 if (ascii_dom_name_len && ascii_dom_name_len < FSTRING_LEN)
6367 str[ascii_dom_name_len - 1] = '\0';
6369 /* set opt_* variables to remote domain */
6371 c->opt_workgroup = talloc_strdup(mem_ctx, str);
6372 c->opt_target_workgroup = c->opt_workgroup;
6374 d_printf("%-20s", str);
6376 /* connect to remote domain controller */
6377 nt_status = net_make_ipc_connection(c,
6378 NET_FLAGS_PDC | NET_FLAGS_ANONYMOUS,
6380 if (NT_STATUS_IS_OK(nt_status)) {
6381 /* query for domain's sid */
6382 if (run_rpc_command(
6384 &ndr_table_lsarpc.syntax_id, 0,
6385 rpc_query_domain_sid, argc,
6387 d_printf(_("strange - couldn't get domain's sid\n"));
6389 cli_shutdown(remote_cli);
6392 d_fprintf(stderr, _("domain controller is not "
6393 "responding: %s\n"),
6394 nt_errstr(nt_status));
6395 d_printf(_("couldn't get domain's sid\n"));
6399 } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
6401 if (!found_domain) {
6405 /* close opened samr and domain policy handles */
6406 nt_status = rpccli_samr_Close(pipe_hnd, mem_ctx, &domain_hnd);
6407 if (!NT_STATUS_IS_OK(nt_status)) {
6408 DEBUG(0, ("Couldn't properly close domain policy handle for domain %s\n", domain_name));
6411 nt_status = rpccli_samr_Close(pipe_hnd, mem_ctx, &connect_hnd);
6412 if (!NT_STATUS_IS_OK(nt_status)) {
6413 DEBUG(0, ("Couldn't properly close samr policy handle for domain %s\n", domain_name));
6416 /* close samr pipe and connection to IPC$ */
6419 talloc_destroy(mem_ctx);
6424 * Entrypoint for 'net rpc trustdom' code.
6426 * @param argc Standard argc.
6427 * @param argv Standard argv without initial components.
6429 * @return Integer status (0 means success).
6432 static int rpc_trustdom(struct net_context *c, int argc, const char **argv)
6434 struct functable func[] = {
6439 N_("Add trusting domain's account"),
6440 N_("net rpc trustdom add\n"
6441 " Add trusting domain's account")
6447 N_("Remove trusting domain's account"),
6448 N_("net rpc trustdom del\n"
6449 " Remove trusting domain's account")
6453 rpc_trustdom_establish,
6455 N_("Establish outgoing trust relationship"),
6456 N_("net rpc trustdom establish\n"
6457 " Establish outgoing trust relationship")
6461 rpc_trustdom_revoke,
6463 N_("Revoke outgoing trust relationship"),
6464 N_("net rpc trustdom revoke\n"
6465 " Revoke outgoing trust relationship")
6471 N_("List in- and outgoing domain trusts"),
6472 N_("net rpc trustdom list\n"
6473 " List in- and outgoing domain trusts")
6477 rpc_trustdom_vampire,
6479 N_("Vampire trusts from remote server"),
6480 N_("net rpc trustdom vampire\n"
6481 " Vampire trusts from remote server")
6483 {NULL, NULL, 0, NULL, NULL}
6486 return net_run_function(c, argc, argv, "net rpc trustdom", func);
6490 * Check if a server will take rpc commands
6491 * @param flags Type of server to connect to (PDC, DMB, localhost)
6492 * if the host is not explicitly specified
6493 * @return bool (true means rpc supported)
6495 bool net_rpc_check(struct net_context *c, unsigned flags)
6497 struct cli_state *cli;
6499 struct sockaddr_storage server_ss;
6500 char *server_name = NULL;
6503 /* flags (i.e. server type) may depend on command */
6504 if (!net_find_server(c, NULL, flags, &server_ss, &server_name))
6507 if ((cli = cli_initialise()) == NULL) {
6511 status = cli_connect(cli, server_name, &server_ss);
6512 if (!NT_STATUS_IS_OK(status))
6514 if (!attempt_netbios_session_request(&cli, global_myname(),
6515 server_name, &server_ss))
6517 status = cli_negprot(cli);
6518 if (!NT_STATUS_IS_OK(status))
6520 if (cli->protocol < PROTOCOL_NT1)
6529 /* dump sam database via samsync rpc calls */
6530 static int rpc_samdump(struct net_context *c, int argc, const char **argv) {
6531 if (c->display_usage) {
6536 _("Dump remote SAM database"));
6540 return run_rpc_command(c, NULL, &ndr_table_netlogon.syntax_id,
6541 NET_FLAGS_ANONYMOUS,
6542 rpc_samdump_internals, argc, argv);
6545 /* syncronise sam database via samsync rpc calls */
6546 static int rpc_vampire(struct net_context *c, int argc, const char **argv)
6548 struct functable func[] = {
6553 N_("Dump remote SAM database to ldif"),
6554 N_("net rpc vampire ldif\n"
6555 " Dump remote SAM database to LDIF file or "
6562 N_("Dump remote SAM database to Kerberos Keytab"),
6563 N_("net rpc vampire keytab\n"
6564 " Dump remote SAM database to Kerberos keytab "
6571 N_("Dump remote SAM database to passdb"),
6572 N_("net rpc vampire passdb\n"
6573 " Dump remote SAM database to passdb")
6576 {NULL, NULL, 0, NULL, NULL}
6580 if (c->display_usage) {
6585 _("Vampire remote SAM database"));
6589 return run_rpc_command(c, NULL, &ndr_table_netlogon.syntax_id,
6590 NET_FLAGS_ANONYMOUS,
6591 rpc_vampire_internals,
6595 return net_run_function(c, argc, argv, "net rpc vampire", func);
6599 * Migrate everything from a print server.
6601 * @param c A net_context structure.
6602 * @param argc Standard main() style argc.
6603 * @param argv Standard main() style argv. Initial components are already
6606 * @return A shell status integer (0 for success).
6608 * The order is important !
6609 * To successfully add drivers the print queues have to exist !
6610 * Applying ACLs should be the last step, because you're easily locked out.
6613 static int rpc_printer_migrate_all(struct net_context *c, int argc,
6618 if (c->display_usage) {
6620 "net rpc printer migrate all\n"
6623 _("Migrate everything from a print server"));
6628 d_printf(_("no server to migrate\n"));
6632 ret = run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
6633 rpc_printer_migrate_printers_internals, argc,
6638 ret = run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
6639 rpc_printer_migrate_drivers_internals, argc,
6644 ret = run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
6645 rpc_printer_migrate_forms_internals, argc, argv);
6649 ret = run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
6650 rpc_printer_migrate_settings_internals, argc,
6655 return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
6656 rpc_printer_migrate_security_internals, argc,
6662 * Migrate print drivers from a print server.
6664 * @param c A net_context structure.
6665 * @param argc Standard main() style argc.
6666 * @param argv Standard main() style argv. Initial components are already
6669 * @return A shell status integer (0 for success).
6671 static int rpc_printer_migrate_drivers(struct net_context *c, int argc,
6674 if (c->display_usage) {
6676 "net rpc printer migrate drivers\n"
6679 _("Migrate print-drivers from a print-server"));
6684 d_printf(_("no server to migrate\n"));
6688 return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
6689 rpc_printer_migrate_drivers_internals,
6694 * Migrate print-forms from a print-server.
6696 * @param c A net_context structure.
6697 * @param argc Standard main() style argc.
6698 * @param argv Standard main() style argv. Initial components are already
6701 * @return A shell status integer (0 for success).
6703 static int rpc_printer_migrate_forms(struct net_context *c, int argc,
6706 if (c->display_usage) {
6708 "net rpc printer migrate forms\n"
6711 _("Migrate print-forms from a print-server"));
6716 d_printf(_("no server to migrate\n"));
6720 return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
6721 rpc_printer_migrate_forms_internals,
6726 * Migrate printers from a print-server.
6728 * @param c A net_context structure.
6729 * @param argc Standard main() style argc.
6730 * @param argv Standard main() style argv. Initial components are already
6733 * @return A shell status integer (0 for success).
6735 static int rpc_printer_migrate_printers(struct net_context *c, int argc,
6738 if (c->display_usage) {
6740 "net rpc printer migrate printers\n"
6743 _("Migrate printers from a print-server"));
6748 d_printf(_("no server to migrate\n"));
6752 return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
6753 rpc_printer_migrate_printers_internals,
6758 * Migrate printer-ACLs from a print-server
6760 * @param c A net_context structure.
6761 * @param argc Standard main() style argc.
6762 * @param argv Standard main() style argv. Initial components are already
6765 * @return A shell status integer (0 for success).
6767 static int rpc_printer_migrate_security(struct net_context *c, int argc,
6770 if (c->display_usage) {
6772 "net rpc printer migrate security\n"
6775 _("Migrate printer-ACLs from a print-server"));
6780 d_printf(_("no server to migrate\n"));
6784 return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
6785 rpc_printer_migrate_security_internals,
6790 * Migrate printer-settings from a print-server.
6792 * @param c A net_context structure.
6793 * @param argc Standard main() style argc.
6794 * @param argv Standard main() style argv. Initial components are already
6797 * @return A shell status integer (0 for success).
6799 static int rpc_printer_migrate_settings(struct net_context *c, int argc,
6802 if (c->display_usage) {
6804 "net rpc printer migrate settings\n"
6807 _("Migrate printer-settings from a "
6813 d_printf(_("no server to migrate\n"));
6817 return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
6818 rpc_printer_migrate_settings_internals,
6823 * 'net rpc printer' entrypoint.
6825 * @param c A net_context structure.
6826 * @param argc Standard main() style argc.
6827 * @param argv Standard main() style argv. Initial components are already
6831 int rpc_printer_migrate(struct net_context *c, int argc, const char **argv)
6834 /* ouch: when addriver and setdriver are called from within
6835 rpc_printer_migrate_drivers_internals, the printer-queue already
6838 struct functable func[] = {
6841 rpc_printer_migrate_all,
6843 N_("Migrate all from remote to local print server"),
6844 N_("net rpc printer migrate all\n"
6845 " Migrate all from remote to local print server")
6849 rpc_printer_migrate_drivers,
6851 N_("Migrate drivers to local server"),
6852 N_("net rpc printer migrate drivers\n"
6853 " Migrate drivers to local server")
6857 rpc_printer_migrate_forms,
6859 N_("Migrate froms to local server"),
6860 N_("net rpc printer migrate forms\n"
6861 " Migrate froms to local server")
6865 rpc_printer_migrate_printers,
6867 N_("Migrate printers to local server"),
6868 N_("net rpc printer migrate printers\n"
6869 " Migrate printers to local server")
6873 rpc_printer_migrate_security,
6875 N_("Mirgate printer ACLs to local server"),
6876 N_("net rpc printer migrate security\n"
6877 " Mirgate printer ACLs to local server")
6881 rpc_printer_migrate_settings,
6883 N_("Migrate printer settings to local server"),
6884 N_("net rpc printer migrate settings\n"
6885 " Migrate printer settings to local server")
6887 {NULL, NULL, 0, NULL, NULL}
6890 return net_run_function(c, argc, argv, "net rpc printer migrate",func);
6895 * List printers on a remote RPC server.
6897 * @param c A net_context structure.
6898 * @param argc Standard main() style argc.
6899 * @param argv Standard main() style argv. Initial components are already
6902 * @return A shell status integer (0 for success).
6904 static int rpc_printer_list(struct net_context *c, int argc, const char **argv)
6906 if (c->display_usage) {
6908 "net rpc printer list\n"
6911 _("List printers on a remote RPC server"));
6915 return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
6916 rpc_printer_list_internals,
6921 * List printer-drivers on a remote RPC server.
6923 * @param c A net_context structure.
6924 * @param argc Standard main() style argc.
6925 * @param argv Standard main() style argv. Initial components are already
6928 * @return A shell status integer (0 for success).
6930 static int rpc_printer_driver_list(struct net_context *c, int argc,
6933 if (c->display_usage) {
6935 "net rpc printer driver\n"
6938 _("List printer-drivers on a remote RPC server"));
6942 return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
6943 rpc_printer_driver_list_internals,
6948 * Publish printer in ADS via MSRPC.
6950 * @param c A net_context structure.
6951 * @param argc Standard main() style argc.
6952 * @param argv Standard main() style argv. Initial components are already
6955 * @return A shell status integer (0 for success).
6957 static int rpc_printer_publish_publish(struct net_context *c, int argc,
6960 if (c->display_usage) {
6962 "net rpc printer publish publish\n"
6965 _("Publish printer in ADS via MSRPC"));
6969 return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
6970 rpc_printer_publish_publish_internals,
6975 * Update printer in ADS via MSRPC.
6977 * @param c A net_context structure.
6978 * @param argc Standard main() style argc.
6979 * @param argv Standard main() style argv. Initial components are already
6982 * @return A shell status integer (0 for success).
6984 static int rpc_printer_publish_update(struct net_context *c, int argc, const char **argv)
6986 if (c->display_usage) {
6988 "net rpc printer publish update\n"
6991 _("Update printer in ADS via MSRPC"));
6995 return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
6996 rpc_printer_publish_update_internals,
7001 * UnPublish printer in ADS via MSRPC.
7003 * @param c A net_context structure.
7004 * @param argc Standard main() style argc.
7005 * @param argv Standard main() style argv. Initial components are already
7008 * @return A shell status integer (0 for success).
7010 static int rpc_printer_publish_unpublish(struct net_context *c, int argc,
7013 if (c->display_usage) {
7015 "net rpc printer publish unpublish\n"
7018 _("UnPublish printer in ADS via MSRPC"));
7022 return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
7023 rpc_printer_publish_unpublish_internals,
7028 * List published printers via MSRPC.
7030 * @param c A net_context structure.
7031 * @param argc Standard main() style argc.
7032 * @param argv Standard main() style argv. Initial components are already
7035 * @return A shell status integer (0 for success).
7037 static int rpc_printer_publish_list(struct net_context *c, int argc,
7040 if (c->display_usage) {
7042 "net rpc printer publish list\n"
7045 _("List published printers via MSRPC"));
7049 return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
7050 rpc_printer_publish_list_internals,
7056 * Publish printer in ADS.
7058 * @param c A net_context structure.
7059 * @param argc Standard main() style argc.
7060 * @param argv Standard main() style argv. Initial components are already
7063 * @return A shell status integer (0 for success).
7065 static int rpc_printer_publish(struct net_context *c, int argc,
7069 struct functable func[] = {
7072 rpc_printer_publish_publish,
7074 N_("Publish printer in AD"),
7075 N_("net rpc printer publish publish\n"
7076 " Publish printer in AD")
7080 rpc_printer_publish_update,
7082 N_("Update printer in AD"),
7083 N_("net rpc printer publish update\n"
7084 " Update printer in AD")
7088 rpc_printer_publish_unpublish,
7090 N_("Unpublish printer"),
7091 N_("net rpc printer publish unpublish\n"
7092 " Unpublish printer")
7096 rpc_printer_publish_list,
7098 N_("List published printers"),
7099 N_("net rpc printer publish list\n"
7100 " List published printers")
7102 {NULL, NULL, 0, NULL, NULL}
7106 if (c->display_usage) {
7107 d_printf(_("Usage:\n"));
7108 d_printf(_("net rpc printer publish\n"
7109 " List published printers\n"
7110 " Alias of net rpc printer publish "
7112 net_display_usage_from_functable(func);
7115 return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
7116 rpc_printer_publish_list_internals,
7120 return net_run_function(c, argc, argv, "net rpc printer publish",func);
7126 * Display rpc printer help page.
7128 * @param c A net_context structure.
7129 * @param argc Standard main() style argc.
7130 * @param argv Standard main() style argv. Initial components are already
7133 int rpc_printer_usage(struct net_context *c, int argc, const char **argv)
7135 d_printf(_("net rpc printer LIST [printer] [misc. options] [targets]\n"
7136 "\tlists all printers on print-server\n\n"));
7137 d_printf(_("net rpc printer DRIVER [printer] [misc. options] [targets]\n"
7138 "\tlists all printer-drivers on print-server\n\n"));
7139 d_printf(_("net rpc printer PUBLISH action [printer] [misc. options] [targets]\n"
7140 "\tpublishes printer settings in Active Directory\n"
7141 "\taction can be one of PUBLISH, UPDATE, UNPUBLISH or LIST\n\n"));
7142 d_printf(_("net rpc printer MIGRATE PRINTERS [printer] [misc. options] [targets]"
7143 "\n\tmigrates printers from remote to local server\n\n"));
7144 d_printf(_("net rpc printer MIGRATE SETTINGS [printer] [misc. options] [targets]"
7145 "\n\tmigrates printer-settings from remote to local server\n\n"));
7146 d_printf(_("net rpc printer MIGRATE DRIVERS [printer] [misc. options] [targets]"
7147 "\n\tmigrates printer-drivers from remote to local server\n\n"));
7148 d_printf(_("net rpc printer MIGRATE FORMS [printer] [misc. options] [targets]"
7149 "\n\tmigrates printer-forms from remote to local server\n\n"));
7150 d_printf(_("net rpc printer MIGRATE SECURITY [printer] [misc. options] [targets]"
7151 "\n\tmigrates printer-ACLs from remote to local server\n\n"));
7152 d_printf(_("net rpc printer MIGRATE ALL [printer] [misc. options] [targets]"
7153 "\n\tmigrates drivers, forms, queues, settings and acls from\n"
7154 "\tremote to local print-server\n\n"));
7155 net_common_methods_usage(c, argc, argv);
7156 net_common_flags_usage(c, argc, argv);
7158 "\t-v or --verbose\t\t\tgive verbose output\n"
7159 "\t --destination\t\tmigration target server (default: localhost)\n"));
7165 * 'net rpc printer' entrypoint.
7167 * @param c A net_context structure.
7168 * @param argc Standard main() style argc.
7169 * @param argv Standard main() style argv. Initial components are already
7172 int net_rpc_printer(struct net_context *c, int argc, const char **argv)
7174 struct functable func[] = {
7179 N_("List all printers on print server"),
7180 N_("net rpc printer list\n"
7181 " List all printers on print server")
7185 rpc_printer_migrate,
7187 N_("Migrate printer to local server"),
7188 N_("net rpc printer migrate\n"
7189 " Migrate printer to local server")
7193 rpc_printer_driver_list,
7195 N_("List printer drivers"),
7196 N_("net rpc printer driver\n"
7197 " List printer drivers")
7201 rpc_printer_publish,
7203 N_("Publish printer in AD"),
7204 N_("net rpc printer publish\n"
7205 " Publish printer in AD")
7207 {NULL, NULL, 0, NULL, NULL}
7211 if (c->display_usage) {
7212 d_printf(_("Usage:\n"));
7213 d_printf(_("net rpc printer\n"
7214 " List printers\n"));
7215 net_display_usage_from_functable(func);
7218 return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
7219 rpc_printer_list_internals,
7223 return net_run_function(c, argc, argv, "net rpc printer", func);
7227 * 'net rpc' entrypoint.
7229 * @param c A net_context structure.
7230 * @param argc Standard main() style argc.
7231 * @param argv Standard main() style argv. Initial components are already
7235 int net_rpc(struct net_context *c, int argc, const char **argv)
7237 NET_API_STATUS status;
7239 struct functable func[] = {
7244 N_("Modify global audit settings"),
7245 N_("net rpc audit\n"
7246 " Modify global audit settings")
7252 N_("Show basic info about a domain"),
7254 " Show basic info about a domain")
7260 N_("Join a domain"),
7268 N_("Join a domain created in server manager"),
7269 N_("net rpc oldjoin\n"
7270 " Join a domain created in server manager")
7276 N_("Test that a join is valid"),
7277 N_("net rpc testjoin\n"
7278 " Test that a join is valid")
7284 N_("List/modify users"),
7286 " List/modify users")
7292 N_("Change a user password"),
7293 N_("net rpc password\n"
7294 " Change a user password\n"
7295 " Alias for net rpc user password")
7301 N_("List/modify groups"),
7302 N_("net rpc group\n"
7303 " List/modify groups")
7309 N_("List/modify shares"),
7310 N_("net rpc share\n"
7311 " List/modify shares")
7317 N_("List open files"),
7325 N_("List/modify printers"),
7326 N_("net rpc printer\n"
7327 " List/modify printers")
7331 net_rpc_changetrustpw,
7333 N_("Change trust account password"),
7334 N_("net rpc changetrustpw\n"
7335 " Change trust account password")
7341 N_("Modify domain trusts"),
7342 N_("net rpc trustdom\n"
7343 " Modify domain trusts")
7349 N_("Abort a remote shutdown"),
7350 N_("net rpc abortshutdown\n"
7351 " Abort a remote shutdown")
7357 N_("Shutdown a remote server"),
7358 N_("net rpc shutdown\n"
7359 " Shutdown a remote server")
7365 N_("Dump SAM data of remote NT PDC"),
7366 N_("net rpc samdump\n"
7367 " Dump SAM data of remote NT PDC")
7373 N_("Sync a remote NT PDC's data into local passdb"),
7374 N_("net rpc vampire\n"
7375 " Sync a remote NT PDC's data into local passdb")
7381 N_("Fetch the domain sid into local secrets.tdb"),
7382 N_("net rpc getsid\n"
7383 " Fetch the domain sid into local secrets.tdb")
7389 N_("Manage privileges assigned to SID"),
7390 N_("net rpc rights\n"
7391 " Manage privileges assigned to SID")
7397 N_("Start/stop/query remote services"),
7398 N_("net rpc service\n"
7399 " Start/stop/query remote services")
7405 N_("Manage registry hives"),
7406 N_("net rpc registry\n"
7407 " Manage registry hives")
7413 N_("Open interactive shell on remote server"),
7414 N_("net rpc shell\n"
7415 " Open interactive shell on remote server")
7417 {NULL, NULL, 0, NULL, NULL}
7420 status = libnetapi_init(&c->netapi_ctx);
7424 libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
7425 libnetapi_set_password(c->netapi_ctx, c->opt_password);
7426 if (c->opt_kerberos) {
7427 libnetapi_set_use_kerberos(c->netapi_ctx);
7429 if (c->opt_ccache) {
7430 libnetapi_set_use_ccache(c->netapi_ctx);
7433 return net_run_function(c, argc, argv, "net rpc", func);